Snapshot 205707dc11cdd6508ae84db85d104f834028fd65 from idea/132.1045 of git://git.jetbrains.org/idea/community.git

205707d: support abbreviations in Search Everywhere
9eeb98a: NPE fix
f701598: AA painting for shortcuts
9636e23: add abbreviations
d1f7c58: IDEA-116296 Search match looks terrible under Retina
8bc5adc: AIOOBE
f92fa41: IDEA-116194 "Generate equals() and hashcode()" for final classes should disable "accept subclasses" variant
ec773fc: CCE
9a208ab: selected completion item should be the first or second visible (IDEA-115199)
be542d6: linear-time filterByDumbAwareness
83273e5: faster next/prev occurrence action in the console (IDEA-115163)
d684469: LanguageConsole: shutdown printXXX fiesta. Everyone is advised to use ConsoleView API the right way.
480215a: Merge branch 'master' of git.labs.intellij.net:idea/community
c85aae4: https://android-review.googlesource.com/69716
76daf2e: Heroku integration - show log on redeploy
c567431: Jediterm updated (PY-11368).
5d325de: Accept only terminal tabs on DnD.
a1d5cd4: Merge remote-tracking branch 'origin/master'
0a3bcdb: Jediterm updated.
218607a8: Terminal: support presentation mode.
ea6fd6f: switch on console-content-type highlighting in all language consoles
e824117: Quick fix for RefParserTest
450ecea: suggest scrambled classes on second completion
7ba82d9: NPE fixed
525a30d: cleanup
2fa314d: don't display "Loading spellchecker dictionaries" in status bar (IDEA-115130)
276a47a: don't suggest scrambled classes in autopopup (IDEA-115199)
b4a4b99: temporary fix for layouts of small IDEs
02e07e1: [log] Move SimpleHash from vcs-log-graph to vcs-log-impl
f7b1796: [log] Hash -> int in Graph
0c4d0bb: [log] Don't call new VcsRefImpl() directly, use the factory
4c1c1c2: [log] Memory consumption: Hash -> int. Take 1
2e36939: Improvement from Roman Shevchenko to be compatible with Ubuntu 13.10.
b6edb35: Show pin icon in pinned Find Usages tabs
c143cee: IDEA-110064 JSF 2.2: Pass-through elements: if upper-case symbols are used instead of default 'jsf' namespace prefix, attributes are red-highlihted
3a69458: added actions 'mark/unmark as generated sources root' to popup menu
bdfc48c: Use maven3 importer by default.
d9417b6: Merge remote-tracking branch 'origin/master'
5b526fc: Add pty libs to pycharm community build.
c912c67: add HowTo
6d940b1: depend on PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT if the file cannot be resolved yet
7c63c25: platform: jayatana patched to support Ubuntu 13.10 (sources only)
59622ee: IDEA-116276 Console font is small in Presentation mode
6863abc: IDEA-115889 Framework toolwindows: support scope-based file colors for items
ac0f8ab: obtaining framework libraries from app server: download libraries list asynchronously from server
185804e: refactor supported root type checking according to CR-IC-3056
6b085fe: formatter removes spaces in import statement parentheses (PY-11359)
b04030e: Show pin icon in pinned Find Usages tabs
90ea6d7: do not disable empty frameworks page if no templates available
bb55e29: platform: jayatana sources attached
d1911f7: platform: Ubuntu app menu loading code extracted and corrected
897738a: Cleanup (deprecated code)
56e41fb: Check Grails SDK in background thread, not in the AWT. +review CR-IU @gromopert
fd2b6b3: IDEA-115074 New Project Wizard: Grails: grails-specific settings are missing
a69a88a: spi: decline abstract classes, suggest all available inheritors (IDEA-115502)
eeaee1e: SIOOBE
6cd3cb9: Fix spelling
5f4c814: IDEA-102413 (pointless assertion dropped)
dc455bd: Cleanup (arrangement, formatting)
44590dc: IDEA-25934 Maven: Webapp resources filtering store web resources configuration.
6e65f2b: IDEA-25934 Maven: Webapp resources filtering store web resources configuration.
df137ae: DOM stubs: namespace key index
046e455: Merge remote-tracking branch 'origin/master'
0681517: testdata fixed
dd63221: IDEA-116168 Action creation does not escape special chars in plugin.xml
48fa01e: restore plugin description
d34d829: new project wizard: remote templates
389db71: methods renamed
b07e674: prefer non-qualified xml completion variants (IDEA-115355)
add165a: IDEA-116144 Opening build.gradle of android project fails
d524a84: refixed IDEA-111753 to remove unnecessary dependency on debugger
b8df146: show usages from generated code in separate group (IDEA-97579)
034f42b: removed obsolete 'remote-server-util' module from installation, added new module to git plugin installation
c8deccf: download libraries in parallel (IDEA-88561)
674de91: our LinkedHashMap: added methods to obtain last added key/value
43aced8: Restore context menu after DnD back to Terminal View.
b6987d3: Merge remote-tracking branch 'origin/master'
c147027: Fix: terminal tab doesn't save name change after DnD.
495bda4: JediTerm update to version 1.0
46667e2: Fix closing tab on session end. Fix popup for editor terminal tabs.
fdd3e70: Fix potential NPE.
9ea940a: [git] Fix refresh notification after changing non-active branch hashes
34b357c: more console folding by default
d21cf01: Fix memory leak.
1dcfd64: Fix removing terminal tabs on drag'n'drop.
29a4f60: add accessOrder parameter to our LinkedHashMap
e0ff96d: DockableEditorTabbedContainer shouldn't return root pane as accept area as it makes impossible to add any other dockable container. It is better to return root pane in the special fallback method after we checked all containers.
4b22045: Terminal tabs: drag'n'drop to editor and back implemented.
6ac9ae9: DockableEditor doesn't need EditorWindow reference.
73f7ab5: [log] IDEA-115980 Don't show Git actions if there are no Git roots
7964385: [log] "Go To Commit" action
c647083: [log] Extract the popup text field used for user completion
7e9497a: Merge remote-tracking branch 'origin/master'
0eb8a6f: [log] Fix hidden graph because of the date filter existance
95d5d5b: [log] IDEA-116022 Implement Structure filter for VCS Log & Git
4989fa1: [vcs] VcsStructureChooser: remove dependency on the AbstractVcs.
278cd62: [log] move structure filter implementation to vcs-log-impl
9b5b1c2: Github: change search request parameter
a543347: IDEA-115330 Incorrect "condition is always false"
0b85cc1: trying to make project opening progress information more meaningful (IDEA-115130)
35af155: Don't display empty panel if there are no moreMessage in the dialog
41592ca: [vcs] IDEA-116036 Pressing Escape in Commit/TODO dialog performs commit
7c5ba53: [log] Fix IDEA-115676 once again
8fb8d34: [log] IDEA-116056 Display commit time in details if different from author time
9b6d291: [log] IDEA-116022 Add filter by date
c49b45b: only suppress eager psi creation when there were stubs in the file
f815aa9: our LinkedHashMap clients aren't necessarily aware that it updates its ordering on every get. Let clients specify if they need this feature (IDEA-116222)
6fcd19c: return not-null MODULE_CONTEXT data only for single content roots (IDEA-115422)
0af49e6: fix two psi elements per one ast element in stub-ast switch:   psi1 is taken from stub   psi2 is eagerly created during chameleon parsing   another thread gets the ast when some psi1 parent is already switched and psi1 is not, it walks down the ast and gets psi2
fcfef16: remove big JI sign
2ad7bd2: support for <shortcut>
cd74ff8: IDEA-116206
59b556f: set transparency 20%
152e772: fix missing help button
b8f59ef: add getLanguage() method
25dece1: IDEA-110540 ("String concat (+) and super.toString()" template adds "+ super.toString()" even if no super)
35c07da: new inference: reject isExact for no constructor parameterized class
5fafbd5: EA-51725 - NPE: IntroduceVariableBase.replace
22cf8de: ignore anonymous classes when generating constructors EA-51713 - assert: CreateConstructorMatchingSuperFix$.run
1735391: getWidget method
fcb4970: attempt to fix IDEA-116128 LiveEdit doesn't work correctly for JSP files
36e4932: continue "ability to return list of URLs"  — isConfigurationFromContext
d67f88c: Cleanup (formatting)
3112d12: reliably check if a task for debugger manager thread was interrupted
201c7b5: IDEA-75717 ("Referenced checked for null not used inside if" false positive)
795357c: do not suppress file-level inspections
4745efc: continue "ability to return list of URLs"  IDEA-115787
43216f8: IDEA-115787 Better resolvement for JSF page URLs
2e6db86: IDEA-100279 ChooseComponentsToExportDialog
72ee12c: fix warning "mac file equals"
19576b2: overrides, cleanup
0a15306: IDEA-100279 git init
b596340: IDEA-100279 xml editor location dialog
3c0f6cd: IDEA-100279 copyright plugin
b7c6e4c: overrides
e9e6eb2: 'Download library' refactored a little
946216e: IDEA-116197 (filter improvements)
9439744: EA-51425 - ISE: MavenUtil.resolveSuperPomFile add assertion.
9c38499: EA-51325 - assert: MavenIndices.createNewDir
9346755: don't log Connection reset by peer
cfb11fa: cleanup
038e39d: IDEA-114461 Structure tool window: Jump to Source (F4) does not move focus to Editor
ed4794e: VcsRootDetector and RootErrorsFinder tests updated
c196ab3: Remove unnecessary check and param from HgRepositoryImpl
b486fcb: template actions are now injection aware
773f5f0: IDEA-102454 Parameter Info: TAB/Shift-TAB and editing does not work in language injected fragment
3b34a0b: IDEA-49273  Injected language: parameter info tooltip disappears on moving caret
7afa57d: move indexer to indexing-impl
4ab17a0: don't shift text range if the element has no last child (PY-11344)
9e3bbe9: don't show "inspect test source" checkbox in PyCharm (PY-1187)
ac7f1b2: IDEA-113483 (action fixed to select directories too)
7bd9931: Emmet: extract SurroundWithEmmetAction
625e81b: don't show "production" and "test" scopes in predefined scopes if current product doesn't support test source roots (PY-7324)
f01a713: grouping by directory uses project-relative paths (PY-11176); rename the action from "Group by package" to "Group by directory" in platform-based IDEs
be45c85: move GeneralFormatterTest to platform-tests; fix NPE in DocumentImpl when running standalone GeneralFormatterTest
4d22f5e: DirectoryIndex: don't include roots from content to projectExcludeRoots set, update projectExcludeRoots on VFS change
02f7305: Merge branch 'master' of git.labs.intellij.net:idea/community
7994da2: External System: test fix Related task: IDEA-79466 gradle support should generate web module configuration
e3cfba1: IDEA-116126 - NoClassDefFound on attempt to deploy to heroku
630eacf: Merge remote-tracking branch 'origin/master'
a902c4e: testdata fixed
db0433c: fix NPE — final class variable is not yet initialized — we must not open connection until debug process class is not constructed.
dd2d5f6: platform: ensure event file validity on dropping symlink target
eaeed33: platform: better pairing of before/after VFS events
97aec30: Cleanup (formatting)
017646f: remove dead code, cleanup
2181005: more templates
ab315c8: new project wizard: template description & count
e789a57: External system: adding TEST_GENERATED source type to ExternalSystemSourceType
62eeca9: new project wizard: adding project templates
25e633c: SimpleColoredComponent: builder style
84c2eb6: ColoredListCellRenderer parameterized
3c567ba: cleanup
ab15886: cleanup
aaad70d: cleanup
81c7d30: update Key.findKeyByName usages due to API changes
41ca0a4: CCE aware API
fe3700f: java call hierarchy extension
51c76a3: Make view meta model extendable
e17daa4: unused methods with strange names deprecated
4910498: service replaced by utility methods
d0fd16f: faster for simple cases
3dd6919: fix CSS completion tests: if the reference starts at completion start location, we do need to overwrite it when Tab is pressed
22c1ef9: Gradle: update to  Gradle 1.9-rc-3
7a38323: Pty4j updated.
29ac873: IDEA-97390 Java Debugger: View Text action shows white on white [2]
1c329ac: Merge branch 'master' of git.labs.intellij.net:idea/community
0c60dd9: IDEA-86998 Evaluate expression mixes colorschemas when displaying injected code
ce6fbd9: IDEA-97390 Java Debugger: View Text action shows white on white
a50bd7e: Merge branch 'master' of git.labs.intellij.net:idea/community
8de20e2: remote servers - headers cleanup
c5e1cf7: don't reformat mock variable during control flow building
8e11281: don't walk module src roots in search for .class file source (IDEA-116085)
992d740: cache expected names (IDEA-116085)
10976b3: walk library src roots once when searching for class sources (IDEA-116085)
dfc71fc: fix java pull up refactoring!
4af2a83: Merge remote-tracking branch 'origin/master'
a818922: javadoc: include in classpath only libraries from modules which participate in the scope (IDEA-116083)
38e2991: new inference: do not use nested call args to infer on the top level
465762a: new inference: reject multiple eq bounds
d84a0a0: Darcula eats almost all EDT cpu time
fe23143: IDEA-94922 (Report negatively named boolean variables and suggest to perform 'Invert Boolean' for them)
f637ac6: fix description
9005acd: common "invert boolean" quickfix
9a5bfa9: add #loc's
dd94fc6: fix "No dependencies provided which causes CachedValue to be never recalculated again."
e4cce36: java.lang.IllegalThreadStateException additional handling
1249362: disposed check
0495c47: cleanup
25fc653: extra inspections
8850957: IDEA-101405 Call hierarchy support for Groovy
3026341: hierarchy package
deb52f5: Flat & round stripe buttons (Internal Mode only) v.3, colors improvement
d903511: IDEA-116139 Workaround NPE fix
8fccc30: avoid assertion on file path completion (EA-51068)
fdb9f6e: ctrl+w shouldn't choke on unclosed argument lists (EA-51589)
1de20e6: don't inc modification counter on first load of gant/gradle settings
8a9c177: IDEA-25934 Maven: Webapp resources filtering store web resource configuration.
9553c1a: catch all exceptions that may influence VM attach process
aa8a8e8: IDEA-116146 Search everywhere has small font in Presentation mode
9c7d5d5: #WEB-8915 fixed
5d96196: dfa: flush resource variables when leaving try block
15c0fd6: jsr166e.jar included into standalone jps distribution
edbde43: generics: bounds check should stop expanding nested wildcards up to 2nd level
d991c73: fix invalid file assertion
aae4c5a: IDEA-116049 Mercurial log problem with Mac default locale (x_MacRoman)
08a6b0c: Unnecessary encoding argument in new hg log removed.
5cd75d1: style
5a365fd: fix BooleanParameterInspectionTest
4e2e6ca: [log] IDEA-115966 Show HAND cursor over branch arrows
7793ca6: [log] Collect user information from the whole log
4e8c466: [log] Completion in filter by user
bc4c9f8: [log] intern VcsUsers.
0505705: [log] Encapsulate author & committer into VcsUser
1fb280e: [log] Let VcsLogObjectsFactory be project service & depend on VcsLogManager
2f2f008: Gradle: add Tooling API extra models support. Related task: IDEA-79466 gradle support should generate web module configuration
3c9aa6d: convert EventLogCategory to abstract class
0804cb1: html5 char entities for fragments
0e50db9: #IDEA-116106 fixed
483a5d1: enable entities validation for html5 #WEB-7053 fixed
962e050: generated entities for html 5 chars, use it in resolve and completion
b57823a: Merge remote-tracking branch 'origin/master'
da8e5d0: we must add "http://" prefix if specified path is not absolute
6bb2810: small lens mode fix
88caaf7: Merge remote-tracking branch 'origin/master'
4268072: IDEA-116125 extra gutter in presentation mode
6d03a86: Eliminated dependencies on pthread, glib rec mutex synchronization. A crash fixed.
b5f05f4: Quick fix for not Unity window managers. Should be moved into linux-specific code.
fe27876: WI-14476 When hovering over variable, Expression Evaluation tooltip disappears before I can click the + icon (cherry picked from commit 3034e98)
202e2ae: Cleanup (test)
a5960af: java: no need to check package prefix for annotations on ref adjustment
ab262e2: Cleanup (test)
5b2a86b: IDEA-89720 Preview usages: "select usages to preview" should be shown at the center of panel
7b82bf1: IDEA-116119 Darcula: links are hardly visible on warnings
d2a2cd9: don't hide run configuration type if there are only one irrelevant type (IDEA-116046)
15e08d4: javadoc corrected
5575eb1: hide 'deploy to cloud' run configurations if corresponding cloud isn't configured (IDEA-116046)
3b3c221: WEB-9876 Fuzzy search is still colliding with completion
50bd840: Spock method should be a GrMethod.
5364513: exception-safe rendering
544a580: thread assertion fix
bc4c101: fix NPEs
56940f1: a way to increase dismiss  delay
9aee54e: framework version from existing library
37f430f: removing borders automatically
19a21fd: new "Non-varargs method overrides varargs method" inspection
e82e54d: improve description
31fedec: New in 13
0fbffa1: fixed downloading client libraries from modal dialog (IDEA-115975)
5db09f5: CCE from android step fixed
cded14f: IDEA-115064 New Project Wizard: Spring page looks bad: preselected frameworks
e6b1f8e: fix NPE (request status)
8bba7c9: IDEA-115076 Groovy: New Project Wizard: IAE at DialogWrapperPeerFactoryImpl.createPeer() on 'Create Groovy Library'
5a47ef8: app server editor: don't show 'change version' button for app server library
f510156: IDEA-115398 New Project Wizard: libraries downloading doesn't work
3d251be: event log category EP
7d76939: Take shortcuts for next tab and prev tabs from keymap.
be19e2e: Next tab and Previous tab actions.
67310ba: Null class name tolerated
db170d7: Fixed text shaking on tab name editing.
bd3c4bc: Some cleanup.
b27ba6e: IDEA-112596 SQL: MySQL uncomment doesn't work with "--"
a67dac8: IDEA-115954 lens mode warning annotation bubbles overlap text on retina
b6c179c: IDEA-93733 Double line above editor tabs
2c91f79: EA-51491 - assert: DocumentImpl.createRangeMarker
1743e7b: EA-51650 - assert: JavaDocInfoGenerator.getDocComment
16712b8: Todo
f9d2c43: Cleanup (formatting)
38f058d: failing test for PY-10319
dd3f3fa: rename some methods and cleanup code to make logic clearer
aa885ea: report missing identifier after 'as' (PY-9853)
52efcb5: only allow single expression after 'in'; tweak error recovery when waiting for colon (PY-9561)
7f8dc3d: change default match-from-start to false
bfb1819: EA-51669 (unneeded augmentation avoided)
b27e492: platform: extension point declaration moved to correct .xml
4d9e686: sourcemaps: ability to resolve sources relative to generated file
40e08dc: Fix the size changing of text field for terminal tabs.
62223eb: Merge remote-tracking branch 'origin/master'
6c84d33: take synchronized statements into account when mapping local variable names to slots
4e560b6: allow to view hidden items in 'New Run Configuration' popup (IDEA-116046)
37caefe: IDEA-72889 (CodeStyle inspection to check tabs instead of spaces in file)
f345cfd: EA-51469: do not call GemManager.updateGemset(Module) with null
e27287d: ShowSettingUtil: selecting configurable by class is fixed
b9f0e95: new inference: infer recursively for conditional expression
646aea3: new inference: avoid self bounds when possible
a2ad6fd: new inference: accept captured wildcard opening during subtype constraint reduction
66462d0: remove incorrect copyright messages
c3c03a0: don't set default cursor if empty text is invisible
4f009e8: IDEA-115398 New Project Wizard: libraries downloading doesn't work
3607191: Merge remote-tracking branch 'origin/master'
a95509a: extracted method to get/set 'for generated source' option via API
7b00b8f: hide Groovy run configuration if there are no groovy files in project (IDEA-116046)
89f2a76: Minor VFS optimization (cleanup)
0defb40: less spam in the logs when there's PSI/document inconsistency during reference search (IDEA-115950)
29427e7: added service to quickly find modules by module type; hide DevKit and J2ME  run configurations if there are no corresponding modules (IDEA-116046)
d031ebc: hide Python run configurations if they are irrelevant (IDEA-116046)
75ca45a: IDEA-116000 Error message  shown if hg root marked as git
e9b3a8c: style
24f91c2: IDEA-115474 Maven Dependency template broken in latest Idea Cardea
26b5659: added API to hide irrelevant run configuration types from 'New' popup in 'Edit Configurations' dialog (IDEA-116046)
5b6b259: Merge remote-tracking branch 'origin/master'
0525b10: Revert the change.
4f9d3f0: Disable formatter ranges in formatter off/on tags [CR-IC-2916]
f760c44: IDEA-36685: Provide better 'no matching constructor' warnings where possible
915fb35a: new overload resolution: testdata
3546317: new overload resolution
971909a: method refs: exact tweaks
f6932ac: Merge remote-tracking branch 'origin/master'
c22e14c: JediTerm jar updated.
08eed1d: Merge remote-tracking branch 'origin/master'
5ff6e1a: Merge remote-tracking branch 'origin/master'
feec183: Pty4j with debug info.
08c90e8: Minor VFS optimization
53a81a0: Cleanup (formatting)
dc52633: EA-50578 - assert: TextRange.<init>
b532d92: Merge remote-tracking branch 'origin/master'
aa20e7d: status bar should have a height at least of an icon, even before any icons appear, to prevent unnecessary blinking (IDEA-114453)
1e0e31e: IDEA-112982 Status bar starts with bad layout before project is fully loaded   default min height was 1 which made BoxLayout center-align everything along the top border resulting in 2x less memory indicator height
5fdc8f8: Merge branch 'svn_18_2'
cc6dd17: svn: Fixed destroy for process under terminal
9826ae7: external system: EA-51656, check for disposable project components added
7337a62: external system: EA-51656, check for disposable project components added
ea5159b: IDEA-116001 Incorrect behavior of root scanner in case non hg project marked as hg fixed
2186112: Merge remote-tracking branch 'origin/master'
9f02f7e: don't generate icons for IntelliJ laf
0f252a9: IDEA-90751 Scope tabs coloring does not affect hidden tabs pop-up
ab0e88a: cleanup dead code
79bf40e: IDEA-114608 breakpoints dialog: add panel must be at top
d9b94c5: new icons: vendors & sql structure view
5b4b9a7: svn: Do not read from error stream for process under terminal
ca6a8ac: drop command wrapper
5617a42: use correct date format in command to fix reverting changes on file with a sticky date
afbef4d: new inference: mark List::get as inexact
4fde439: EA-51621 - IOE: CheckUtil.checkWritable
eb79b67: EA-51643 - assert: DataManagerImpl$MyDataContext.getData
e1b69a4: new inference: exact method reference: decline constructor with parameter with type parameter of class
664ee85: improve parser recovery if keyword is used as function or class name (PY-8319)
5d6bac5: improve parser recovery if keyword is used as named parameter (PY-8318)
ce1ff5d: if we have only one import candidate, show its name instead of "import this name" (PY-8067)
27c5fbb: Visual Studio keymap maps Shift+F1 to both QuickJavaDoc and ExternalJavaDoc (PY-7291)
baaf551: rename file when renaming class if file name equals lowercased class name (PY-7155)
f52709b: tweak decorator parsing so that following line comment is outside the text range of PyDecorator (PY-5912)
a61112a: don't overwrite reference by Tab if it starts exactly after reference being completed (PY-6095)
12249d1: tab completion for keyword arguments overwrites the = sign (PY-1337(
a351f53: highlight only the last line of string literal when triple quotes are unclosed (PY-1780); allow running StringLiteralQuotesAnnotator in dumb mode
1bf4336: consistent behavior of PyFunction.getContainingClass() in stub-based and non-stub-based cases (PY-1448)
36c20c2: fix caret position after pressing Enter in Python line comment
e55c85f: fix HtmlCompletionTest.testDotTypeWhileActiveLookupInFileReference
a3e89bc: IntelliLang PatternValidator: class parsing errors should not fail the build if the class is not going to be instrumented by the validator. Covered 2 more cases when this check was not performed (IDEA-115189 IntelliLang Pattern Validator: Class not found)
6f7b23e: Merge remote-tracking branch 'origin/master'
c5d7ccd: Merge remote-tracking branch 'origin/master'
946d9ab: svn: terminal: Implemented handling of "unknown host" prompt for ssh
f1e1ceb: IDEA-113191 Used "write" access to sqlite db and try to access db several times if failed
b95367c: svn: Do not handle auth errors when command is finished if in terminal mode
e306801: svn: terminal: Added separate logging for status command output (as there are some issues with terminal output parsing)
f22a4ed: svn: terminal: Implemented cancelling authentication prompts
4e7c774: svn: terminal: Treat stdout lines with svn errors as stderr lines
a48733d: svn: Fixed default focused element for credentials dialog opening (password is focused if username is disabled)
aac45e5: svn: Implemented password prompts for ssh authentication through terminal
b8768d1: svn: Implemented basic svn+ssh authentication using terminal (under svn.use.terminal registry key)
13a217b: svn: Refactored CommandExecutor - ability to write to process input stream, small changes for inheritors
e9ccca6: svn: Moved setting "non-interactive" mode when command executor is created
4092ffa: svn: Added command logging in for non-zero exit code
8441324: Tab name length is limited by 50 in jediterm library.
1c63154: Use JB tabs in terminal(PY-10609). Pass disposable to terminal widget.
2ba2163: Extract method that sets content to the holder.
9c5a392: NPE (IDEA-115607).

Change-Id: I83d19d7826b59dbc1d782247b78553b4632e7635
diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java
index 6d455d3..9add783 100644
--- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java
+++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java
@@ -37,6 +37,7 @@
 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
 import com.intellij.psi.util.PsiUtilBase;
 import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.ui.awt.RelativePoint;
 import com.intellij.ui.popup.NotLookupOrSearchCondition;
 import com.intellij.ui.popup.PopupPositionManager;
 import com.intellij.util.Processor;
@@ -79,6 +80,8 @@
     final VirtualFile virtualFile = PsiUtilCore.getVirtualFile(psiElement);
     if (virtualFile == null) return;
 
+    final RelativePoint bestPopupLocation = JBPopupFactory.getInstance().guessBestPopupLocation(dataContext);
+
     final SmartPsiElementPointer element = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(psiElement);
     ProgressManager.getInstance().run(new Task.Backgroundable(project, "Searching byte code...") {
       private String myByteCode;
@@ -145,7 +148,11 @@
             .createPopup();
           Disposer.register(popup, component);
 
-          PopupPositionManager.positionPopupInBestPosition(popup, editor, dataContext);
+          if (editor != null) {
+            popup.showInBestPositionFor(editor);
+          } else {
+            popup.show(bestPopupLocation);
+          }
         }
       }
     });
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
index 1ca8290..8ebb212 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
@@ -760,6 +760,10 @@
     <localInspection language="JAVA" shortName="LawOfDemeter" bundle="com.siyeh.InspectionGadgetsBundle" key="law.of.demeter.display.name"
                      groupBundle="messages.InspectionsBundle" groupKey="group.names.data.flow.issues" enabledByDefault="false"
                      level="WARNING" implementationClass="com.siyeh.ig.dataflow.LawOfDemeterInspection"/>
+    <localInspection language="JAVA" shortName="NegativelyNamedBooleanVariable" bundle="com.siyeh.InspectionGadgetsBundle"
+                     key="negatively.named.boolean.variable.display.name" groupBundle="messages.InspectionsBundle"
+                     groupKey="group.names.data.flow.issues" enabledByDefault="false" level="WARNING"
+                     implementationClass="com.siyeh.ig.dataflow.NegativelyNamedBooleanVariableInspection"/>
     <localInspection language="JAVA" shortName="OrredNotEqualExpression" bundle="com.siyeh.InspectionGadgetsBundle"
                      key="orred.not.equal.expression.display.name" groupBundle="messages.InspectionsBundle"
                      groupKey="group.names.data.flow.issues" enabledByDefault="true" level="WARNING"
@@ -1014,6 +1018,10 @@
                      bundle="com.siyeh.InspectionGadgetsBundle" key="non.protected.constructor.in.abstract.class.display.name"
                      groupBundle="messages.InspectionsBundle" groupKey="group.names.inheritance.issues" enabledByDefault="false"
                      level="WARNING" implementationClass="com.siyeh.ig.inheritance.NonProtectedConstructorInAbstractClassInspection"/>
+    <localInspection language="JAVA" shortName="ProblematicVarargsMethodOverride" bundle="com.siyeh.InspectionGadgetsBundle"
+                     key="problematic.varargs.method.display.name" groupBundle="messages.InspectionsBundle"
+                     groupKey="group.names.inheritance.issues" enabledByDefault="false" level="WARNING"
+                     implementationClass="com.siyeh.ig.inheritance.ProblematicVarargsMethodOverrideInspection"/>
     <localInspection language="JAVA" shortName="RedundantMethodOverride" bundle="com.siyeh.InspectionGadgetsBundle"
                      key="redundant.method.override.display.name" groupBundle="messages.InspectionsBundle"
                      groupKey="group.names.inheritance.issues" enabledByDefault="false" level="WARNING"
@@ -2388,6 +2396,10 @@
                      key="size.replaceable.by.isempty.display.name" groupBundle="messages.InspectionsBundle"
                      groupKey="group.names.code.style.issues" enabledByDefault="false" level="WARNING"
                      implementationClass="com.siyeh.ig.style.SizeReplaceableByIsEmptyInspection"/>
+    <localInspection language="JAVA" shortName="ProblematicWhitespace" bundle="com.siyeh.InspectionGadgetsBundle"
+                     key="problematic.whitespace.display.name" groupBundle="messages.InspectionsBundle"
+                     groupKey="group.names.code.style.issues" enabledByDefault="false" level="WARNING"
+                     implementationClass="com.siyeh.ig.style.ProblematicWhitespaceInspection"/>
 
     <!--group.names.threading.issues-->
     <localInspection language="JAVA" suppressId="AccessToNonThreadSafeStaticField" shortName="AccessToNonThreadSafeStaticFieldFromInstance"
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
index 1f3e7e8..36709b6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
@@ -910,7 +910,7 @@
 final.method.problem.descriptor=Method declared <code>#ref</code> #loc
 class.initializer.problem.descriptor=Non-'static' initializer #loc
 class.may.be.interface.problem.descriptor=<code>#ref</code> may be interface #loc
-non.protected.constructor.in.abstract.class.problem.descriptor=Constructor <code>#ref</code> is not declared 'protected' in 'abstract' class #loc
+non.protected.constructor.in.abstract.class.problem.descriptor=Constructor <code>#ref()</code> is not declared 'protected' in 'abstract' class #loc
 class.without.constructor.problem.descriptor=Class <code>#ref</code> has no constructor #loc
 abstract.class.without.abstract.methods.problem.descriptor=Class <code>#ref</code> is declared 'abstract', and has no 'abstract' methods #loc
 final.method.in.final.class.problem.descriptor=Method declared <code>#ref</code> in 'final' class #loc
@@ -1428,7 +1428,7 @@
 replace.indexof.with.contains.quickfix=Replace 'indexOf()' with 'contains()'
 overloaded.methods.with.same.number.parameters.problem.descriptor=Multiple methods named <code>#ref</code> with the same number of parameters #loc
 overloaded.vararg.method.problem.descriptor=Overloaded variable argument method <code>#ref()</code> #loc
-overloaded.vararg.constructor.problem.descriptor=Overloaded variable argument constructor <code>#ref</code> #loc
+overloaded.vararg.constructor.problem.descriptor=Overloaded variable argument constructor <code>#ref()</code> #loc
 cached.number.constructor.call.display.name=Number constructor call with primitive argument
 cached.number.constructor.call.problem.descriptor=Number constructor call with primitive argument <code>#ref</code> #loc
 cached.number.constructor.call.quickfix=Replace with ''{0}.valueOf()'' call
@@ -1731,7 +1731,8 @@
 field.may.be.final.problem.descriptor=Field <code>#ref</code> may be 'final' #loc
 cast.that.loses.precision.option=Ignore casts from int to char
 variable.not.used.inside.if.display.name=Reference checked for 'null' is not used inside 'if'
-variable.not.used.inside.if.problem.descriptor=<code>#ref</code> is not used inside if #loc
+variable.not.used.inside.if.problem.descriptor=<code>#ref</code> checked for 'null' is not used inside 'if' #loc
+variable.not.used.inside.conditional.problem.descriptor=<code>#ref</code> checked for 'null' is not used inside conditional #loc
 if.may.be.conditional.display.name='if' statement could be replaced with conditional expression
 if.may.be.conditional.problem.descriptor=<code>#ref</code> could be replaced with conditional expression #loc
 if.may.be.conditional.quickfix=Replace with conditional expression
@@ -1901,7 +1902,7 @@
 method.can.be.variable.arity.method.display.name=Method can be variable arity method
 method.can.be.variable.arity.method.problem.descriptor=<code>#ref()</code> can be converted to variable arity method #loc
 method.can.be.variable.arity.method.ignore.byte.short.option=<html>Ignore methods with a last parameter of type byte[] or short[]</html>
-convert.to.variable.arity.method.quickfix=Convert to variable arity method
+convert.to.variable.arity.method.quickfix=Convert to varargs method
 mismatched.string.builder.query.update.display.name=Mismatched query and update of StringBuilder
 mismatched.string.builder.updated.problem.descriptor=Contents of {0} <code>#ref</code> are updated, but never queried #loc
 mismatched.string.builder.queried.problem.descriptor=Contents of {0} <code>#ref</code> are queried, but never updated #loc
@@ -2026,7 +2027,7 @@
 placeholder.count.matches.argument.count.more.problem.descriptor=<code>#ref()</code> call has more arguments ({0}) than placeholders ({1}) #loc
 placeholder.count.matches.argument.count.fewer.problem.descriptor=<code>#ref()</code> call has fewer arguments ({0}) than placeholders ({1}) #loc
 assignment.to.superclass.field.display.name=Constructor assigns value to field defined in superclass
-assignment.to.superclass.field.problem.descriptor=Assignment to field ''{0}'' defined in superclass ''{1}''
+assignment.to.superclass.field.problem.descriptor=Assignment to field ''{0}'' defined in superclass ''{1}'' #loc
 junit.rule.display.name=Malformed @Rule/@ClassRule field
 junit.rule.problem.descriptor=Fields annotated with @{0} should be {1}
 junit.rule.type.problem.descriptor=Field type should be subtype of org.junit.rules.TestRule
@@ -2036,13 +2037,13 @@
 inner.class.referenced.via.subclass.problem.descriptor=Inner class <code>#ref</code> declared in class ''{0}'' but referenced via subclass ''{1}'' #loc
 inner.class.referenced.via.subclass.quickfix=Rationalize inner class access
 boolean.parameter.display.name='public' method with 'boolean' parameter
-boolean.parameter.problem.descriptor='public' method <code>#ref</code> with 'boolean' parameter
-boolean.parameters.problem.descriptor='public' method <code>#ref</code> with 'boolean' parameters
-boolean.parameter.constructor.problem.descriptor='public' constructor <code>#ref</code> with 'boolean' parameter
-boolean.parameters.constructor.problem.descriptor='public' constructor <code>#ref</code> with 'boolean' parameters
+boolean.parameter.problem.descriptor='public' method <code>#ref()</code> with 'boolean' parameter #loc
+boolean.parameters.problem.descriptor='public' method <code>#ref()</code> with 'boolean' parameters #loc
+boolean.parameter.constructor.problem.descriptor='public' constructor <code>#ref()</code> with 'boolean' parameter #loc
+boolean.parameters.constructor.problem.descriptor='public' constructor <code>#ref()</code> with 'boolean' parameters #loc
 boolean.parameter.only.report.multiple.option=Only report methods with multiple boolean parameters
 unnecessary.unicode.escape.display.name=Unnecessary unicode escape sequence
-unnecessary.unicode.escape.problem.descriptor=Unicode escape sequence <code>#ref</code> can be replaced with ''{0}''
+unnecessary.unicode.escape.problem.descriptor=Unicode escape sequence <code>#ref</code> can be replaced with ''{0}'' #loc
 missing.package.info.display.name=Missing 'package-info.java'
 missing.package.info.problem.descriptor=Package ''{0}'' is missing a <code>package-info.java</code> file
 missing.package.html.problem.descriptor=Package ''{0}'' is missing a <code>package.html</code> file
@@ -2051,5 +2052,16 @@
 package.info.without.package.quickfix=add ''package {0};''
 package.info.without.package.family.quickfix=add package statement
 auto.closeable.resource.display.name=AutoCloseable used without 'try'-with-resources
-auto.closeable.resource.problem.descriptor=''{0}'' used without ''try''-with-resources statement
+auto.closeable.resource.problem.descriptor=''{0}'' used without ''try''-with-resources statement #loc
 auto.closeable.resource.returned.option=Ignore AutoCloseable instances returned from method calls
+problematic.whitespace.display.name=Problematic whitespace
+problematic.whitespace.tabs.problem.descriptor=File ''{0}'' uses tabs for indentation
+problematic.whitespace.spaces.problem.descriptor=File ''{0}'' uses spaces for indentation
+problematic.whitespace.show.whitespaces.quickfix=Toggle show whitespace in the editor
+problematic.varargs.method.display.name=Non-varargs method overrides varargs method
+problematic.varargs.method.override.problem.descriptor=Non-varargs method <code>#ref()</code> overrides varargs method #loc
+negatively.named.boolean.variable.problem.descriptor=Boolean variable <code>#ref</code> is negatively named #loc
+negatively.named.boolean.variable.display.name=Negatively named boolean variable
+invert.quickfix.family.name=Invert boolean
+invert.method.quickfix=Invert method
+invert.quickfix=Invert ''{0}''
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspectionVisitor.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspectionVisitor.java
index 028b359..1ba34a6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspectionVisitor.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspectionVisitor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -222,17 +222,10 @@
   }
 
   @Override
-  public void visitReferenceExpression(
-    PsiReferenceExpression expression) {
+  public void visitReferenceExpression(PsiReferenceExpression expression) {
     visitExpression(expression);
   }
 
-  @Override
-  public final void visitWhiteSpace(PsiWhiteSpace space) {
-    // none of our inspections need to do anything with white space,
-    // so this is a performance optimization
-  }
-
   public final void setProblemsHolder(ProblemsHolder holder) {
     this.holder = holder;
   }
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/VariableNotUsedInsideIfInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/VariableNotUsedInsideIfInspection.java
index f6dc0e4..bae56e9 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/VariableNotUsedInsideIfInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/VariableNotUsedInsideIfInspection.java
@@ -31,15 +31,19 @@
   @Nls
   @NotNull
   public String getDisplayName() {
-    return InspectionGadgetsBundle.message(
-      "variable.not.used.inside.if.display.name");
+    return InspectionGadgetsBundle.message("variable.not.used.inside.if.display.name");
   }
 
   @Override
   @NotNull
   protected String buildErrorString(Object... infos) {
-    return InspectionGadgetsBundle.message(
-      "variable.not.used.inside.if.problem.descriptor");
+    final boolean isIf = ((Boolean)infos[0]).booleanValue();
+    if (isIf) {
+      return InspectionGadgetsBundle.message("variable.not.used.inside.if.problem.descriptor");
+    }
+    else {
+      return InspectionGadgetsBundle.message("variable.not.used.inside.conditional.problem.descriptor");
+    }
   }
 
   @Override
@@ -63,10 +67,14 @@
       }
       final IElementType tokenType = binaryExpression.getOperationTokenType();
       if (tokenType == JavaTokenType.EQEQ) {
-        checkVariableUsage(referenceExpression, expression.getThenExpression(), expression.getElseExpression());
+        if (checkVariableUsage(referenceExpression, expression.getThenExpression(), expression.getElseExpression())) {
+          registerError(referenceExpression, Boolean.FALSE);
+        }
       }
       else if (tokenType == JavaTokenType.NE) {
-        checkVariableUsage(referenceExpression, expression.getElseExpression(), expression.getThenExpression());
+        if (checkVariableUsage(referenceExpression, expression.getElseExpression(), expression.getThenExpression())) {
+          registerError(referenceExpression, Boolean.FALSE);
+        }
       }
     }
 
@@ -84,29 +92,30 @@
       }
       final IElementType tokenType = binaryExpression.getOperationTokenType();
       if (tokenType == JavaTokenType.EQEQ) {
-        checkVariableUsage(referenceExpression, statement.getThenBranch(), statement.getElseBranch());
+        if (checkVariableUsage(referenceExpression, statement.getThenBranch(), statement.getElseBranch())) {
+          registerError(referenceExpression, Boolean.TRUE);
+        }
       }
       else if (tokenType == JavaTokenType.NE) {
-        checkVariableUsage(referenceExpression, statement.getElseBranch(), statement.getThenBranch());
+        if (checkVariableUsage(referenceExpression, statement.getElseBranch(), statement.getThenBranch())) {
+          registerError(referenceExpression, Boolean.TRUE);
+        }
       }
     }
 
-    private void checkVariableUsage(PsiReferenceExpression referenceExpression, PsiElement thenContext, PsiElement elseContext) {
-      if (thenContext == null) {
-        return;
-      }
+    private boolean checkVariableUsage(PsiReferenceExpression referenceExpression, PsiElement thenContext, PsiElement elseContext) {
       final PsiElement target = referenceExpression.resolve();
       if (!(target instanceof PsiVariable)) {
-        return;
+        return false;
       }
       final PsiVariable variable = (PsiVariable)target;
-      if (contextExits(thenContext) || VariableAccessUtils.variableIsAssigned(variable, thenContext)) {
-        return;
+      if (thenContext != null && (contextExits(thenContext) || VariableAccessUtils.variableIsAssigned(variable, thenContext))) {
+        return false;
       }
-      if (elseContext != null && (contextExits(elseContext) || VariableAccessUtils.variableIsUsed(variable, elseContext))) {
-        return;
+      if (elseContext == null || VariableAccessUtils.variableIsUsed(variable, elseContext)) {
+        return false;
       }
-      registerError(referenceExpression);
+      return true;
     }
 
     private static PsiReferenceExpression extractVariableReference(PsiBinaryExpression expression) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/NegativelyNamedBooleanVariableInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/NegativelyNamedBooleanVariableInspectionBase.java
new file mode 100644
index 0000000..0d3ba03
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/NegativelyNamedBooleanVariableInspectionBase.java
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+package com.siyeh.ig.dataflow;
+
+import com.intellij.psi.PsiType;
+import com.intellij.psi.PsiVariable;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class NegativelyNamedBooleanVariableInspectionBase extends BaseInspection {
+
+  @NonNls
+  private static final String[] NEGATIVE_NAMES = {"not", "isNot", "shouldNot", "shallNot", "willNot", "cannot", "cant", "hasNot",
+    "couldNot", "hidden", "isHidden", "disabled", "isDisabled"};
+
+  @Nls
+  @NotNull
+  @Override
+  public String getDisplayName() {
+    return InspectionGadgetsBundle.message("negatively.named.boolean.variable.display.name");
+  }
+
+  @NotNull
+  @Override
+  protected String buildErrorString(Object... infos) {
+    return InspectionGadgetsBundle.message("negatively.named.boolean.variable.problem.descriptor");
+  }
+
+  @Override
+  public BaseInspectionVisitor buildVisitor() {
+    return new NegativelyNamedBooleanVariableVisitor();
+  }
+
+  private static class NegativelyNamedBooleanVariableVisitor extends BaseInspectionVisitor {
+
+    @Override
+    public void visitVariable(PsiVariable variable) {
+      super.visitVariable(variable);
+      if (!PsiType.BOOLEAN.equals(variable.getType())) {
+        return;
+      }
+      final String name = variable.getName();
+      for (final String negativeName : NEGATIVE_NAMES) {
+        if (name.startsWith(negativeName) &&
+            (name.length() == negativeName.length() || Character.isUpperCase(name.charAt(negativeName.length())))) {
+          registerVariableError(variable, variable);
+          break;
+        }
+      }
+    }
+  }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ConvertToVarargsMethodFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ConvertToVarargsMethodFix.java
new file mode 100644
index 0000000..2c0212f
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ConvertToVarargsMethodFix.java
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+package com.siyeh.ig.fixes;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.Query;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.InspectionGadgetsFix;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class ConvertToVarargsMethodFix extends InspectionGadgetsFix {
+
+  @Override
+  @NotNull
+  public String getFamilyName() {
+    return getName();
+  }
+
+  @NotNull
+  @Override
+  public String getName() {
+    return InspectionGadgetsBundle.message("convert.to.variable.arity.method.quickfix");
+  }
+
+  @Override
+  protected boolean prepareForWriting() {
+    return false;
+  }
+
+  @Override
+  protected void doFix(Project project, ProblemDescriptor descriptor) {
+    final PsiElement element = descriptor.getPsiElement();
+    final PsiElement parent = element.getParent();
+    if (!(parent instanceof PsiMethod)) {
+      return;
+    }
+    final PsiMethod method = (PsiMethod)parent;
+    final Collection<PsiElement> writtenElements = new ArrayList<PsiElement>();
+    final Collection<PsiReferenceExpression> methodCalls = new ArrayList<PsiReferenceExpression>();
+    writtenElements.add(method);
+    for (final PsiReference reference : ReferencesSearch.search(method, method.getUseScope(), false)) {
+      final PsiElement referenceElement = reference.getElement();
+      if (referenceElement instanceof PsiReferenceExpression) {
+        writtenElements.add(referenceElement);
+        methodCalls.add((PsiReferenceExpression)referenceElement);
+      }
+    }
+    if (!FileModificationService.getInstance().preparePsiElementsForWrite(writtenElements)) {
+      return;
+    }
+    makeMethodVarargs(method);
+    makeMethodCallsVarargs(methodCalls);
+  }
+
+  private static void makeMethodVarargs(PsiMethod method) {
+    final PsiParameterList parameterList = method.getParameterList();
+    if (parameterList.getParametersCount() == 0) {
+      return;
+    }
+    final PsiParameter[] parameters = parameterList.getParameters();
+    final PsiParameter lastParameter = parameters[parameters.length - 1];
+    final PsiType type = lastParameter.getType();
+    if (!(type instanceof PsiArrayType)) {
+      return;
+    }
+    final PsiArrayType arrayType = (PsiArrayType)type;
+    final PsiType componentType = arrayType.getComponentType();
+    final PsiElementFactory factory = JavaPsiFacade.getElementFactory(method.getProject());
+    final PsiType ellipsisType = PsiEllipsisType.createEllipsis(componentType, type.getAnnotations());
+    final PsiTypeElement newTypeElement = factory.createTypeElement(ellipsisType);
+    final PsiTypeElement typeElement = lastParameter.getTypeElement();
+    if (typeElement != null) {
+      typeElement.replace(newTypeElement);
+    }
+  }
+
+  private static void makeMethodCallsVarargs(Collection<PsiReferenceExpression> referenceExpressions) {
+    for (final PsiReferenceExpression referenceExpression : referenceExpressions) {
+      final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)referenceExpression.getParent();
+      final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
+      final PsiExpression[] arguments = argumentList.getExpressions();
+      if (arguments.length == 0) {
+        continue;
+      }
+      final PsiExpression lastArgument = arguments[arguments.length - 1];
+      if (!(lastArgument instanceof PsiNewExpression)) {
+        continue;
+      }
+      final PsiNewExpression newExpression = (PsiNewExpression)lastArgument;
+      final PsiArrayInitializerExpression arrayInitializerExpression = newExpression.getArrayInitializer();
+      if (arrayInitializerExpression == null) {
+        continue;
+      }
+      final PsiExpression[] initializers = arrayInitializerExpression.getInitializers();
+      for (final PsiExpression initializer : initializers) {
+        argumentList.add(initializer);
+      }
+      lastArgument.delete();
+    }
+  }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/ProblematicVarargsMethodOverrideInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/ProblematicVarargsMethodOverrideInspection.java
new file mode 100644
index 0000000..bf121ff
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/ProblematicVarargsMethodOverrideInspection.java
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+package com.siyeh.ig.inheritance;
+
+import com.intellij.psi.*;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.InspectionGadgetsFix;
+import com.siyeh.ig.fixes.ConvertToVarargsMethodFix;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class ProblematicVarargsMethodOverrideInspection extends BaseInspection {
+
+  @Nls
+  @NotNull
+  @Override
+  public String getDisplayName() {
+    return InspectionGadgetsBundle.message("problematic.varargs.method.display.name");
+  }
+
+  @NotNull
+  @Override
+  protected String buildErrorString(Object... infos) {
+    return InspectionGadgetsBundle.message("problematic.varargs.method.override.problem.descriptor");
+  }
+
+  @Nullable
+  @Override
+  protected InspectionGadgetsFix buildFix(Object... infos) {
+    return new ConvertToVarargsMethodFix();
+  }
+
+  @Override
+  public BaseInspectionVisitor buildVisitor() {
+    return new NonVarargsMethodOverridesVarArgsMethodVisitor();
+  }
+
+  private static class NonVarargsMethodOverridesVarArgsMethodVisitor extends BaseInspectionVisitor {
+
+    @Override
+    public void visitMethod(PsiMethod method) {
+      super.visitMethod(method);
+      final PsiParameterList parameterList = method.getParameterList();
+      final PsiParameter[] parameters = parameterList.getParameters();
+      if (parameters.length == 0) {
+        return;
+      }
+      final PsiParameter parameter = parameters[parameters.length - 1];
+      final PsiType type = parameter.getType();
+      if (!(type instanceof PsiArrayType)) {
+        return;
+      }
+      final PsiMethod[] superMethods = method.findDeepestSuperMethods();
+      for (final PsiMethod superMethod : superMethods) {
+        if (superMethod.isVarArgs()) {
+          registerMethodError(method);
+          return;
+        }
+      }
+    }
+  }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/SuppressionAnnotationInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/SuppressionAnnotationInspectionBase.java
index e7bb246..2eb1cc3 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/SuppressionAnnotationInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/SuppressionAnnotationInspectionBase.java
@@ -62,9 +62,12 @@
           && !tokenType.equals(JavaTokenType.C_STYLE_COMMENT)) {
         return;
       }
-      @NonNls final String strippedComment = commentText.substring(2).trim();
-      if (strippedComment.startsWith(SuppressionUtilCore.SUPPRESS_INSPECTIONS_TAG_NAME)) {
-        registerError(comment);
+
+      if (commentText.length() > 2) {
+        @NonNls final String strippedComment = commentText.substring(2).trim();
+        if (strippedComment.startsWith(SuppressionUtilCore.SUPPRESS_INSPECTIONS_TAG_NAME)) {
+          registerError(comment);
+        }
       }
     }
 
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java
index ef15918..74a0a9b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java
@@ -15,15 +15,14 @@
  */
 package com.siyeh.ig.migration;
 
-import com.intellij.codeInspection.ProblemDescriptor;
 import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
-import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiUtil;
 import com.siyeh.InspectionGadgetsBundle;
 import com.siyeh.ig.BaseInspection;
 import com.siyeh.ig.BaseInspectionVisitor;
 import com.siyeh.ig.InspectionGadgetsFix;
+import com.siyeh.ig.fixes.ConvertToVarargsMethodFix;
 import com.siyeh.ig.psiutils.LibraryUtil;
 import com.siyeh.ig.psiutils.MethodUtils;
 import org.jetbrains.annotations.Nls;
@@ -64,49 +63,7 @@
 
   @Override
   protected InspectionGadgetsFix buildFix(Object... infos) {
-    return new MethodCanBeVariableArityMethodFix();
-  }
-
-  private static class MethodCanBeVariableArityMethodFix extends InspectionGadgetsFix {
-       @Override
-  @NotNull
-  public String getFamilyName() {
-    return getName();
-  }
-
-    @NotNull
-    @Override
-    public String getName() {
-      return InspectionGadgetsBundle.message("convert.to.variable.arity.method.quickfix");
-    }
-
-    @Override
-    protected void doFix(Project project, ProblemDescriptor descriptor) {
-      final PsiElement element = descriptor.getPsiElement();
-      final PsiElement parent = element.getParent();
-      if (!(parent instanceof PsiMethod)) {
-        return;
-      }
-      final PsiMethod method = (PsiMethod)parent;
-      final PsiParameterList parameterList = method.getParameterList();
-      if (parameterList.getParametersCount() == 0) {
-        return;
-      }
-      final PsiParameter[] parameters = parameterList.getParameters();
-      final PsiParameter lastParameter = parameters[parameters.length - 1];
-      final PsiType type = lastParameter.getType();
-      if (!(type instanceof PsiArrayType)) {
-        return;
-      }
-      final PsiArrayType arrayType = (PsiArrayType)type;
-      final PsiType componentType = arrayType.getComponentType();
-      final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
-      final PsiTypeElement newTypeElement = factory.createTypeElementFromText(componentType.getCanonicalText() + "...", method);
-      final PsiTypeElement typeElement = lastParameter.getTypeElement();
-      if (typeElement != null) {
-        typeElement.replace(newTypeElement);
-      }
-    }
+    return new ConvertToVarargsMethodFix();
   }
 
   @Override
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java
index e8bf9a9..f7eeccf 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java
@@ -140,7 +140,7 @@
     }
   }
 
-  static boolean isPrimitiveNumericCastNecessary(PsiTypeCastExpression expression) {
+  public static boolean isPrimitiveNumericCastNecessary(PsiTypeCastExpression expression) {
     final PsiType castType = expression.getType();
     if (castType == null) {
       return true;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/DefiniteAssignment.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/DefiniteAssignment.java
index 893de08..325ddc2 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/DefiniteAssignment.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/DefiniteAssignment.java
@@ -13,11 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-/**
- * (c) 2013 Desert Island BV
- * created: 03 09 2013
- */
 package com.siyeh.ig.psiutils;
 
 import com.intellij.psi.*;
@@ -31,7 +26,7 @@
 /**
 * @author Bas Leijdekkers
 */
-public class DefiniteAssignment {
+class DefiniteAssignment {
 
   @NotNull
   private final PsiVariable variable;
diff --git a/plugins/InspectionGadgets/src/com/intellij/codeInspection/booleanIsAlwaysInverted/BooleanMethodIsAlwaysInvertedInspection.java b/plugins/InspectionGadgets/src/com/intellij/codeInspection/booleanIsAlwaysInverted/BooleanMethodIsAlwaysInvertedInspection.java
index 7642c92..8b847b7 100644
--- a/plugins/InspectionGadgets/src/com/intellij/codeInspection/booleanIsAlwaysInverted/BooleanMethodIsAlwaysInvertedInspection.java
+++ b/plugins/InspectionGadgets/src/com/intellij/codeInspection/booleanIsAlwaysInverted/BooleanMethodIsAlwaysInvertedInspection.java
@@ -15,60 +15,18 @@
  */
 package com.intellij.codeInspection.booleanIsAlwaysInverted;
 
-import com.intellij.codeInspection.LocalQuickFix;
-import com.intellij.codeInspection.ProblemDescriptor;
 import com.intellij.codeInspection.QuickFix;
-import com.intellij.ide.DataManager;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.refactoring.JavaRefactoringActionHandlerFactory;
-import com.intellij.refactoring.RefactoringActionHandler;
-import org.jetbrains.annotations.NotNull;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.fixes.InvertBooleanFix;
 
 /**
  * User: anna
  * Date: 06-Jan-2006
  */
 public class BooleanMethodIsAlwaysInvertedInspection extends BooleanMethodIsAlwaysInvertedInspectionBase {
+
   @Override
   public QuickFix getQuickFix(final String hint) {
-    return new InvertMethodFix();
+    return new InvertBooleanFix(InspectionGadgetsBundle.message("invert.method.quickfix"));
   }
-
-  private static class InvertMethodFix implements LocalQuickFix {
-    @Override
-    @NotNull
-    public String getName() {
-      return "Invert method";
-    }
-
-    @Override
-    @NotNull
-    public String getFamilyName() {
-      return getName();
-    }
-
-    @Override
-    public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
-      final PsiElement element = descriptor.getPsiElement();
-      final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
-      assert psiMethod != null;
-      final RefactoringActionHandler invertBooleanHandler = JavaRefactoringActionHandlerFactory.getInstance().createInvertBooleanHandler();
-      final Runnable runnable = new Runnable() {
-        @Override
-        public void run() {
-          invertBooleanHandler.invoke(project, new PsiElement[]{psiMethod}, DataManager.getInstance().getDataContext());
-        }
-      };
-      if (ApplicationManager.getApplication().isUnitTestMode()) {
-        runnable.run();
-      }
-      else {
-        ApplicationManager.getApplication().invokeLater(runnable, project.getDisposed());
-      }
-    }
-  }
-}
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/BooleanVariableAlwaysNegatedInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/BooleanVariableAlwaysNegatedInspection.java
index 1a69c90..0c9c286 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/BooleanVariableAlwaysNegatedInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/BooleanVariableAlwaysNegatedInspection.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011 Bas Leijdekkers
+ * Copyright 2011-2013 Bas Leijdekkers
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,57 +15,16 @@
  */
 package com.siyeh.ig.dataflow;
 
-import com.intellij.codeInspection.ProblemDescriptor;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.refactoring.invertBoolean.InvertBooleanDialog;
-import com.intellij.util.IncorrectOperationException;
+import com.intellij.psi.PsiVariable;
 import com.siyeh.InspectionGadgetsBundle;
 import com.siyeh.ig.InspectionGadgetsFix;
-import org.jetbrains.annotations.NotNull;
+import com.siyeh.ig.fixes.InvertBooleanFix;
 
 public class BooleanVariableAlwaysNegatedInspection extends BooleanVariableAlwaysNegatedInspectionBase {
 
   @Override
   protected InspectionGadgetsFix buildFix(Object... infos) {
     final PsiVariable variable = (PsiVariable)infos[0];
-    return new BooleanVariableIsAlwaysNegatedFix(variable.getName());
-  }
-
-  private static class BooleanVariableIsAlwaysNegatedFix
-    extends InspectionGadgetsFix {
-
-    private final String name;
-
-    public BooleanVariableIsAlwaysNegatedFix(String name) {
-      this.name = name;
-    }
-
-    @NotNull
-    @Override
-    public String getName() {
-      return InspectionGadgetsBundle.message(
-        "boolean.variable.always.inverted.quickfix", name);
-    }
-
-    @NotNull
-    @Override
-    public String getFamilyName() {
-      return "Invert";
-    }
-
-    @Override
-    protected void doFix(Project project, ProblemDescriptor descriptor)
-      throws IncorrectOperationException {
-      final PsiElement element = descriptor.getPsiElement();
-      final PsiVariable variable =
-        PsiTreeUtil.getParentOfType(element, PsiVariable.class);
-      if (variable == null) {
-        return;
-      }
-      final InvertBooleanDialog dialog = new InvertBooleanDialog(variable);
-      dialog.show();
-    }
+    return new InvertBooleanFix(InspectionGadgetsBundle.message("invert.quickfix", variable.getName()));
   }
 }
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/NegativelyNamedBooleanVariableInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/NegativelyNamedBooleanVariableInspection.java
new file mode 100644
index 0000000..06cdfff
--- /dev/null
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/NegativelyNamedBooleanVariableInspection.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+package com.siyeh.ig.dataflow;
+
+import com.intellij.psi.PsiVariable;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.InspectionGadgetsFix;
+import com.siyeh.ig.fixes.InvertBooleanFix;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class NegativelyNamedBooleanVariableInspection extends NegativelyNamedBooleanVariableInspectionBase {
+
+  @Nullable
+  @Override
+  protected InspectionGadgetsFix buildFix(Object... infos) {
+    final PsiVariable variable = (PsiVariable)infos[0];
+    return new InvertBooleanFix(InspectionGadgetsBundle.message("invert.quickfix", variable.getName()));
+  }
+}
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/InvertBooleanFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/InvertBooleanFix.java
new file mode 100644
index 0000000..68b1685
--- /dev/null
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/InvertBooleanFix.java
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+package com.siyeh.ig.fixes;
+
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiNameIdentifierOwner;
+import com.intellij.psi.PsiVariable;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.refactoring.JavaRefactoringActionHandlerFactory;
+import com.intellij.refactoring.RefactoringActionHandler;
+import com.intellij.util.IncorrectOperationException;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.InspectionGadgetsFix;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class InvertBooleanFix extends InspectionGadgetsFix {
+
+  private final String myName;
+
+  public InvertBooleanFix(String name) {
+    myName = name;
+  }
+
+  @NotNull
+  @Override
+  public String getName() {
+    return myName;
+  }
+
+  @NotNull
+  @Override
+  public String getFamilyName() {
+    return InspectionGadgetsBundle.message("invert.quickfix.family.name");
+  }
+
+  @Override
+  protected void doFix(final Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
+    final PsiNameIdentifierOwner owner = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiVariable.class, PsiMethod.class);
+    if (owner == null) {
+      return;
+    }
+    final RefactoringActionHandler handler = JavaRefactoringActionHandlerFactory.getInstance().createInvertBooleanHandler();
+    final Runnable runnable = new Runnable() {
+      @Override
+      public void run() {
+        handler.invoke(project, new PsiElement[]{owner}, null);
+      }
+    };
+    if (ApplicationManager.getApplication().isUnitTestMode()) {
+      runnable.run();
+    }
+    else {
+      ApplicationManager.getApplication().invokeLater(runnable, project.getDisposed());
+    }
+  }
+}
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/ProblematicWhitespaceInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/ProblematicWhitespaceInspection.java
new file mode 100644
index 0000000..8f823f0
--- /dev/null
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/ProblematicWhitespaceInspection.java
@@ -0,0 +1,165 @@
+/*
+ * 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.
+ */
+package com.siyeh.ig.style;
+
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorSettings;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiJavaFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.InspectionGadgetsFix;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class ProblematicWhitespaceInspection extends BaseInspection {
+
+  @Nls
+  @NotNull
+  @Override
+  public String getDisplayName() {
+    return InspectionGadgetsBundle.message("problematic.whitespace.display.name");
+  }
+
+  @NotNull
+  @Override
+  protected String buildErrorString(Object... infos) {
+    final Boolean useTabs = (Boolean)infos[2];
+    return useTabs.booleanValue()
+           ? InspectionGadgetsBundle.message("problematic.whitespace.spaces.problem.descriptor", (String)infos[0])
+           : InspectionGadgetsBundle.message("problematic.whitespace.tabs.problem.descriptor", (String)infos[0]);
+  }
+
+  @Nullable
+  @Override
+  protected InspectionGadgetsFix buildFix(Object... infos) {
+    final boolean buildFix = ((Boolean)infos[1]).booleanValue();
+    if (!buildFix) {
+      return null;
+    }
+    return new ShowWhitespaceFix();
+  }
+
+
+  private static class ShowWhitespaceFix extends InspectionGadgetsFix {
+
+    @NotNull
+    @Override
+    public String getName() {
+      return InspectionGadgetsBundle.message("problematic.whitespace.show.whitespaces.quickfix");
+    }
+
+    @NotNull
+    @Override
+    public String getFamilyName() {
+      return getName();
+    }
+
+    @Override
+    protected void doFix(Project project, ProblemDescriptor descriptor) {
+      final FileEditorManager editorManager = FileEditorManager.getInstance(project);
+      final Editor editor = editorManager.getSelectedTextEditor();
+      if (editor == null) {
+        return;
+      }
+      final EditorSettings settings = editor.getSettings();
+      settings.setWhitespacesShown(!settings.isWhitespacesShown());
+      editor.getComponent().repaint();
+    }
+  }
+
+
+  @Override
+  public BaseInspectionVisitor buildVisitor() {
+    return new ProblematicWhitespaceVisitor();
+  }
+
+  private static class ProblematicWhitespaceVisitor extends BaseInspectionVisitor {
+
+    @Override
+    public void visitJavaFile(PsiJavaFile file) {
+      super.visitJavaFile(file);
+      final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(file.getProject());
+      final CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions(JavaFileType.INSTANCE);
+      final boolean useTabs = indentOptions.USE_TAB_CHARACTER;
+      final boolean smartTabs = indentOptions.SMART_TABS;
+      final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
+      if (document == null) {
+        return;
+      }
+      final int lineCount = document.getLineCount();
+      int previousLineIndent = 0;
+      for (int i = 0; i < lineCount; i++) {
+        final int startOffset = document.getLineStartOffset(i);
+        final int endOffset = document.getLineEndOffset(i);
+        final String line = document.getText(new TextRange(startOffset, endOffset));
+        boolean spaceSeen = false;
+        for (int j = 0, length = line.length(); j < length; j++) {
+          final char c = line.charAt(j);
+          if (c == '\t') {
+            if (useTabs) {
+              if (smartTabs && spaceSeen) {
+                registerError(file, file.getName(), Boolean.valueOf(isOnTheFly()), Boolean.TRUE);
+                return;
+              }
+            }
+            else {
+              registerError(file, file.getName(), Boolean.valueOf(isOnTheFly()), Boolean.FALSE);
+              return;
+            }
+          }
+          else if (c == ' ') {
+            if (useTabs) {
+              if (!smartTabs) {
+                registerError(file, file.getName(), Boolean.valueOf(isOnTheFly()), Boolean.TRUE);
+                return;
+              }
+              else {
+                final int currentIndent = Math.max(0, j);
+                if (currentIndent != previousLineIndent) {
+                  registerError(file, file.getName(), Boolean.valueOf(isOnTheFly()), Boolean.TRUE);
+                  return;
+                }
+                previousLineIndent = currentIndent;
+              }
+            }
+            spaceSeen = true;
+          }
+          else {
+            if (!spaceSeen) {
+              previousLineIndent = Math.max(0, j);
+            }
+            break;
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NegativelyNamedBooleanVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NegativelyNamedBooleanVariable.html
new file mode 100644
index 0000000..5f3ded7
--- /dev/null
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NegativelyNamedBooleanVariable.html
@@ -0,0 +1,9 @@
+<html>
+<body>
+Reports negatively named variables, for example 'disabled', 'hidden', 'isNotChanged'.
+It is usually more clear to invert the <b>boolean</b> value and remove the negation from the name.
+<!-- tooltip end -->
+<p>
+<small>New in 13</small>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OverloadedVarargsMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OverloadedVarargsMethod.html
index 4961418..3df760d 100644
--- a/plugins/InspectionGadgets/src/inspectionDescriptions/OverloadedVarargsMethod.html
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OverloadedVarargsMethod.html
@@ -1,7 +1,7 @@
 <html>
 <body>
-Reports vararg methods, when there are one or more other methods with the
-same name present in a class. Overloaded varargs methods can be very confusing,
+Reports varargs methods, when there are other methods with the
+same name present in a class. Overloaded variable arity methods can be very confusing,
 as it is often not clear which overloading gets called.
 <!-- tooltip end -->
 <p>
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ProblematicVarargsMethodOverride.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ProblematicVarargsMethodOverride.html
new file mode 100644
index 0000000..769746d
--- /dev/null
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ProblematicVarargsMethodOverride.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+Reports methods overriding a variable arity (varargs) method with an array parameter. While this is legal Java, it can be confusing.
+<!-- tooltip end -->
+<p>
+<small>New in 13</small>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ProblematicWhitespace.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ProblematicWhitespace.html
new file mode 100644
index 0000000..9bde0506
--- /dev/null
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ProblematicWhitespace.html
@@ -0,0 +1,10 @@
+<html>
+<body>
+Reports tabs used for indentation when the code style is configured to use only spaces. Reports spaces used for indentation when
+the code style is configured to use only tabs. Reports spaces used for indentation and tabs used for alignment when the code
+style is configured to use smart tabs.
+<!-- tooltip end -->
+<p>
+<small>New in 13</small>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnicodeEscape.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnicodeEscape.html
index 0cb8778..f768541 100644
--- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnicodeEscape.html
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnicodeEscape.html
@@ -4,6 +4,6 @@
 Unicode control characters are not reported by this inspection.
   <!-- tooltip end -->
 <p>
-
+<small>New in 13</small>
 </body>
 </html>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/problematic_varargs_method_override/One.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/problematic_varargs_method_override/One.after.java
new file mode 100644
index 0000000..79dd8da
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/problematic_varargs_method_override/One.after.java
@@ -0,0 +1,14 @@
+package com.siyeh.igfixes.inheritance.problematic_varargs_method_override;
+
+class One {
+
+  public void m(String... ss) {}
+}
+class Two extends One {
+  public void m(String... ss) {}
+}
+class Three {
+  public static void main(String... args) {
+    new Two().m("1", "2", "3");
+  }
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/problematic_varargs_method_override/One.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/problematic_varargs_method_override/One.java
new file mode 100644
index 0000000..d74e7d0
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/problematic_varargs_method_override/One.java
@@ -0,0 +1,14 @@
+package com.siyeh.igfixes.inheritance.problematic_varargs_method_override;
+
+class One {
+
+  public void m(String... ss) {}
+}
+class Two extends One {
+  public void m<caret>(String[] ss) {}
+}
+class Three {
+  public static void main(String... args) {
+    new Two().m(new String[]{"1", "2", "3"});
+  }
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/variable_not_used_inside_if/VariableNotUsedInsideIf.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/variable_not_used_inside_if/VariableNotUsedInsideIf.java
index e8dcfc5..c6d1302 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/variable_not_used_inside_if/VariableNotUsedInsideIf.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/variable_not_used_inside_if/VariableNotUsedInsideIf.java
@@ -27,10 +27,10 @@
   }
 
   void bat(String s) {
-    if (s == null) {
+    if (s != null) {
       System.out.println();
     }
-    if (s != null) {
+    if (s == null) {
 
     } else {
       
@@ -38,8 +38,27 @@
   }
 
   void money(String s) {
-    if ((s == null)) {
+    if (((s) != (null))) {
       System.out.println();
     }
   }
+
+  void x(Integer x){
+    if (x != null) {
+      System.out.println();
+    }
+  }
+
+  int x(Integer x, int y){
+    if (x != null) return y;//oops, wrong one
+    return y;
+  }
+
+  int conditional(Integer x) {
+    return x == null ? 1 : someValue();
+  }
+
+  private int someValue() {
+    return 0;
+  }
 }
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/variable_not_used_inside_if/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/variable_not_used_inside_if/expected.xml
index a6d23f9..603a542 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/variable_not_used_inside_if/expected.xml
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/variable_not_used_inside_if/expected.xml
@@ -20,4 +20,25 @@
     <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Reference checked for 'null' is not used inside 'if'</problem_class>
     <description>&lt;code&gt;s&lt;/code&gt; is not used inside if #loc</description>
   </problem>
+
+  <problem>
+    <file>VariableNotUsedInsideIf.java</file>
+    <line>47</line>
+    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Reference checked for 'null' is not used inside 'if'</problem_class>
+    <description>&lt;code&gt;x&lt;/code&gt; checked for 'null' is not used inside 'if' #loc</description>
+  </problem>
+
+  <problem>
+    <file>VariableNotUsedInsideIf.java</file>
+    <line>53</line>
+    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Reference checked for 'null' is not used inside 'if'</problem_class>
+    <description>&lt;code&gt;x&lt;/code&gt; checked for 'null' is not used inside 'if' #loc</description>
+  </problem>
+
+  <problem>
+    <file>VariableNotUsedInsideIf.java</file>
+    <line>58</line>
+    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Reference checked for 'null' is not used inside 'if'</problem_class>
+    <description>&lt;code&gt;x&lt;/code&gt; checked for 'null' is not used inside conditional #loc</description>
+  </problem>
 </problems>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/BooleanParameterInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/BooleanParameterInspectionTest.java
index b0c134f..0cefd2c 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/BooleanParameterInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/BooleanParameterInspectionTest.java
@@ -25,7 +25,7 @@
 
   public void testSimple() {
     doTest("class X {" +
-           "  public void /*'public' method 'm' with 'boolean' parameter*/m/**/(boolean b) {}" +
+           "  public void /*'public' method 'm()' with 'boolean' parameter*/m/**/(boolean b) {}" +
            "  public void n() {}" +
            "  public void o(int i) {}" +
            "  void p(boolean b) {}" +
@@ -34,7 +34,7 @@
 
   public void testConstructor() {
     doTest("class X {" +
-           "  public /*'public' constructor 'X' with 'boolean' parameter*/X/**/(boolean x) {}" +
+           "  public /*'public' constructor 'X()' with 'boolean' parameter*/X/**/(boolean x) {}" +
            "}");
   }
 
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedRegexInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedRegexInspectionTest.java
index 68a1a06..a12eebc 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedRegexInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedRegexInspectionTest.java
@@ -1,7 +1,3 @@
-/**
- * (c) 2013 Desert Island BV
- * created: 20 09 2013
- */
 package com.siyeh.ig.bugs;
 
 import com.intellij.codeInspection.LocalInspectionTool;
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/NegativelyNamedBooleanVariableInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/NegativelyNamedBooleanVariableInspectionTest.java
new file mode 100644
index 0000000..d8ff328
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/NegativelyNamedBooleanVariableInspectionTest.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+package com.siyeh.ig.dataflow;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class NegativelyNamedBooleanVariableInspectionTest extends LightInspectionTestCase {
+
+  public void testTree() {
+    doTest("class X {" +
+           "  boolean /*Boolean variable 'hidden' is negatively named*/hidden/**/ = false;" +
+           "  boolean /*Boolean variable 'disabled' is negatively named*/disabled/**/ = false;" +
+           "  boolean /*Boolean variable 'isNotChanged' is negatively named*/isNotChanged/**/ = false;" +
+           "}");
+  }
+
+  @Override
+  protected InspectionProfileEntry getInspection() {
+    return new NegativelyNamedBooleanVariableInspection();
+  }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/inheritance/ProblematicVarargsMethodOverrideFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/inheritance/ProblematicVarargsMethodOverrideFixTest.java
new file mode 100644
index 0000000..0e94dc6
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/inheritance/ProblematicVarargsMethodOverrideFixTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+package com.siyeh.ig.fixes.inheritance;
+
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.IGQuickFixesTestCase;
+import com.siyeh.ig.inheritance.ProblematicVarargsMethodOverrideInspection;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class ProblematicVarargsMethodOverrideFixTest extends IGQuickFixesTestCase {
+
+  public void testOne() { doTest(); }
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    myFixture.enableInspections(new ProblematicVarargsMethodOverrideInspection());
+    myRelativePath = "inheritance/problematic_varargs_method_override";
+    myDefaultHint = InspectionGadgetsBundle.message("convert.to.variable.arity.method.quickfix");
+  }
+
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/ProblematicVarargsMethodOverrideInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/ProblematicVarargsMethodOverrideInspectionTest.java
new file mode 100644
index 0000000..46ec84b
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/ProblematicVarargsMethodOverrideInspectionTest.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+package com.siyeh.ig.inheritance;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class ProblematicVarargsMethodOverrideInspectionTest extends LightInspectionTestCase {
+
+  public void testSimple() {
+    doTest("class One {" +
+           "  void m(String... ss) {" +
+           "  }" +
+           "}" +
+           "class Two extends One {" +
+           "  void /*Non-varargs method 'm()' overrides varargs method*/m/**/(String[] ss) {" +
+           "  }" +
+           "}");
+  }
+
+  @Override
+  protected InspectionProfileEntry getInspection() {
+    return new ProblematicVarargsMethodOverrideInspection();
+  }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspectionTest.java
index 7079c5f..1ee8eab 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspectionTest.java
@@ -13,11 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-/**
- * (c) 2013 Desert Island BV
- * created: 23 09 2013
- */
 package com.siyeh.ig.internationalization;
 
 import com.intellij.codeInspection.LocalInspectionTool;
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/ExpectedExceptionNeverThrownInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/ExpectedExceptionNeverThrownInspectionTest.java
index e057666..d9ab5d6 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/ExpectedExceptionNeverThrownInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/ExpectedExceptionNeverThrownInspectionTest.java
@@ -1,7 +1,3 @@
-/**
- * (c) 2013 Desert Island BV
- * created: 14 08 2013
- */
 package com.siyeh.ig.junit;
 
 import com.intellij.codeInspection.LocalInspectionTool;
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ProblematicWhitespaceInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ProblematicWhitespaceInspectionTest.java
new file mode 100644
index 0000000..c0e062c
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ProblematicWhitespaceInspectionTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+package com.siyeh.ig.style;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.siyeh.ig.LightInspectionTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class ProblematicWhitespaceInspectionTest extends LightInspectionTestCase {
+
+  public void testTabsInFile() {
+    final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
+    settings.getIndentOptions(JavaFileType.INSTANCE).USE_TAB_CHARACTER = false;
+    doTest("/*File 'X.java' uses tabs for indentation*/class X {\n" +
+           "\tString s;\n" +
+           "}\n/**/");
+  }
+
+  public void testTabsInFile2() {
+    final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
+    settings.getIndentOptions(JavaFileType.INSTANCE).USE_TAB_CHARACTER = true;
+    doTest("class X {\n" +
+           "\tString s;\n" +
+           "}\n");
+  }
+
+  public void testSpacesInFile() {
+    final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
+    settings.getIndentOptions(JavaFileType.INSTANCE).USE_TAB_CHARACTER = true;
+    doTest("/*File 'X.java' uses spaces for indentation*/class X {\n" +
+           "  String s;\n" +
+           "}\n/**/");
+  }
+
+  public void testSpacesInFile2() {
+    final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
+    settings.getIndentOptions(JavaFileType.INSTANCE).USE_TAB_CHARACTER = false;
+    doTest("class X {\n" +
+           "  String s;\n" +
+           "}\n");
+  }
+
+  public void testSmartTabsInFile() {
+    final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
+    final CommonCodeStyleSettings.IndentOptions options = settings.getIndentOptions(JavaFileType.INSTANCE);
+    options.USE_TAB_CHARACTER = true;
+    options.SMART_TABS = true;
+    doTest("/*File 'X.java' uses spaces for indentation*/class X {\n" +
+           "  \tString s;\n" +
+           "}\n/**/");
+  }
+
+  @Override
+  protected InspectionProfileEntry getInspection() {
+    return new ProblematicWhitespaceInspection();
+  }
+}
diff --git a/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/ErrorPostponingMethodVisitor.java b/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/ErrorPostponingMethodVisitor.java
new file mode 100644
index 0000000..e47eab8
--- /dev/null
+++ b/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/ErrorPostponingMethodVisitor.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+package org.jetbrains.jps.intellilang.instrumentation;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.asm4.MethodVisitor;
+import org.jetbrains.asm4.Opcodes;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 11/5/13
+ */
+public class ErrorPostponingMethodVisitor extends MethodVisitor {
+
+  private final PatternInstrumenter myInstrumenter;
+  private final String myMethodName;
+
+  public ErrorPostponingMethodVisitor(@NotNull PatternInstrumenter instrumenter, String methodName, @Nullable MethodVisitor methodvisitor) {
+    super(Opcodes.ASM4, methodvisitor);
+    myInstrumenter = instrumenter;
+    myMethodName = methodName;
+  }
+
+  public void visitMaxs(int maxStack, int maxLocals) {
+    try {
+      super.visitMaxs(maxStack, maxLocals);
+    }
+    catch (Throwable e) {
+      myInstrumenter.registerError(myMethodName, "visitMaxs", e);
+    }
+  }
+}
diff --git a/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternInstrumenter.java b/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternInstrumenter.java
index 56e979a..083252c 100644
--- a/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternInstrumenter.java
+++ b/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternInstrumenter.java
@@ -183,7 +183,7 @@
     if ((access & ACC_STATIC) != 0 && name.equals("<clinit>")) {
       myHasStaticInitializer = true;
 
-      return new MethodVisitor(Opcodes.ASM4, methodvisitor) {
+      return new ErrorPostponingMethodVisitor(this, name, methodvisitor) {
         public void visitCode() {
           super.visitCode();
           patchStaticInitializer(mv);
@@ -206,7 +206,7 @@
       }
     }
 
-    return methodvisitor;
+    return new ErrorPostponingMethodVisitor(this, name, methodvisitor);
   }
 
   private static boolean isStringType(Type type) {
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypeIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypeIntention.java
index 729e5c2..4745c88 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypeIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypeIntention.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -13,11 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-/*
- * (c) 2012 Desert Island BV
- * created: 14 08 2012
- */
 package com.siyeh.ipp.decls;
 
 import com.intellij.psi.*;
diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/junit/FlipAssertLiteralIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/junit/FlipAssertLiteralIntentionTest.java
index edf3905..9837187 100644
--- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/junit/FlipAssertLiteralIntentionTest.java
+++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/junit/FlipAssertLiteralIntentionTest.java
@@ -1,7 +1,3 @@
-/**
- * (c) 2013 Desert Island BV
- * created: 08 09 2013
- */
 package com.siyeh.ipp.junit;
 
 import com.siyeh.IntentionPowerPackBundle;
diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntBuildModelImpl.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntBuildModelImpl.java
index e13e5bc..6739856 100644
--- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntBuildModelImpl.java
+++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntBuildModelImpl.java
@@ -30,8 +30,9 @@
 import com.intellij.psi.impl.PsiCachedValueImpl;
 import com.intellij.psi.util.CachedValue;
 import com.intellij.psi.util.CachedValueProvider;
-import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.psi.util.PsiModificationTracker;
 import com.intellij.psi.xml.XmlFile;
+import com.intellij.util.ArrayUtil;
 import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.Nullable;
 
@@ -48,9 +49,9 @@
     
     myTargets = new PsiCachedValueImpl<List<AntBuildTargetBase>>(PsiManager.getInstance(project), new CachedValueProvider<List<AntBuildTargetBase>>() {
       public Result<List<AntBuildTargetBase>> compute() {
-        final Pair<List<AntBuildTargetBase>, Collection<PsiFile>> result = getTargetListImpl(AntBuildModelImpl.this);
-        final Collection<PsiFile> deps = result.getSecond();
-        return Result.create(result.getFirst(), PsiUtilCore.toPsiFileArray(deps));
+        final Pair<List<AntBuildTargetBase>, Collection<Object>> result = getTargetListImpl(AntBuildModelImpl.this);
+        final Collection<Object> deps = result.getSecond();
+        return Result.create(result.getFirst(), ArrayUtil.toObjectArray(deps));
       }
     });    
   }
@@ -150,17 +151,16 @@
   }
 
   // todo: return list of dependent psi files as well
-  private static Pair<List<AntBuildTargetBase>, Collection<PsiFile>> getTargetListImpl(final AntBuildModelBase model) {
+  private static Pair<List<AntBuildTargetBase>, Collection<Object>> getTargetListImpl(final AntBuildModelBase model) {
     final List<AntBuildTargetBase> list = new ArrayList<AntBuildTargetBase>();
-    final Set<PsiFile> dependencies = new HashSet<PsiFile>();
+    final Set<Object> dependencies = new HashSet<Object>();
     
     final AntDomProject project = model.getAntProject();
     if (project != null) {
       final AntBuildFile buildFile = model.getBuildFile();
       final XmlFile xmlFile = buildFile.getAntFile();
-      if (xmlFile != null) {
-        dependencies.add(xmlFile);
-      }
+      dependencies.add(xmlFile != null? xmlFile : PsiModificationTracker.MODIFICATION_COUNT);
+
       final VirtualFile sourceFile = buildFile.getVirtualFile();
       new Object() {
         private boolean myIsImported = false;
@@ -189,20 +189,26 @@
           for (AntDomIncludingDirective incl : allIncludes) {
             final PsiFileSystemItem includedFile = incl.getFile().getValue();
             if (includedFile instanceof PsiFile) {
+              final PsiFile included = includedFile.getContainingFile().getOriginalFile();
+              dependencies.add(included);
               final AntDomProject includedProject = AntSupport.getAntDomProject((PsiFile)includedFile);
               if (includedProject != null) {
-                final PsiFile included = includedFile.getContainingFile().getOriginalFile();
-                dependencies.add(included);
                 fillTargets(list, model, includedProject, included.getVirtualFile());
               }
             }
-
+            else {
+              if (includedFile == null) {
+                // if not resolved yet, it's possible that the file will be created later,
+                // thus we need to recalculate the cached value
+                dependencies.add(PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
+              }
+            }
           }
     
         }
       }.fillTargets(list, model, project, sourceFile);
     }
-    return new Pair<List<AntBuildTargetBase>, Collection<PsiFile>>(list, dependencies);
+    return new Pair<List<AntBuildTargetBase>, Collection<Object>>(list, dependencies);
   }
 
 }
diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java
index 5cf28c8..7eec6e9 100644
--- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java
+++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java
@@ -29,7 +29,6 @@
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
 import com.intellij.openapi.application.Application;
 import com.intellij.openapi.application.ApplicationManager;
@@ -687,14 +686,13 @@
   }
 
   private void loadBuildFileProjectProperties(final Element parentNode) {
-    final List<Pair<Element, VirtualFile>> files = new ArrayList<Pair<Element, VirtualFile>>();
+    final List<Pair<Element, String>> files = new ArrayList<Pair<Element, String>>();
     final VirtualFileManager vfManager = VirtualFileManager.getInstance();
     for (final Object o : parentNode.getChildren(BUILD_FILE)) {
       final Element element = (Element)o;
       final String url = element.getAttributeValue(URL);
-      final VirtualFile file = vfManager.findFileByUrl(url);
-      if (file != null) {
-        files.add(new Pair<Element, VirtualFile>(element, file));
+      if (url != null) {
+        files.add(new Pair<Element, String>(element, url));
       }
     }
     
@@ -732,9 +730,12 @@
                 }
                 // then fill the configuration with the files configured in xml
                 List<Pair<Element, AntBuildFileBase>> buildFiles = new ArrayList<Pair<Element, AntBuildFileBase>>(files.size());
-                for (Pair<Element, VirtualFile> pair : files) {
+                for (Pair<Element, String> pair : files) {
                   final Element element = pair.getFirst();
-                  final VirtualFile file = pair.getSecond();
+                  final VirtualFile file = vfManager.findFileByUrl(pair.getSecond());
+                  if (file == null) {
+                    continue;
+                  }
                   try {
                     final AntBuildFileBase buildFile = addBuildFileImpl(file);
                     buildFile.readProperties(element);
diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java
index 6c349e0..20ef584 100644
--- a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java
+++ b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java
@@ -33,8 +33,9 @@
 import com.intellij.openapi.ui.popup.JBPopupFactory;
 import com.intellij.openapi.ui.popup.PopupStep;
 import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
-import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Consumer;
 import com.intellij.util.IconUtil;
 import com.intellij.util.PlatformIcons;
 import com.intellij.util.containers.HashMap;
@@ -48,6 +49,7 @@
 
 import javax.swing.*;
 import javax.swing.tree.TreePath;
+import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -80,6 +82,7 @@
     return "Copyright.UI";
   }
 
+  @Override
   protected void processRemovedItems() {
     Map<String, CopyrightProfile> profiles = getAllProfiles();
     final List<CopyrightProfile> deleted = new ArrayList<CopyrightProfile>();
@@ -93,16 +96,19 @@
     }
   }
 
+  @Override
   protected boolean wasObjectStored(Object o) {
     return myManager.getCopyrights().contains((CopyrightProfile)o);
   }
 
+  @Override
   @Nls
   public String getDisplayName() {
     return "Copyright Profiles";
   }
 
-  @Nullable
+  @Override
+  @NotNull
   @NonNls
   public String getHelpTopic() {
     return "copyright.profiles";
@@ -114,6 +120,7 @@
     }
   }
 
+  @Override
   public void apply() throws ConfigurationException {
     final Set<String> profiles = new HashSet<String>();
     for (int i = 0; i < myRoot.getChildCount(); i++) {
@@ -151,6 +158,7 @@
     myInitialized.set(false);
   }
 
+  @Override
   @Nullable
   protected ArrayList<AnAction> createActions(boolean fromPopup) {
     ArrayList<AnAction> result = new ArrayList<AnAction>();
@@ -159,6 +167,7 @@
         registerCustomShortcutSet(CommonShortcuts.INSERT, myTree);
       }
 
+      @Override
       public void actionPerformed(AnActionEvent event) {
         final String name = askForProfileName("Create Copyright Profile", "");
         if (name == null) return;
@@ -169,9 +178,10 @@
     result.add(new MyDeleteAction());
     result.add(new AnAction("Copy", "Copy", PlatformIcons.COPY_ICON) {
       {
-        registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_D, KeyEvent.CTRL_MASK)), myTree);
+        registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.CTRL_MASK)), myTree);
       }
 
+      @Override
       public void actionPerformed(AnActionEvent event) {
         final String profileName = askForProfileName("Copy Copyright Profile", "");
         if (profileName == null) return;
@@ -181,12 +191,14 @@
         addProfileNode(clone);
       }
 
+      @Override
       public void update(AnActionEvent event) {
         super.update(event);
         event.getPresentation().setEnabled(getSelectedObject() != null);
       }
     });
     result.add(new AnAction("Import", "Import", PlatformIcons.IMPORT_ICON) {
+      @Override
       public void actionPerformed(AnActionEvent event) {
         final OpenProjectFileChooserDescriptor descriptor = new OpenProjectFileChooserDescriptor(true) {
           @Override
@@ -204,38 +216,41 @@
           }
         };
         descriptor.setTitle("Choose file containing copyright notice");
-        final VirtualFile file = FileChooser.chooseFile(descriptor, myProject, null);
-        if (file == null) return;
-
-        final List<CopyrightProfile> copyrightProfiles = ExternalOptionHelper.loadOptions(VfsUtil.virtualToIoFile(file));
-        if (copyrightProfiles == null) return;
-        if (!copyrightProfiles.isEmpty()) {
-          if (copyrightProfiles.size() == 1) {
-            importProfile(copyrightProfiles.get(0));
-          }
-          else {
-            JBPopupFactory.getInstance()
-              .createListPopup(new BaseListPopupStep<CopyrightProfile>("Choose profile to import", copyrightProfiles) {
-                @Override
-                public PopupStep onChosen(final CopyrightProfile selectedValue, boolean finalChoice) {
-                  return doFinalStep(new Runnable() {
-                    public void run() {
-                      importProfile(selectedValue);
+        FileChooser.chooseFile(descriptor, myProject, null, new Consumer<VirtualFile>() {
+          @Override
+          public void consume(VirtualFile file) {
+            final List<CopyrightProfile> copyrightProfiles = ExternalOptionHelper.loadOptions(VfsUtilCore.virtualToIoFile(file));
+            if (copyrightProfiles == null) return;
+            if (!copyrightProfiles.isEmpty()) {
+              if (copyrightProfiles.size() == 1) {
+                importProfile(copyrightProfiles.get(0));
+              }
+              else {
+                JBPopupFactory.getInstance()
+                  .createListPopup(new BaseListPopupStep<CopyrightProfile>("Choose profile to import", copyrightProfiles) {
+                    @Override
+                    public PopupStep onChosen(final CopyrightProfile selectedValue, boolean finalChoice) {
+                      return doFinalStep(new Runnable() {
+                        @Override
+                        public void run() {
+                          importProfile(selectedValue);
+                        }
+                      });
                     }
-                  });
-                }
 
-                @NotNull
-                @Override
-                public String getTextFor(CopyrightProfile value) {
-                  return value.getName();
-                }
-              }).showUnderneathOf(myNorthPanel);
+                    @NotNull
+                    @Override
+                    public String getTextFor(CopyrightProfile value) {
+                      return value.getName();
+                    }
+                  }).showUnderneathOf(myNorthPanel);
+              }
+            }
+            else {
+              Messages.showWarningDialog(myProject, "The selected file does not contain any copyright settings.", "Import Failure");
+            }
           }
-        }
-        else {
-          Messages.showWarningDialog(myProject, "The selected file does not contain any copyright settings.", "Import Failure");
-        }
+        });
       }
 
       private void importProfile(CopyrightProfile copyrightProfile) {
@@ -253,10 +268,12 @@
   @Nullable
   private String askForProfileName(String title, String initialName) {
     return Messages.showInputDialog("New copyright profile name:", title, Messages.getQuestionIcon(), initialName, new InputValidator() {
+      @Override
       public boolean checkInput(String s) {
         return !getAllProfiles().containsKey(s) && s.length() > 0;
       }
 
+      @Override
       public boolean canClose(String s) {
         return checkInput(s);
       }
@@ -289,6 +306,7 @@
     myInitialized.set(true);
   }
 
+  @Override
   public void reset() {
     reloadTree();
     super.reset();
@@ -301,21 +319,25 @@
 
   public void addItemsChangeListener(final Runnable runnable) {
     addItemsChangeListener(new ItemsChangeListener() {
+      @Override
       public void itemChanged(@Nullable Object deletedItem) {
         SwingUtilities.invokeLater(runnable);
       }
 
+      @Override
       public void itemsExternallyChanged() {
         SwingUtilities.invokeLater(runnable);
       }
     });
   }
 
+  @Override
   @NotNull
   public String getId() {
     return getHelpTopic();
   }
 
+  @Override
   public Runnable enableSearch(String option) {
     return null;
   }
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/CommandWrapper.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/CommandWrapper.java
deleted file mode 100644
index eb5e1a3..0000000
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/CommandWrapper.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2000-2009 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.
- */
-package com.intellij.cvsSupport2.cvsoperations.dateOrRevision;
-
-import org.netbeans.lib.cvsclient.command.Command;
-import org.netbeans.lib.cvsclient.command.checkout.CheckoutCommand;
-import org.netbeans.lib.cvsclient.command.checkout.ExportCommand;
-import org.netbeans.lib.cvsclient.command.update.UpdateCommand;
-
-/**
- * author: lesya
- */
-public class CommandWrapper {
-  private final Command myCommand;
-
-  public CommandWrapper(Command command) {
-    myCommand = command;
-  }
-
-  @SuppressWarnings({"HardCodedStringLiteral"})
-  public void setUpdateByRevisionOrDate(String revision, final String date) {
-    if (isCheckoutCommand()) {
-      asCheckoutCommand().setUpdateByRevisionOrTag(revision);
-      asCheckoutCommand().setUpdateByDate(date);
-    }
-    else if (isUpdateCommand()) {
-      asUpdateCommand().setUpdateByRevisionOrTag(revision);
-      asUpdateCommand().setUpdateByDate(date);
-    }
-    else if (isExportCommand()) {
-      asExportCommand().setUpdateByRevisionOrTag(revision == null && date == null ? "HEAD" : revision);
-      asExportCommand().setUpdateByDate(date);
-    }
-  }
-
-  private UpdateCommand asUpdateCommand() {
-    return ((UpdateCommand)myCommand);
-  }
-
-  private CheckoutCommand asCheckoutCommand() {
-    return ((CheckoutCommand)myCommand);
-  }
-
-  private ExportCommand asExportCommand() {
-    return ((ExportCommand)myCommand);
-  }
-
-  private boolean isUpdateCommand() {
-    return myCommand instanceof UpdateCommand;
-  }
-
-  private boolean isCheckoutCommand() {
-    return myCommand instanceof CheckoutCommand;
-  }
-
-  private boolean isExportCommand() {
-    return myCommand instanceof ExportCommand;
-  }
-
-}
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/RevisionOrDateImpl.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/RevisionOrDateImpl.java
index 3c1a461..1e8f854 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/RevisionOrDateImpl.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/RevisionOrDateImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -19,20 +19,28 @@
 import com.intellij.cvsSupport2.application.CvsEntriesManager;
 import com.intellij.cvsSupport2.config.DateOrRevisionSettings;
 import com.intellij.cvsSupport2.history.CvsRevisionNumber;
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.netbeans.lib.cvsclient.admin.Entry;
 import org.netbeans.lib.cvsclient.command.Command;
-import org.jetbrains.annotations.NotNull;
+
+import java.text.ParseException;
+import java.util.Date;
 
 /**
- * author: lesya
+ * @author lesya
  */
 public class RevisionOrDateImpl implements RevisionOrDate {
-  private String myStickyTag;
-  private String myStickyDate;
+
+  private static final Logger LOG = Logger.getInstance(RevisionOrDateImpl.class);
+
+  @Nullable private String myStickyTag;
+  @Nullable private Date myStickyDate;
 
   public static RevisionOrDate createOn(@NotNull VirtualFile file) {
-    VirtualFile parent = file.getParent();
+    final VirtualFile parent = file.getParent();
     return new RevisionOrDateImpl(parent, CvsEntriesManager.getInstance().getEntryFor(parent, file.getName()));
   }
 
@@ -41,27 +49,25 @@
   }
 
   public static RevisionOrDate createOn(VirtualFile parent, Entry entry, DateOrRevisionSettings config) {
-    RevisionOrDateImpl result = new RevisionOrDateImpl(parent, entry);
+    final RevisionOrDateImpl result = new RevisionOrDateImpl(parent, entry);
     updateOn(result, config);
     return result;
   }
 
   private static void updateOn(RevisionOrDateImpl result, DateOrRevisionSettings config) {
-    String stickyTagFromConfig = config.USE_BRANCH ? config.BRANCH : null;
-    String stickyDateFromConfig = config.USE_DATE ? config.getDate() : null;
+    final String stickyTagFromConfig = config.USE_BRANCH ? config.BRANCH : null;
+    final String stickyDateFromConfig = config.USE_DATE ? config.getDate() : null;
     result.setStickyInfo(stickyTagFromConfig, stickyDateFromConfig);
   }
 
   @NotNull
   public static RevisionOrDate createOn(DateOrRevisionSettings config) {
-    RevisionOrDateImpl result = new RevisionOrDateImpl();
+    final RevisionOrDateImpl result = new RevisionOrDateImpl();
     updateOn(result, config);
     return result;
   }
 
-  private RevisionOrDateImpl() {
-
-  }
+  private RevisionOrDateImpl() {}
 
   private RevisionOrDateImpl(VirtualFile parent, Entry entry) {
     if (entry == null) {
@@ -75,7 +81,7 @@
         myStickyTag = entry.getStickyTag();
       }
       else if (entry.getStickyDateString() != null) {
-        myStickyDate = entry.getStickyDateString();
+        myStickyDate = entry.getStickyDate();
       }
       else {
         lookupDirectory(parent);
@@ -91,22 +97,34 @@
     }
     else {
       myStickyTag = null;
-      myStickyDate = stickyDate;
+      try {
+        myStickyDate = Entry.getLastModifiedDateFormatter().parse(stickyDate);
+      }
+      catch (ParseException e) {
+        LOG.error(e);
+      }
     }
   }
 
   public void setForCommand(Command command) {
-    CommandWrapper wrapper = new CommandWrapper(command);
-    wrapper.setUpdateByRevisionOrDate(myStickyTag, myStickyDate);
+    command.setUpdateByRevisionOrDate(myStickyTag, myStickyDate == null ? null : Entry.getLastModifiedDateFormatter().format(myStickyDate));
   }
 
   private void lookupDirectory(VirtualFile directory) {
-    String stickyTag = CvsUtil.getStickyTagForDirectory(directory);
+    final String stickyTag = CvsUtil.getStickyTagForDirectory(directory);
     if (stickyTag != null) {
       myStickyTag = stickyTag;
       return;
     }
-    myStickyDate = CvsUtil.getStickyDateForDirectory(directory);
+    try {
+      final String stickyDateString = CvsUtil.getStickyDateForDirectory(directory);
+      if (stickyDateString != null) {
+        myStickyDate = Entry.STICKY_DATE_FORMAT.parse(stickyDateString);
+      }
+    }
+    catch (ParseException e) {
+      LOG.error(e);
+    }
   }
 
   public String getRevision() {
@@ -121,14 +139,15 @@
     try {
       return new CvsRevisionNumber(myStickyTag);
     }
-    catch (NumberFormatException ex) {
+    catch (NumberFormatException e) {
+      LOG.error(e);
       return null;
     }
   }
 
   public String toString() {
     if (myStickyDate != null) {
-      return myStickyDate;
+      return Entry.getLastModifiedDateFormatter().format(myStickyDate);
     } else {
       return myStickyTag;
     }
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/SimpleRevision.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/SimpleRevision.java
index 9100952..3f85ecc 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/SimpleRevision.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/SimpleRevision.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -47,7 +47,7 @@
   }
 
   public void setForCommand(Command command) {
-    new CommandWrapper(command).setUpdateByRevisionOrDate(myRevision, null);
+    command.setUpdateByRevisionOrDate(myRevision, null);
   }
 
   public CvsRevisionNumber getCvsRevisionNumber() {
diff --git a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/Command.java b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/Command.java
index 829d415..9ed3bb1 100644
--- a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/Command.java
+++ b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/Command.java
@@ -95,4 +95,8 @@
                         globalOptions.reset();
                 }
         }
+
+        public void setUpdateByRevisionOrDate(String revision, final String date) {
+                throw new UnsupportedOperationException();
+        }
 }
diff --git a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/CheckoutCommand.java b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/CheckoutCommand.java
index 3a82568..84f0803 100644
--- a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/CheckoutCommand.java
+++ b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/CheckoutCommand.java
@@ -354,4 +354,10 @@
     }
     return cvsArguments.toString();
   }
+
+  @Override
+  public void setUpdateByRevisionOrDate(String revision, String date) {
+    setUpdateByRevisionOrTag(revision);
+    setUpdateByDate(date);
+  }
 }
diff --git a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/ExportCommand.java b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/ExportCommand.java
index aa4ce6c..712cb54 100644
--- a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/ExportCommand.java
+++ b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/ExportCommand.java
@@ -248,4 +248,9 @@
 		}
 		return cvsArguments.toString();
 	}
+
+	public void setUpdateByRevisionOrDate(String revision, final String date) {
+		setUpdateByRevisionOrTag(revision == null && date == null ? "HEAD" : revision);
+		setUpdateByDate(date);
+	}
 }
diff --git a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/update/UpdateCommand.java b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/update/UpdateCommand.java
index 7cdd085..9f81b31 100644
--- a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/update/UpdateCommand.java
+++ b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/update/UpdateCommand.java
@@ -285,7 +285,7 @@
 		}
 		if (getKeywordSubst() != null) {
 			cvsArguments.append("-k");
-			cvsArguments.append(getKeywordSubst().toString());
+			cvsArguments.append(getKeywordSubst());
 			cvsArguments.append(' ');
 		}
 		if (getUpdateByRevision() != null) {
@@ -311,4 +311,9 @@
 		}
 		return cvsArguments.toString();
 	}
+
+	public void setUpdateByRevisionOrDate(String revision, final String date) {
+		setUpdateByRevisionOrTag(revision);
+		setUpdateByDate(date);
+	}
 }
diff --git a/plugins/devkit/resources/META-INF/plugin.xml b/plugins/devkit/resources/META-INF/plugin.xml
index e0a0ae7..8e26284 100644
--- a/plugins/devkit/resources/META-INF/plugin.xml
+++ b/plugins/devkit/resources/META-INF/plugin.xml
@@ -3,6 +3,10 @@
   <id>DevKit</id>
   <version>1.0</version>
 
+  <description>
+    IntelliJ Platform plugin development kit.
+  </description>
+
   <category>inspection</category>
   <vendor>JetBrains</vendor>
 
@@ -96,6 +100,9 @@
     <psi.referenceContributor implementation="org.jetbrains.idea.devkit.references.IconsReferencesContributor"/>
     <referencesSearch implementation="org.jetbrains.idea.devkit.references.IconsReferencesContributor"/>
     <unusedDeclarationFixProvider implementation="org.jetbrains.idea.devkit.inspections.quickfix.RegisterExtensionFixProvider"/>
+
+    <stacktrace.fold substring="at com.intellij.testFramework."/>
+
   </extensions>
 
   <module-components>
@@ -136,7 +143,8 @@
     </action>
 
     <group id="Internal.DevKit" internal="true" text="DevKit" popup="true">
-      <action internal="true" class="org.jetbrains.idea.devkit.actions.ToggleHighlightingMarkupAction" text="Toggle Expected Highlighting Markup"
+      <action internal="true" class="org.jetbrains.idea.devkit.actions.ToggleHighlightingMarkupAction"
+              text="Toggle Expected Highlighting Markup"
               id="ToggleHighlightingMarkup"/>
 
       <action internal="true" class="org.jetbrains.idea.devkit.actions.ShuffleNamesAction" text="Shuffle Names"
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java b/plugins/devkit/src/dom/Abbreviation.java
similarity index 61%
copy from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java
copy to plugins/devkit/src/dom/Abbreviation.java
index bed999e..4f5be39d5 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java
+++ b/plugins/devkit/src/dom/Abbreviation.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -13,12 +13,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jetbrains.plugins.groovy.lang;
+package org.jetbrains.idea.devkit.dom;
 
-import com.intellij.ide.hierarchy.type.JavaTypeHierarchyProvider;
+import com.intellij.util.xml.DomElement;
+import com.intellij.util.xml.GenericAttributeValue;
+import org.jetbrains.annotations.NotNull;
 
 /**
- * @author peter
+ * @author Konstantin Bulenkov
  */
-public class GroovyTypeHierarchyProvider extends JavaTypeHierarchyProvider{
+public interface Abbreviation extends DomElement {
+  @NotNull
+  GenericAttributeValue<String> getValue();
 }
diff --git a/plugins/devkit/src/dom/Action.java b/plugins/devkit/src/dom/Action.java
index 02ced123..be3d595 100644
--- a/plugins/devkit/src/dom/Action.java
+++ b/plugins/devkit/src/dom/Action.java
@@ -129,6 +129,18 @@
 	 */
 	Shortcut addShortcut();
 
+        /**
+ 	 * Returns the list of abbreviation children.
+ 	 * @return the list of abbreviation children.
+ 	 */
+ 	@NotNull
+ 	List<Abbreviation> getAbbreviations();
+
+ 	/**
+ 	 * Adds new child to the list of abbreviation children.
+ 	 * @return created child
+ 	 */
+        Abbreviation addAbbreviation();
 
 	/**
 	 * Returns the list of add-to-group children.
diff --git a/plugins/devkit/src/module/PluginModuleType.java b/plugins/devkit/src/module/PluginModuleType.java
index 56bc22db..b97ec1b 100644
--- a/plugins/devkit/src/module/PluginModuleType.java
+++ b/plugins/devkit/src/module/PluginModuleType.java
@@ -17,7 +17,6 @@
 
 import com.intellij.icons.AllIcons;
 import com.intellij.openapi.module.*;
-import com.intellij.openapi.project.Project;
 import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.roots.ModuleRootManager;
 import com.intellij.openapi.util.IconLoader;
@@ -123,15 +122,4 @@
   public boolean isValidSdk(@NotNull final Module module, final Sdk projectSdk) {
     return JavaModuleType.isValidJavaSdk(module);
   }
-
-  public static Module[] getAllPluginModules(final Project project) {
-    List<Module> modules = new ArrayList<Module>();
-    Module[] allModules = ModuleManager.getInstance(project).getModules();
-    for (Module module : allModules) {
-      if (get(module) == getInstance()) {
-        modules.add(module);
-      }
-    }
-    return modules.toArray(new Module[modules.size()]);
-  }
 }
diff --git a/plugins/devkit/src/run/PluginConfigurationType.java b/plugins/devkit/src/run/PluginConfigurationType.java
index 8f7394a..cb25590 100644
--- a/plugins/devkit/src/run/PluginConfigurationType.java
+++ b/plugins/devkit/src/run/PluginConfigurationType.java
@@ -22,8 +22,10 @@
 import com.intellij.icons.AllIcons;
 import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.idea.devkit.DevKitBundle;
 import org.jetbrains.idea.devkit.module.PluginModuleType;
@@ -31,6 +33,7 @@
 import javax.swing.*;
 import java.io.File;
 import java.io.IOException;
+import java.util.Collection;
 
 public class PluginConfigurationType implements ConfigurationType {
   private final ConfigurationFactory myFactory;
@@ -49,6 +52,11 @@
       }
 
       @Override
+      public boolean isApplicable(@NotNull Project project) {
+        return ModuleUtil.hasModulesOfType(project, PluginModuleType.getInstance());
+      }
+
+      @Override
       public boolean isConfigurationSingletonByDefault() {
         return true;
       }
@@ -56,10 +64,9 @@
       public RunConfiguration createConfiguration(String name, RunConfiguration template) {
         final PluginRunConfiguration pluginRunConfiguration = (PluginRunConfiguration)template;
         if (pluginRunConfiguration.getModule() == null) {
-          final Module[] modules = PluginModuleType.getAllPluginModules(pluginRunConfiguration.getProject());
-          if (modules.length > 0){
-            pluginRunConfiguration.setModule(modules[0]);
-          }
+          final Collection<Module> modules = ModuleUtil
+            .getModulesOfType(pluginRunConfiguration.getProject(), PluginModuleType.getInstance());
+          pluginRunConfiguration.setModule(ContainerUtil.getFirstItem(modules));
         }
         return super.createConfiguration(name, pluginRunConfiguration);
       }
diff --git a/plugins/devkit/src/util/ActionType.java b/plugins/devkit/src/util/ActionType.java
index f703709..36b4d9db 100644
--- a/plugins/devkit/src/util/ActionType.java
+++ b/plugins/devkit/src/util/ActionType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -19,8 +19,9 @@
 import com.intellij.openapi.actionSystem.ActionGroup;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.keymap.KeymapManager;
-import com.intellij.psi.PsiClass;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
 import com.intellij.psi.xml.XmlFile;
 import com.intellij.psi.xml.XmlTag;
 import com.intellij.util.IncorrectOperationException;
@@ -83,10 +84,10 @@
       XmlTag actionTag = (XmlTag)actions.add(actions.createChildTag(myName, actions.getNamespace(), null, false));
       actionTag.setAttribute("id", dialog.getActionId());
       actionTag.setAttribute("class", klass.getQualifiedName());
-      actionTag.setAttribute("text", dialog.getActionText());
+      actionTag.setAttribute("text", StringUtil.escapeXml(dialog.getActionText()));
       String description = dialog.getActionDescription();
       if (description != null && description.length() > 0) {
-        actionTag.setAttribute("description", description);
+        actionTag.setAttribute("description", StringUtil.escapeXml(description));
       }
 
       String groupId = dialog.getSelectedGroupId();
diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ElementFactory.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ElementFactory.java
index 68c60c8..be60bff 100644
--- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ElementFactory.java
+++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ElementFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2012 the original author or authors.
+ * Copyright 2001-2013 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -44,7 +44,9 @@
 
     // super
     PsiClass superClass = clazz.getSuperClass();
-    ce.setSuperName((superClass == null) ? null : superClass.getName());
+    if (superClass != null && !CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) {
+      ce.setSuperName(superClass.getName());
+    }
 
     // interfaces
     ce.setImplementNames(PsiAdapter.getImplementsClassnames(clazz));
diff --git a/plugins/git4idea/remote-servers-git/remote-servers-git.iml b/plugins/git4idea/remote-servers-git/remote-servers-git.iml
new file mode 100644
index 0000000..07e0637
--- /dev/null
+++ b/plugins/git4idea/remote-servers-git/remote-servers-git.iml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/resources" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="remote-servers-agent-rt" />
+    <orderEntry type="module" module-name="core-api" />
+    <orderEntry type="module" module-name="vcs-api" />
+    <orderEntry type="module" module-name="remote-servers-api" />
+    <orderEntry type="module" module-name="git4idea" />
+    <orderEntry type="module" module-name="remote-servers-impl" />
+    <orderEntry type="module" module-name="lang-api" />
+    <orderEntry type="module" module-name="lang-impl" />
+  </component>
+</module>
+
diff --git a/plugins/git4idea/remote-servers-git/resources/resources/cloud.properties b/plugins/git4idea/remote-servers-git/resources/resources/cloud.properties
new file mode 100644
index 0000000..f7637990
--- /dev/null
+++ b/plugins/git4idea/remote-servers-git/resources/resources/cloud.properties
@@ -0,0 +1,8 @@
+cloud.undeploy.confirm.title=Confirm delete application
+cloud.undeploy.confirm.message=Are you sure to delete the application \"{0}\"?\nPlease enter your account password to confirm
+cloud.undeploy.confirm.password.incorrect=Password incorrect\!
+failed.add.remote=Failed to add {0} repository as remote
+failed.reset.remote=Failed to set {0} repository as remote
+cloning.existing.application=Cloning existing {0} application
+fetching.application=Fetching {0} application
+
diff --git a/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudBundle.java b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudBundle.java
new file mode 100644
index 0000000..b2036536
--- /dev/null
+++ b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudBundle.java
@@ -0,0 +1,37 @@
+package com.intellij.remoteServer.util;
+
+import com.intellij.CommonBundle;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.PropertyKey;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.ResourceBundle;
+
+/**
+ * @author michael.golubev
+ */
+public class CloudBundle {
+
+  private static Reference<ResourceBundle> ourBundle;
+
+  @NonNls private static final String BUNDLE = "resources.cloud";
+
+  private CloudBundle() {
+
+  }
+
+  public static String getText(@PropertyKey(resourceBundle = BUNDLE) String key, Object... params) {
+    return CommonBundle.message(getBundle(), key, params);
+  }
+
+  private static ResourceBundle getBundle() {
+    ResourceBundle bundle = null;
+    if (ourBundle != null) bundle = ourBundle.get();
+    if (bundle == null) {
+      bundle = ResourceBundle.getBundle(BUNDLE);
+      ourBundle = new SoftReference<ResourceBundle>(bundle);
+    }
+    return bundle;
+  }
+}
diff --git a/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentRuntime.java b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentRuntime.java
new file mode 100644
index 0000000..ba78e40
--- /dev/null
+++ b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentRuntime.java
@@ -0,0 +1,508 @@
+package com.intellij.remoteServer.util;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.remoteServer.agent.util.CloudGitAgent;
+import com.intellij.remoteServer.agent.util.CloudGitAgentDeployment;
+import com.intellij.remoteServer.agent.util.CloudGitApplication;
+import com.intellij.remoteServer.agent.util.CloudGitLoggingHandler;
+import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
+import com.intellij.remoteServer.configuration.deployment.ModuleDeploymentSource;
+import com.intellij.remoteServer.runtime.ServerTaskExecutor;
+import com.intellij.remoteServer.runtime.deployment.DeploymentRuntime;
+import com.intellij.remoteServer.runtime.deployment.DeploymentTask;
+import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance;
+import com.intellij.util.ThrowableRunnable;
+import com.intellij.util.concurrency.Semaphore;
+import git4idea.GitUtil;
+import git4idea.actions.GitInit;
+import git4idea.commands.*;
+import git4idea.repo.GitRemote;
+import git4idea.repo.GitRepository;
+import git4idea.repo.GitRepositoryManager;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author michael.golubev
+ */
+public abstract class CloudGitDeploymentRuntime<DC extends CloudDeploymentNameConfiguration,
+  AD extends CloudGitAgentDeployment,
+  A extends CloudGitAgent<?, AD>> extends DeploymentRuntime {
+
+  private static final Logger LOG = Logger.getInstance("#" + CloudGitDeploymentRuntime.class.getName());
+  private final String myApplicationName;
+  private final CloudConfigurationBase myConfiguration;
+
+  private final Project myProject;
+  private final GitRepositoryManager myGitRepositoryManager;
+  private final Git myGit;
+
+  private final VirtualFile myContentRoot;
+  private final File myContentRootFile;
+  private final AgentTaskExecutor myAgentTaskExecutor;
+  private final String myPresentableName;
+  private final CloudGitLoggingHandler myLoggingHandler;
+  private final ServerTaskExecutor myTasksExecutor;
+  private final AD myDeployment;
+
+  private final String myRemoteName;
+  private final String myCloudName;
+
+  private GitRepository myRepository;
+
+  public CloudGitDeploymentRuntime(CloudConfigurationBase serverConfiguration,
+                                   A agent,
+                                   ServerTaskExecutor taskExecutor,
+                                   DeploymentTask<DC> task,
+                                   AgentTaskExecutor agentTaskExecutor,
+                                   CloudGitLoggingHandler loggingHandler,
+                                   CloudDeploymentNameProvider deploymentNameProvider,
+                                   String remoteName,
+                                   String cloudName) throws ServerRuntimeException {
+    myConfiguration = serverConfiguration;
+    myTasksExecutor = taskExecutor;
+
+    myRemoteName = remoteName;
+    myCloudName = cloudName;
+
+    DeploymentSource deploymentSource = task.getSource();
+    if (!(deploymentSource instanceof ModuleDeploymentSource)) {
+      throw new ServerRuntimeException("Module deployment source is the only supported");
+    }
+
+    ModuleDeploymentSource moduleDeploymentSource = (ModuleDeploymentSource)deploymentSource;
+    Module module = moduleDeploymentSource.getModule();
+    if (module == null) {
+      throw new ServerRuntimeException("Module not found: " + moduleDeploymentSource.getModulePointer().getModuleName());
+    }
+
+    VirtualFile contentRoot = moduleDeploymentSource.getContentRoot();
+    LOG.assertTrue(contentRoot != null, "Content root is not found");
+    myContentRoot = contentRoot;
+
+    File contentRootFile = moduleDeploymentSource.getFile();
+    LOG.assertTrue(contentRootFile != null, "Content root file is not found");
+    myContentRootFile = contentRootFile;
+
+    myProject = task.getProject();
+    myGitRepositoryManager = GitUtil.getRepositoryManager(myProject);
+    myGit = ServiceManager.getService(Git.class);
+    if (myGit == null) {
+      throw new ServerRuntimeException("Can't initialize GIT");
+    }
+
+    myAgentTaskExecutor = agentTaskExecutor;
+    myLoggingHandler = loggingHandler;
+
+    myPresentableName = deploymentSource.getPresentableName();
+
+    DC deploymentConfiguration = task.getConfiguration();
+    myApplicationName = deploymentConfiguration.isDefaultDeploymentName()
+                        ? deploymentNameProvider.getDeploymentName(deploymentSource)
+                        : deploymentConfiguration.getDeploymentName();
+
+    myDeployment = agent.createDeployment(getApplicationName(), loggingHandler);
+  }
+
+  public AgentTaskExecutor getAgentTaskExecutor() {
+    return myAgentTaskExecutor;
+  }
+
+  public AD getDeployment() {
+    return myDeployment;
+  }
+
+  public void deploy(ServerRuntimeInstance.DeploymentOperationCallback callback) {
+    try {
+      deploy();
+      callback.succeeded(this);
+    }
+    catch (ServerRuntimeException e) {
+      callback.errorOccurred(e.getMessage());
+    }
+  }
+
+  public void deploy() throws ServerRuntimeException {
+    VirtualFile contentRoot = getContentRoot();
+
+    CloudGitApplication application = findApplication();
+    if (application == null) {
+      application = createApplication();
+    }
+
+    GitRepository repository = findRepository();
+    if (repository == null) {
+      myLoggingHandler.println("Initializing git repository...");
+      GitCommandResult gitInitResult = getGit().init(getProject(), contentRoot, createGitLineHandlerListener());
+      checkGitResult(gitInitResult);
+
+      refreshApplicationRepository();
+
+      repository = getRepository();
+    }
+
+    GitRemote gitRemote = GitUtil.findRemoteByName(repository, getRemoteName());
+    if (gitRemote == null) {
+      addGitRemote(application);
+    }
+    else if (!gitRemote.getUrls().contains(application.getGitUrl())) {
+      resetGitRemote(application);
+    }
+
+    try {
+      GitSimpleHandler handler = new GitSimpleHandler(getProject(), contentRoot, GitCommand.ADD);
+      handler.setSilent(false);
+      handler.addParameters(".");
+      handler.run();
+    }
+    catch (VcsException e) {
+      throw new ServerRuntimeException(e);
+    }
+
+    try {
+      if (GitUtil.hasLocalChanges(true, getProject(), contentRoot)) {
+        GitSimpleHandler handler = new GitSimpleHandler(getProject(), contentRoot, GitCommand.COMMIT);
+        handler.setSilent(false);
+        handler.addParameters("-a");
+        handler.addParameters("-m", "Deploy");
+        handler.endOptions();
+        handler.run();
+      }
+    }
+    catch (VcsException e) {
+      throw new ServerRuntimeException(e);
+    }
+
+    repository.update();
+
+    pushApplication(getRemoteName(), application.getGitUrl());
+  }
+
+  @Override
+  public void undeploy(final @NotNull UndeploymentTaskCallback callback) {
+    myTasksExecutor.submit(new ThrowableRunnable<Exception>() {
+
+      @Override
+      public void run() throws Exception {
+        try {
+          undeploy();
+          callback.succeeded();
+        }
+        catch (ServerRuntimeException e) {
+          callback.errorOccurred(e.getMessage());
+        }
+      }
+    }, callback);
+  }
+
+  public void undeploy() throws ServerRuntimeException {
+    if (!confirmUndeploy()) {
+      throw new ServerRuntimeException("Undeploy cancelled");
+    }
+    myAgentTaskExecutor.execute(new Computable<Object>() {
+
+      @Override
+      public Object compute() {
+        myDeployment.deleteApplication();
+        return null;
+      }
+    });
+  }
+
+  public boolean isDeployed() throws ServerRuntimeException {
+    return findApplication() != null;
+  }
+
+  public void downloadExistingApplication() throws ServerRuntimeException {
+    CloudGitApplication application = findApplication();
+    if (application == null) {
+      throw new ServerRuntimeException("Can't find the application: " + getApplicationName());
+    }
+
+    new CloneJobWithRemote().cloneToModule(application.getGitUrl());
+
+    getRepository().update();
+    refreshContentRoot();
+  }
+
+  protected Project getProject() {
+    return myProject;
+  }
+
+  private String getApplicationName() {
+    return myApplicationName;
+  }
+
+  private Git getGit() {
+    return myGit;
+  }
+
+  protected VirtualFile getContentRoot() {
+    return myContentRoot;
+  }
+
+  private File getContentRootFile() {
+    return myContentRootFile;
+  }
+
+  protected static void checkGitResult(GitCommandResult commandResult) throws ServerRuntimeException {
+    if (!commandResult.success()) {
+      Throwable exception = commandResult.getException();
+      if (exception != null) {
+        LOG.info(exception);
+        throw new ServerRuntimeException(exception);
+      }
+      else {
+        throw new ServerRuntimeException(commandResult.getErrorOutputAsJoinedString());
+      }
+    }
+  }
+
+  protected GitLineHandlerListener createGitLineHandlerListener() {
+    return new GitLineHandlerAdapter() {
+
+      @Override
+      public void onLineAvailable(String line, Key outputType) {
+        myLoggingHandler.println(line);
+      }
+    };
+  }
+
+  protected void addGitRemote(CloudGitApplication application) throws ServerRuntimeException {
+    doGitRemote(getRemoteName(), application, "add", CloudBundle.getText("failed.add.remote", getRemoteName()));
+  }
+
+  protected void resetGitRemote(CloudGitApplication application) throws ServerRuntimeException {
+    doGitRemote(getRemoteName(), application, "set-url", CloudBundle.getText("failed.reset.remote", getRemoteName()));
+  }
+
+  protected void doGitRemote(String remoteName,
+                             CloudGitApplication application,
+                             String subCommand,
+                             String failMessage)
+    throws ServerRuntimeException {
+    try {
+      final GitSimpleHandler handler = new GitSimpleHandler(myProject, myContentRoot, GitCommand.REMOTE);
+      handler.setSilent(false);
+      handler.addParameters(subCommand, remoteName, application.getGitUrl());
+      handler.run();
+      getRepository().update();
+      if (handler.getExitCode() != 0) {
+        throw new ServerRuntimeException(failMessage);
+      }
+    }
+    catch (VcsException e) {
+      throw new ServerRuntimeException(e);
+    }
+  }
+
+  @Nullable
+  protected GitRepository findRepository() {
+    if (myRepository != null) {
+      return myRepository;
+    }
+    myRepository = myGitRepositoryManager.getRepositoryForRoot(myContentRoot);
+    return myRepository;
+  }
+
+  protected void refreshApplicationRepository() {
+    GitInit.refreshAndConfigureVcsMappings(myProject, getContentRoot(), getContentRootFile().getAbsolutePath());
+  }
+
+  protected void pushApplication(String remoteName, String gitUrl) throws ServerRuntimeException {
+    GitCommandResult gitPushResult
+      = getGit().push(getRepository(), remoteName, gitUrl, "master:master", createGitLineHandlerListener());
+    checkGitResult(gitPushResult);
+  }
+
+  @NotNull
+  protected GitRepository getRepository() throws ServerRuntimeException {
+    GitRepository repository = findRepository();
+    if (repository == null) {
+      throw new ServerRuntimeException("Unable to find GIT repository for module root: " + myContentRoot);
+    }
+    return repository;
+  }
+
+  protected void fetch() throws ServerRuntimeException {
+    final VirtualFile contentRoot = getContentRoot();
+    GitRepository repository = getRepository();
+    final GitLineHandler fetchHandler = new GitLineHandler(getProject(), contentRoot, GitCommand.FETCH);
+    fetchHandler.setSilent(false);
+    fetchHandler.addParameters(getRemoteName());
+    fetchHandler.addLineListener(createGitLineHandlerListener());
+    performRemoteGitTask(fetchHandler, CloudBundle.getText("fetching.application", getCloudName()));
+
+    repository.update();
+  }
+
+  protected void performRemoteGitTask(final GitLineHandler handler, String title) throws ServerRuntimeException {
+    final GitTask task = new GitTask(myProject, handler, title);
+    task.setProgressAnalyzer(new GitStandardProgressAnalyzer());
+
+    final Semaphore semaphore = new Semaphore();
+    semaphore.down();
+
+    final Ref<ServerRuntimeException> errorRef = new Ref<ServerRuntimeException>();
+
+    ApplicationManager.getApplication().invokeLater(new Runnable() {
+
+      @Override
+      public void run() {
+        task.execute(false, false, new GitTaskResultHandlerAdapter() {
+
+          @Override
+          protected void run(GitTaskResult result) {
+            super.run(result);
+            semaphore.up();
+          }
+
+          @Override
+          protected void onFailure() {
+            for (VcsException error : handler.errors()) {
+              myLoggingHandler.println(error.toString());
+              if (errorRef.isNull()) {
+                errorRef.set(new ServerRuntimeException(error));
+              }
+            }
+          }
+        });
+      }
+    });
+
+    semaphore.waitFor();
+    if (!errorRef.isNull()) {
+      throw errorRef.get();
+    }
+  }
+
+  protected void refreshContentRoot() {
+    ApplicationManager.getApplication().invokeLater(new Runnable() {
+
+      @Override
+      public void run() {
+        getContentRoot().refresh(false, true);
+      }
+    });
+  }
+
+  protected boolean confirmUndeploy() {
+    final Ref<Boolean> confirmed = new Ref<Boolean>(false);
+    ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+
+      @Override
+      public void run() {
+        String title = CloudBundle.getText("cloud.undeploy.confirm.title");
+        while (true) {
+          String password = Messages.showPasswordDialog(CloudBundle.getText("cloud.undeploy.confirm.message", myPresentableName), title);
+          if (password == null) {
+            return;
+          }
+          if (password.equals(myConfiguration.getPassword())) {
+            confirmed.set(true);
+            return;
+          }
+          Messages.showErrorDialog(CloudBundle.getText("cloud.undeploy.confirm.password.incorrect"), title);
+        }
+      }
+    }, ModalityState.defaultModalityState());
+    return confirmed.get();
+  }
+
+  private String getRemoteName() {
+    return myRemoteName;
+  }
+
+  private String getCloudName() {
+    return myCloudName;
+  }
+
+  protected CloudGitApplication findApplication() throws ServerRuntimeException {
+    return myAgentTaskExecutor.execute(new Computable<CloudGitApplication>() {
+
+      @Override
+      public CloudGitApplication compute() {
+        return myDeployment.findApplication();
+      }
+    });
+  }
+
+  protected CloudGitApplication createApplication() throws ServerRuntimeException {
+    return myAgentTaskExecutor.execute(new Computable<CloudGitApplication>() {
+
+      @Override
+      public CloudGitApplication compute() {
+        return myDeployment.createApplication();
+      }
+    });
+  }
+
+  public class CloneJob {
+
+    public File cloneToTemp(String gitUrl) throws ServerRuntimeException {
+      File cloneDir;
+      try {
+        cloneDir = FileUtil.createTempDirectory("cloud", "clone");
+      }
+      catch (IOException e) {
+        throw new ServerRuntimeException(e);
+      }
+
+      File cloneDirParent = cloneDir.getParentFile();
+      String cloneDirName = cloneDir.getName();
+
+      doClone(cloneDirParent, cloneDirName, gitUrl);
+      return cloneDir;
+    }
+
+    public void cloneToModule(String gitUrl) throws ServerRuntimeException {
+      File cloneDir = cloneToTemp(gitUrl);
+
+      try {
+        FileUtil.copyDir(cloneDir, getContentRootFile());
+      }
+      catch (IOException e) {
+        throw new ServerRuntimeException(e);
+      }
+
+      refreshApplicationRepository();
+    }
+
+    public void doClone(File cloneDirParent, String cloneDirName, String gitUrl) throws ServerRuntimeException {
+      GitCommandResult gitCloneResult
+        = getGit().clone(getProject(), cloneDirParent, gitUrl, cloneDirName, createGitLineHandlerListener());
+      checkGitResult(gitCloneResult);
+    }
+  }
+
+  public class CloneJobWithRemote extends CloneJob {
+
+    public void doClone(File cloneDirParent, String cloneDirName, String gitUrl) throws ServerRuntimeException {
+      final GitLineHandler handler = new GitLineHandler(getProject(), cloneDirParent, GitCommand.CLONE);
+      handler.setSilent(false);
+      handler.setUrl(gitUrl);
+      handler.addParameters("--progress");
+      handler.addParameters(gitUrl);
+      handler.addParameters(cloneDirName);
+      handler.addParameters("-o");
+      handler.addParameters(getRemoteName());
+      handler.addLineListener(createGitLineHandlerListener());
+      performRemoteGitTask(handler, CloudBundle.getText("cloning.existing.application", getCloudName()));
+    }
+  }
+}
diff --git a/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitServerRuntimeInstanceBase.java b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitServerRuntimeInstanceBase.java
new file mode 100644
index 0000000..79c2dfa
--- /dev/null
+++ b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitServerRuntimeInstanceBase.java
@@ -0,0 +1,227 @@
+package com.intellij.remoteServer.util;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.remoteServer.agent.RemoteAgentManager;
+import com.intellij.remoteServer.agent.util.*;
+import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
+import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
+import com.intellij.remoteServer.runtime.ServerConnector;
+import com.intellij.remoteServer.runtime.ServerTaskExecutor;
+import com.intellij.remoteServer.runtime.deployment.DeploymentLogManager;
+import com.intellij.remoteServer.runtime.deployment.DeploymentTask;
+import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance;
+import com.intellij.util.ThrowableRunnable;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * @author michael.golubev
+ */
+
+public abstract class CloudGitServerRuntimeInstanceBase<
+  DC extends CloudDeploymentNameConfiguration,
+  AC extends CloudAgentConfigBase,
+  A extends CloudGitAgent<AC, ?>,
+  SC extends AC,
+  DR extends CloudGitDeploymentRuntime>
+  extends CloudServerRuntimeInstance<DC>
+  implements CloudDeploymentNameProvider {
+
+  private static final Logger LOG = Logger.getInstance("#" + CloudGitServerRuntimeInstanceBase.class.getName());
+
+  private final A myAgent;
+  private final AgentTaskExecutor myAgentTaskExecutor;
+
+  private final SC myConfiguration;
+  private final ServerTaskExecutor myTasksExecutor;
+
+  public CloudGitServerRuntimeInstanceBase(SC configuration,
+                                           ServerTaskExecutor tasksExecutor,
+                                           List<File> libraries,
+                                           List<Class<?>> commonJarClasses,
+                                           String specificsModuleName,
+                                           String specificJarPath,
+                                           Class<A> agentInterface,
+                                           String agentClassName) throws Exception {
+    myConfiguration = configuration;
+    myTasksExecutor = tasksExecutor;
+
+    RemoteAgentManager agentManager = RemoteAgentManager.getInstance();
+    myAgent = agentManager.createAgent(agentManager.createReflectiveThreadProxyFactory(getClass().getClassLoader()),
+                                       libraries,
+                                       commonJarClasses,
+                                       specificsModuleName,
+                                       specificJarPath,
+                                       agentInterface,
+                                       agentClassName,
+                                       getClass());
+    myAgentTaskExecutor = new AgentTaskExecutor();
+  }
+
+  @NotNull
+  @Override
+  public String getDeploymentName(@NotNull DeploymentSource source) {
+    return CloudDeploymentNameProvider.DEFAULT_NAME_PROVIDER.getDeploymentName(source);
+  }
+
+  public void connect(final ServerConnector.ConnectionCallback<DC> callback) {
+    myAgentTaskExecutor.execute(new Computable() {
+
+                                  @Override
+                                  public Object compute() {
+                                    doConnect(myConfiguration,
+                                              new CloudAgentLogger() {
+
+                                                @Override
+                                                public void debugEx(Exception e) {
+                                                  LOG.debug(e);
+                                                }
+
+                                                @Override
+                                                public void debug(String message) {
+                                                  LOG.debug(message);
+                                                }
+                                              });
+                                    return null;
+                                  }
+                                }, new CallbackWrapper() {
+
+                                  @Override
+                                  public void onSuccess(Object result) {
+                                    callback.connected(CloudGitServerRuntimeInstanceBase.this);
+                                  }
+
+                                  @Override
+                                  public void onError(String message) {
+                                    callback.errorOccurred(message);
+                                  }
+                                }
+    );
+  }
+
+  @Override
+  public void deploy(@NotNull final DeploymentTask<DC> task,
+                     @NotNull final DeploymentLogManager logManager,
+                     @NotNull final ServerRuntimeInstance.DeploymentOperationCallback callback) {
+    myTasksExecutor.submit(new ThrowableRunnable<Exception>() {
+
+      @Override
+      public void run() throws Exception {
+        createDeploymentRuntime(myConfiguration, myTasksExecutor, task, createLoggingHandler(logManager)).deploy(callback);
+      }
+    }, callback);
+  }
+
+  @Override
+  public void computeDeployments(@NotNull final ServerRuntimeInstance.ComputeDeploymentsCallback callback) {
+    myTasksExecutor.submit(new ThrowableRunnable<Exception>() {
+      @Override
+      public void run() throws Exception {
+        myAgentTaskExecutor.execute(new Computable<DeploymentData[]>() {
+
+                                      @Override
+                                      public DeploymentData[] compute() {
+                                        return myAgent.getDeployments();
+                                      }
+                                    },
+                                    new CallbackWrapper<DeploymentData[]>() {
+
+                                      @Override
+                                      public void onSuccess(DeploymentData[] deployments) {
+                                        for (DeploymentData deployment : deployments) {
+                                          callback.addDeployment(deployment.getName());
+                                        }
+                                        callback.succeeded();
+                                      }
+
+                                      @Override
+                                      public void onError(String message) {
+                                        callback.errorOccurred(message);
+                                      }
+                                    }
+        );
+      }
+    }, callback);
+  }
+
+  @Override
+  public void disconnect() {
+    myTasksExecutor.submit(new Runnable() {
+
+      @Override
+      public void run() {
+        myAgent.disconnect();
+      }
+    });
+  }
+
+  @Override
+  public ServerTaskExecutor getTaskExecutor() {
+    return myTasksExecutor;
+  }
+
+  protected final A getAgent() {
+    return myAgent;
+  }
+
+  protected final AgentTaskExecutor getAgentTaskExecutor() {
+    return myAgentTaskExecutor;
+  }
+
+  public DR createDeploymentRuntime(final DeployToServerRunConfiguration<?, DC> runConfiguration)
+    throws ServerRuntimeException {
+    return createDeploymentRuntime(myConfiguration,
+                                   myTasksExecutor,
+                                   new DeploymentTask<DC>() {
+
+                                     @NotNull
+                                     @Override
+                                     public DeploymentSource getSource() {
+                                       return runConfiguration.getDeploymentSource();
+                                     }
+
+                                     @NotNull
+                                     @Override
+                                     public DC getConfiguration() {
+                                       return runConfiguration.getDeploymentConfiguration();
+                                     }
+
+                                     @NotNull
+                                     @Override
+                                     public Project getProject() {
+                                       return runConfiguration.getProject();
+                                     }
+
+                                     @Override
+                                     public boolean isDebugMode() {
+                                       return false;
+                                     }
+                                   },
+                                   new CloudGitLoggingHandler() {
+
+                                     @Override
+                                     public void println(String message) {
+                                       LOG.info(message);
+                                     }
+
+                                     @Override
+                                     public void lineLogged(String line, String deploymentName, String kind) {
+
+                                     }
+                                   }
+    );
+  }
+
+  protected abstract DR createDeploymentRuntime(SC configuration,
+                                                ServerTaskExecutor serverTaskExecutor,
+                                                DeploymentTask<DC> deploymentTask,
+                                                CloudGitLoggingHandler loggingHandler) throws ServerRuntimeException;
+
+  protected abstract CloudGitLoggingHandler createLoggingHandler(DeploymentLogManager logManager);
+
+  protected abstract void doConnect(SC configuration, CloudAgentLogger logger);
+}
diff --git a/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudSupportConfigurableBase.java b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudSupportConfigurableBase.java
new file mode 100644
index 0000000..d131adb
--- /dev/null
+++ b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudSupportConfigurableBase.java
@@ -0,0 +1,287 @@
+package com.intellij.remoteServer.util;
+
+import com.intellij.execution.RunManagerEx;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.configurations.ConfigurationType;
+import com.intellij.ide.util.frameworkSupport.FrameworkSupportConfigurable;
+import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationGroup;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModulePointer;
+import com.intellij.openapi.module.ModulePointerManager;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.util.Condition;
+import com.intellij.remoteServer.ServerType;
+import com.intellij.remoteServer.configuration.RemoteServer;
+import com.intellij.remoteServer.configuration.RemoteServersManager;
+import com.intellij.remoteServer.impl.configuration.RemoteServerConfigurable;
+import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerConfigurationType;
+import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
+import com.intellij.remoteServer.impl.configuration.deployment.ModuleDeploymentSourceImpl;
+import com.intellij.remoteServer.runtime.Deployment;
+import com.intellij.remoteServer.runtime.ServerConnection;
+import com.intellij.remoteServer.runtime.ServerConnector;
+import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance;
+import com.intellij.util.concurrency.Semaphore;
+import com.intellij.util.text.UniqueNameGenerator;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Collection;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * @author michael.golubev
+ */
+public abstract class CloudSupportConfigurableBase<
+  SC extends CloudConfigurationBase,
+  DC extends CloudDeploymentNameConfiguration,
+  ST extends ServerType<SC>,
+  SR extends CloudGitServerRuntimeInstanceBase<DC, ?, ?, ?, ?>>
+  extends FrameworkSupportConfigurable {
+
+  private final String myNotificationDisplayId;
+
+  private final FrameworkSupportModel myFrameworkSupportModel;
+  private RemoteServer<SC> myNewServer;
+  private ST myCloudType;
+  private RemoteServerConfigurable myServerConfigurable;
+  private JPanel myServerConfigurablePanel;
+
+  private boolean myInitialized = false;
+
+  public CloudSupportConfigurableBase(FrameworkSupportModel frameworkSupportModel, ST cloudType, String notificationDisplayId) {
+    myFrameworkSupportModel = frameworkSupportModel;
+    myCloudType = cloudType;
+    myNotificationDisplayId = notificationDisplayId;
+  }
+
+  @Override
+  public void dispose() {
+    myServerConfigurable.disposeUIResources();
+  }
+
+  protected void initUI() {
+    JComboBox serverComboBox = getServerComboBox();
+
+    serverComboBox.addActionListener(new ActionListener() {
+
+      @Override
+      public void actionPerformed(ActionEvent e) {
+        onAccountSelectionChanged();
+      }
+    });
+
+    for (RemoteServer<SC> server : RemoteServersManager.getInstance().getServers(myCloudType)) {
+      serverComboBox.addItem(new ServerItem(server));
+    }
+    serverComboBox.addItem(new ServerItem(myNewServer));
+  }
+
+  protected void reloadExistingApplications() {
+    Collection<Deployment> deployments = new ConnectionTask<Collection<Deployment>>("Loading existing applications list", true, true) {
+
+      @Override
+      protected void run(final ServerConnection<DC> connection,
+                         final Semaphore semaphore,
+                         final AtomicReference<Collection<Deployment>> result) {
+        connection.connectIfNeeded(new ServerConnector.ConnectionCallback<DC>() {
+
+          @Override
+          public void connected(@NotNull ServerRuntimeInstance<DC> serverRuntimeInstance) {
+            connection.computeDeployments(new Runnable() {
+
+              @Override
+              public void run() {
+                result.set(connection.getDeployments());
+                semaphore.up();
+              }
+            });
+          }
+
+          @Override
+          public void errorOccurred(@NotNull String errorMessage) {
+            runtimeErrorOccurred(errorMessage);
+            semaphore.up();
+          }
+        });
+      }
+
+      @Override
+      protected Collection<Deployment> run(SR serverRuntimeInstance) throws ServerRuntimeException {
+        return null;
+      }
+    }.perform();
+
+    if (deployments == null) {
+      return;
+    }
+
+    JComboBox existingComboBox = getExistingComboBox();
+    existingComboBox.removeAllItems();
+    for (Deployment deployment : deployments) {
+      existingComboBox.addItem(deployment.getName());
+    }
+  }
+
+  @Override
+  public void onFrameworkSelectionChanged(boolean selected) {
+    if (selected && !myInitialized) {
+      myInitialized = true;
+      initUI();
+      updateApplicationUI();
+    }
+  }
+
+  private ServerItem getSelectedServerItem() {
+    return (ServerItem)getServerComboBox().getSelectedItem();
+  }
+
+  private void onAccountSelectionChanged() {
+    myServerConfigurablePanel.setVisible(getSelectedServerItem().isNew());
+  }
+
+  protected JPanel createServerConfigurablePanel() {
+    myNewServer = RemoteServersManager.getInstance().createServer(myCloudType, generateServerName());
+    myServerConfigurable = new RemoteServerConfigurable(myNewServer, null, true);
+    myServerConfigurablePanel = (JPanel)myServerConfigurable.createComponent();
+    return myServerConfigurablePanel;
+  }
+
+  protected void showMessage(String message, MessageType messageType) {
+    NotificationGroup notificationGroup = NotificationGroup.balloonGroup(myNotificationDisplayId);
+    Notification notification = notificationGroup.createNotification(message, messageType);
+    notification.notify(null);
+  }
+
+  protected void showErrorMessage(String errorMessage) {
+    showMessage(errorMessage, MessageType.ERROR);
+  }
+
+  private String generateServerName() {
+    return UniqueNameGenerator.generateUniqueName(myCloudType.getPresentableName(), new Condition<String>() {
+
+      @Override
+      public boolean value(String s) {
+        for (RemoteServer<?> server : RemoteServersManager.getInstance().getServers()) {
+          if (server.getName().equals(s)) {
+            return false;
+          }
+        }
+        return true;
+      }
+    });
+  }
+
+  protected Project getProject() {
+    return myFrameworkSupportModel.getProject();
+  }
+
+  private DeployToServerConfigurationType getRunConfigurationType() {
+    String id = DeployToServerConfigurationType.getId(myCloudType);
+    for (ConfigurationType configurationType : ConfigurationType.CONFIGURATION_TYPE_EP.getExtensions()) {
+      if (configurationType instanceof DeployToServerConfigurationType) {
+        DeployToServerConfigurationType deployConfigurationType = (DeployToServerConfigurationType)configurationType;
+        if (deployConfigurationType.getId().equals(id)) {
+          return deployConfigurationType;
+        }
+      }
+    }
+    return null;
+  }
+
+  protected RemoteServer<SC> getServer() {
+    ServerItem serverItem = getSelectedServerItem();
+    if (serverItem.isNew()) {
+      try {
+        myServerConfigurable.apply();
+        myNewServer.setName(myServerConfigurable.getDisplayName());
+      }
+      catch (ConfigurationException e) {
+        showErrorMessage(e.getMessage());
+        return null;
+      }
+    }
+    return serverItem.getServer();
+  }
+
+  protected DeployToServerRunConfiguration<SC, DC> createRunConfiguration(String name, Module module, DC deploymentConfiguration) {
+    Project project = getProject();
+
+    RemoteServer<SC> server = getServer();
+
+    if (getSelectedServerItem().isNew()) {
+      RemoteServersManager.getInstance().addServer(server);
+    }
+
+    String serverName = server.getName();
+
+    final RunManagerEx runManager = RunManagerEx.getInstanceEx(project);
+    final RunnerAndConfigurationSettings runSettings
+      = runManager.createRunConfiguration(name, getRunConfigurationType().getConfigurationFactories()[0]);
+
+    final DeployToServerRunConfiguration<SC, DC> result = (DeployToServerRunConfiguration<SC, DC>)runSettings.getConfiguration();
+
+    runManager.addConfiguration(runSettings, false);
+    runManager.setSelectedConfiguration(runSettings);
+
+    result.setServerName(serverName);
+
+    final ModulePointer modulePointer = ModulePointerManager.getInstance(project).create(module);
+    result.setDeploymentSource(new ModuleDeploymentSourceImpl(modulePointer));
+
+    result.setDeploymentConfiguration(deploymentConfiguration);
+
+    return result;
+  }
+
+  protected abstract JComboBox getExistingComboBox();
+
+  protected abstract JComboBox getServerComboBox();
+
+  protected abstract void updateApplicationUI();
+
+  protected class ServerItem {
+
+    private final RemoteServer<SC> myServer;
+
+    public ServerItem(RemoteServer<SC> server) {
+      myServer = server;
+    }
+
+    public boolean isNew() {
+      return myServer == myNewServer;
+    }
+
+    public RemoteServer<SC> getServer() {
+      return myServer;
+    }
+
+    @Override
+    public String toString() {
+      return isNew() ? "New account..." : myServer.getName();
+    }
+  }
+
+  protected abstract class ConnectionTask<T> extends CloudConnectionTask<T, SC, DC, SR> {
+
+    public ConnectionTask(String title, boolean modal, boolean cancellable) {
+      super(title, modal, cancellable);
+    }
+
+    @Override
+    protected RemoteServer<SC> getServer() {
+      return CloudSupportConfigurableBase.this.getServer();
+    }
+
+    @Override
+    protected Project getProject() {
+      return CloudSupportConfigurableBase.this.getProject();
+    }
+  }
+}
diff --git a/plugins/git4idea/src/git4idea/GitCommit.java b/plugins/git4idea/src/git4idea/GitCommit.java
index a4e1fbc..870bc01 100644
--- a/plugins/git4idea/src/git4idea/GitCommit.java
+++ b/plugins/git4idea/src/git4idea/GitCommit.java
@@ -19,6 +19,7 @@
 import com.intellij.openapi.vcs.changes.Change;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.vcs.log.Hash;
+import com.intellij.vcs.log.VcsUser;
 import com.intellij.vcs.log.impl.VcsFullCommitDetailsImpl;
 import git4idea.log.GitContentRevisionFactory;
 import org.jetbrains.annotations.NotNull;
@@ -33,11 +34,9 @@
 public final class GitCommit extends VcsFullCommitDetailsImpl {
 
   public GitCommit(final Project project, @NotNull Hash hash, @NotNull List<Hash> parents, long authorTime, @NotNull VirtualFile root,
-                   @NotNull String subject,
-                   @NotNull String authorName,
-                   @NotNull String authorEmail, @NotNull String message, @NotNull String committerName, @NotNull String committerEmail,
+                   @NotNull String subject, @NotNull VcsUser author, @NotNull String message, @NotNull VcsUser committer,
                    long commitTime, @NotNull List<Change> changes) {
-    super(hash, parents, authorTime, root, subject, authorName, authorEmail, message, committerName, committerEmail, commitTime, changes,
+    super(hash, parents, authorTime, root, subject, author, message, committer, commitTime, changes,
           GitContentRevisionFactory.getInstance(project));
 
   }
diff --git a/plugins/git4idea/src/git4idea/GitUtil.java b/plugins/git4idea/src/git4idea/GitUtil.java
index 42c8f103..b507e4a 100644
--- a/plugins/git4idea/src/git4idea/GitUtil.java
+++ b/plugins/git4idea/src/git4idea/GitUtil.java
@@ -23,6 +23,7 @@
 import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.progress.Task;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
@@ -37,7 +38,10 @@
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.Consumer;
 import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.ui.UIUtil;
+import com.intellij.vcs.log.VcsLog;
+import com.intellij.vcs.log.VcsLogProvider;
 import com.intellij.vcsUtil.VcsFileUtil;
 import com.intellij.vcsUtil.VcsUtil;
 import git4idea.branch.GitBranchUtil;
@@ -951,4 +955,16 @@
                            repositoryManager.getRepositories()));
   }
 
+  /**
+   * Checks if there are Git roots in the VCS log.
+   */
+  public static boolean logHasGitRoot(@NotNull VcsLog log) {
+    return ContainerUtil.find(log.getLogProviders(), new Condition<VcsLogProvider>() {
+      @Override
+      public boolean value(VcsLogProvider logProvider) {
+        return logProvider.getSupportedVcs().equals(GitVcs.getKey());
+      }
+    }) != null;
+  }
+
 }
diff --git a/plugins/git4idea/src/git4idea/actions/GitInit.java b/plugins/git4idea/src/git4idea/actions/GitInit.java
index 04d3ff7..aec2fb6 100644
--- a/plugins/git4idea/src/git4idea/actions/GitInit.java
+++ b/plugins/git4idea/src/git4idea/actions/GitInit.java
@@ -18,7 +18,6 @@
 import com.intellij.notification.NotificationType;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.fileChooser.FileChooser;
 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
@@ -33,6 +32,7 @@
 import com.intellij.openapi.vcs.ProjectLevelVcsManager;
 import com.intellij.openapi.vcs.VcsDirectoryMapping;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Consumer;
 import com.intellij.vcsUtil.VcsFileUtil;
 import git4idea.GitUtil;
 import git4idea.GitVcs;
@@ -51,6 +51,7 @@
  */
 public class GitInit extends DumbAwareAction {
 
+  @Override
   public void actionPerformed(final AnActionEvent e) {
     Project project = e.getData(CommonDataKeys.PROJECT);
     if (project == null) {
@@ -65,40 +66,41 @@
     if (baseDir == null) {
       baseDir = project.getBaseDir();
     }
-    final VirtualFile root = FileChooser.chooseFile(fcd, project, baseDir);
-    if (root == null) {
-      return;
-    }
-    if (GitUtil.isUnderGit(root)) {
-      final int v = Messages.showYesNoDialog(project,
-                                             GitBundle.message("init.warning.already.under.git",
-                                                               StringUtil.escapeXml(root.getPresentableUrl())),
-                                             GitBundle.getString("init.warning.title"),
-                                             Messages.getWarningIcon());
-      if (v != 0) {
-        return;
-      }
-    }
+    doInit(project, fcd, baseDir, baseDir);
+  }
 
-    Git git = ServiceManager.getService(Git.class);
-    GitVcs vcs = GitVcs.getInstance(project);
-    GitCommandResult result = git.init(project, root);
-    if (!result.success()) {
-      if (vcs != null && vcs.getExecutableValidator().checkExecutableAndNotifyIfNeeded()) {
-        GitUIUtil.notify(GitVcs.IMPORTANT_ERROR_NOTIFICATION, project, "Git init failed", result.getErrorOutputAsHtmlString(),
-                         NotificationType.ERROR, null);
-      }
-      return;
-    }
+  private static void doInit(final Project project, FileChooserDescriptor fcd, VirtualFile baseDir, final VirtualFile finalBaseDir) {
+    FileChooser.chooseFile(fcd, project, baseDir, new Consumer<VirtualFile>() {
+      @Override
+      public void consume(final VirtualFile root) {
+        if (GitUtil.isUnderGit(root) && Messages.showYesNoDialog(project,
+                                                                 GitBundle.message("init.warning.already.under.git",
+                                                                                   StringUtil.escapeXml(root.getPresentableUrl())),
+                                                                 GitBundle.getString("init.warning.title"),
+                                                                 Messages.getWarningIcon()) != Messages.YES) {
+          return;
+        }
 
-    if (project.isDefault()) {
-      return;
-    }
-    final String path = root.equals(baseDir) ? "" : root.getPath();
-    final Project finalProject = project;
-    GitVcs.runInBackground(new Task.Backgroundable(finalProject, GitBundle.getString("common.refreshing")) {
-      public void run(@NotNull ProgressIndicator indicator) {
-        refreshAndConfigureVcsMappings(finalProject, root, path);
+        GitCommandResult result = ServiceManager.getService(Git.class).init(project, root);
+        if (!result.success()) {
+          GitVcs vcs = GitVcs.getInstance(project);
+          if (vcs != null && vcs.getExecutableValidator().checkExecutableAndNotifyIfNeeded()) {
+            GitUIUtil.notify(GitVcs.IMPORTANT_ERROR_NOTIFICATION, project, "Git init failed", result.getErrorOutputAsHtmlString(),
+                             NotificationType.ERROR, null);
+          }
+          return;
+        }
+
+        if (project.isDefault()) {
+          return;
+        }
+        final String path = root.equals(finalBaseDir) ? "" : root.getPath();
+        GitVcs.runInBackground(new Task.Backgroundable(project, GitBundle.getString("common.refreshing")) {
+          @Override
+          public void run(@NotNull ProgressIndicator indicator) {
+            refreshAndConfigureVcsMappings(project, root, path);
+          }
+        });
       }
     });
   }
diff --git a/plugins/git4idea/src/git4idea/actions/GitLogSingleCommitAction.java b/plugins/git4idea/src/git4idea/actions/GitLogSingleCommitAction.java
index 364b1f5..0ec2ab6 100644
--- a/plugins/git4idea/src/git4idea/actions/GitLogSingleCommitAction.java
+++ b/plugins/git4idea/src/git4idea/actions/GitLogSingleCommitAction.java
@@ -83,7 +83,7 @@
     }
 
     boolean isValid() {
-      return project != null && log != null;
+      return project != null && log != null && GitUtil.logHasGitRoot(log);
     }
   }
 
diff --git a/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java b/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java
index 84ddd67..f07ef24 100644
--- a/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java
+++ b/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java
@@ -821,7 +821,7 @@
       Object data = list.getData();
       if (data instanceof VcsFullCommitDetails) {
         VcsFullCommitDetails commit = (VcsFullCommitDetails)data;
-        String author = String.format("%s <%s>", commit.getAuthorName(), commit.getAuthorEmail());
+        String author = String.format("%s <%s>", commit.getAuthor().getName(), commit.getAuthor().getEmail());
         myAuthor.getEditor().setItem(author);
         myAuthorDate = new Date(commit.getAuthorTime());
       }
diff --git a/plugins/git4idea/src/git4idea/cherrypick/GitCherryPickAction.java b/plugins/git4idea/src/git4idea/cherrypick/GitCherryPickAction.java
index 705e861..7d24caf 100644
--- a/plugins/git4idea/src/git4idea/cherrypick/GitCherryPickAction.java
+++ b/plugins/git4idea/src/git4idea/cherrypick/GitCherryPickAction.java
@@ -29,6 +29,7 @@
 import com.intellij.vcs.log.*;
 import git4idea.GitLocalBranch;
 import git4idea.GitPlatformFacade;
+import git4idea.GitUtil;
 import git4idea.GitVcs;
 import git4idea.commands.Git;
 import git4idea.config.GitVcsSettings;
@@ -131,7 +132,13 @@
   @Override
   public void update(AnActionEvent e) {
     super.update(e);
-    e.getPresentation().setEnabled(enabled(e));
+    final VcsLog log = getVcsLog(e);
+    if (log != null && !GitUtil.logHasGitRoot(log)) {
+      e.getPresentation().setEnabledAndVisible(false);
+    }
+    else {
+      e.getPresentation().setEnabled(enabled(e));
+    }
   }
 
   private boolean enabled(AnActionEvent e) {
@@ -198,7 +205,7 @@
     return ContainerUtil.map(commits, new Function<GitHeavyCommit, VcsFullCommitDetails>() {
       @Override
       public VcsFullCommitDetails fun(GitHeavyCommit commit) {
-        final VcsLogObjectsFactory factory = ServiceManager.getService(VcsLogObjectsFactory.class);
+        final VcsLogObjectsFactory factory = ServiceManager.getService(project, VcsLogObjectsFactory.class);
         List<Hash> parents = ContainerUtil.map(commit.getParentsHashes(), new Function<String, Hash>() {
           @Override
           public Hash fun(String hashValue) {
diff --git a/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java b/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java
index fb33e93..4c288c5 100644
--- a/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java
+++ b/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java
@@ -113,7 +113,7 @@
       }
       else if (conflictDetector.hasHappened()) {
         boolean mergeCompleted = new CherryPickConflictResolver(myProject, myGit, myPlatformFacade, repository.getRoot(),
-                                                                commit.getHash().asString(), commit.getAuthorName(),
+                                                                commit.getHash().asString(), commit.getAuthor().getName(),
                                                                 commit.getSubject()).merge();
 
         if (mergeCompleted) {
@@ -177,7 +177,7 @@
                                      @NotNull List<GitCommitWrapper> successfulCommits) {
     NotificationListener resolveLinkListener = new ResolveLinkListener(myProject, myGit, myPlatformFacade, repository.getRoot(),
                                                                        commit.getCommit().getHash().toShortString(),
-                                                                       commit.getCommit().getAuthorName(),
+                                                                       commit.getCommit().getAuthor().getName(),
                                                                        commit.getSubject());
     String description = commitDetails(commit)
                          + "<br/>Unresolved conflicts remain in the working tree. <a href='resolve'>Resolve them.<a/>";
diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java
index d51f476..13a8eeb 100644
--- a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java
+++ b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java
@@ -40,12 +40,8 @@
 import com.intellij.util.SmartList;
 import com.intellij.util.concurrency.Semaphore;
 import com.intellij.util.containers.ContainerUtil;
-import com.intellij.vcs.log.Hash;
-import com.intellij.vcs.log.TimedVcsCommit;
-import com.intellij.vcs.log.VcsLogObjectsFactory;
-import com.intellij.vcs.log.VcsShortCommitDetails;
+import com.intellij.vcs.log.*;
 import com.intellij.vcs.log.impl.HashImpl;
-import com.intellij.vcs.log.impl.VcsShortCommitDetailsImpl;
 import git4idea.*;
 import git4idea.branch.GitBranchUtil;
 import git4idea.commands.*;
@@ -483,9 +479,10 @@
     return null;
   }
 
-  public static List<? extends VcsShortCommitDetails> readAllMiniDetails(Project project, final VirtualFile root) throws VcsException {
+  public static List<? extends VcsShortCommitDetails> readAllMiniDetails(final Project project, final VirtualFile root) throws VcsException {
     GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LOG);
-    GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NONE, HASH, PARENTS, AUTHOR_NAME, AUTHOR_TIME, SUBJECT);
+    GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NONE, HASH, PARENTS, AUTHOR_NAME,
+                                           AUTHOR_EMAIL, AUTHOR_TIME, SUBJECT);
     h.setStdoutSuppressed(true);
     h.addParameters(parser.getPretty(), "--encoding=UTF-8");
     h.addParameters("HEAD", "--branches", "--remotes", "--tags");
@@ -503,15 +500,17 @@
         for (String parent : record.getParentsHashes()) {
           parents.add(HashImpl.build(parent));
         }
-        return new VcsShortCommitDetailsImpl(HashImpl.build(record.getHash()), parents, record.getAuthorTimeStamp(), root,
-                                             record.getSubject(), record.getAuthorName());
+
+        return vcsObjectsFactory(project).createShortDetails(HashImpl.build(record.getHash()), parents, record.getAuthorTimeStamp(), root,
+                                             record.getSubject(), record.getAuthorName(), record.getAuthorEmail());
       }
     });
   }
 
-  public static List<? extends VcsShortCommitDetails> readMiniDetails(Project project, final VirtualFile root, List<String> hashes) throws VcsException {
+  public static List<? extends VcsShortCommitDetails> readMiniDetails(final Project project, final VirtualFile root, List<String> hashes) throws VcsException {
     GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LOG);
-    GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NONE, HASH, PARENTS, AUTHOR_NAME, AUTHOR_TIME, SUBJECT);
+    GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NONE, HASH, PARENTS, AUTHOR_NAME,
+                                           AUTHOR_EMAIL, AUTHOR_TIME, SUBJECT);
     h.setStdoutSuppressed(true);
     // git show can show either -p, or --name-status, or --name-only, but we need nothing, just details => using git log --no-walk
     h.addParameters("--no-walk");
@@ -528,18 +527,21 @@
         for (String parent : record.getParentsHashes()) {
           parents.add(HashImpl.build(parent));
         }
-        return new VcsShortCommitDetailsImpl(HashImpl.build(record.getHash()), parents, record.getAuthorTimeStamp(), root,
-                                             record.getSubject(), record.getAuthorName());
+        return vcsObjectsFactory(project).createShortDetails(HashImpl.build(record.getHash()), parents, record.getAuthorTimeStamp(), root,
+                                             record.getSubject(), record.getAuthorName(), record.getAuthorEmail());
       }
     });
   }
 
   @NotNull
-  public static List<TimedVcsCommit> readAllHashes(@NotNull Project project, @NotNull VirtualFile root) throws VcsException {
+  public static List<TimedVcsCommit> readAllHashes(@NotNull final Project project,
+                                                   @NotNull VirtualFile root,
+                                                   @NotNull final Consumer<VcsUser> userRegistry) throws VcsException {
     final int COMMIT_BUFFER = 1000;
 
     GitLineHandler h = new GitLineHandler(project, root, GitCommand.LOG);
-    final GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NONE, HASH, PARENTS, AUTHOR_TIME);
+    final GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NONE, HASH, PARENTS, AUTHOR_TIME,
+                                                 AUTHOR_NAME, AUTHOR_EMAIL);
     h.setStdoutSuppressed(true);
     h.addParameters(parser.getPretty(), "--encoding=UTF-8");
     h.addParameters("HEAD", "--branches", "--remotes", "--tags");
@@ -571,7 +573,7 @@
             afterParseRemainder = line.substring(recordEnd + 1);
           }
           if (afterParseRemainder != null && records.incrementAndGet() > COMMIT_BUFFER) { // null means can't parse now
-            commits.addAll(parseCommit(parser, record));
+            commits.addAll(parseCommit(project, parser, record, userRegistry));
             record.setLength(0);
             record.append(afterParseRemainder);
           }
@@ -584,7 +586,7 @@
       @Override
       public void processTerminated(int exitCode) {
         try {
-          commits.addAll(parseCommit(parser, record));
+          commits.addAll(parseCommit(project, parser, record, userRegistry));
         }
         catch (Exception e) {
           ex.set(new VcsException(e));
@@ -603,19 +605,25 @@
     return commits;
   }
 
-  private static List<TimedVcsCommit> parseCommit(GitLogParser parser, StringBuilder record) {
+  private static List<TimedVcsCommit> parseCommit(final Project project, GitLogParser parser, StringBuilder record,
+                                                  final Consumer<VcsUser> userRegistry) {
     List<GitLogRecord> rec = parser.parse(record.toString());
     return ContainerUtil.mapNotNull(rec, new Function<GitLogRecord, TimedVcsCommit>() {
       @Override
       public TimedVcsCommit fun(GitLogRecord record) {
-        return record == null ? null : convert(record);
+        if (record == null) {
+          return null;
+        }
+        TimedVcsCommit commit = convert(project, record);
+        userRegistry.consume(vcsObjectsFactory(project).createUser(record.getAuthorName(), record.getAuthorEmail()));
+        return commit;
       }
     });
   }
 
   @NotNull
-  private static TimedVcsCommit convert(GitLogRecord rec) {
-    VcsLogObjectsFactory factory = ServiceManager.getService(VcsLogObjectsFactory.class);
+  private static TimedVcsCommit convert(Project project, GitLogRecord rec) {
+    VcsLogObjectsFactory factory = vcsObjectsFactory(project);
     List<Hash> parents = ContainerUtil.map(rec.getParentsHashes(), new Function<String, Hash>() {
       @Override
       public Hash fun(String s) {
@@ -625,6 +633,11 @@
     return factory.createTimedCommit(HashImpl.build(rec.getHash()), parents, rec.getAuthorTimeStamp());
   }
 
+  @NotNull
+  private static VcsLogObjectsFactory vcsObjectsFactory(@NotNull Project project) {
+    return ServiceManager.getService(project, VcsLogObjectsFactory.class);
+  }
+
   private static class MyTokenAccumulator {
     private final StringBuilder myBuffer = new StringBuilder();
 
@@ -775,9 +788,10 @@
         return HashImpl.build(hash);
       }
     });
+    VcsLogObjectsFactory factory = vcsObjectsFactory(project);
     return new GitCommit(project, HashImpl.build(record.getHash()), parents, record.getAuthorTimeStamp(), root, record.getSubject(),
-                         record.getAuthorName(), record.getAuthorEmail(), record.getFullMessage(), record.getCommitterName(),
-                         record.getCommitterEmail(), record.getLongTimeStamp(),
+                         factory.createUser(record.getAuthorName(), record.getAuthorEmail()), record.getFullMessage(),
+                         factory.createUser(record.getCommitterName(), record.getCommitterEmail()), record.getLongTimeStamp(),
                          record.parseChanges(project, root));
   }
 
diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/StructureFilterAction.java b/plugins/git4idea/src/git4idea/history/wholeTree/StructureFilterAction.java
index 573c5f5..b898520 100644
--- a/plugins/git4idea/src/git4idea/history/wholeTree/StructureFilterAction.java
+++ b/plugins/git4idea/src/git4idea/history/wholeTree/StructureFilterAction.java
@@ -23,7 +23,7 @@
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.Consumer;
-import git4idea.GitVcs;
+import com.intellij.vcs.log.ui.VcsStructureChooser;
 
 import java.util.Collection;
 import java.util.Map;
@@ -56,7 +56,7 @@
       @Override
       public void actionPerformed(AnActionEvent e) {
         final VcsStructureChooser vcsStructureChooser =
-          new VcsStructureChooser(GitVcs.getInstance(myProject), "Select folders to filter by", structureFilterI.getSelected(),
+          new VcsStructureChooser(myProject, "Select folders to filter by", structureFilterI.getSelected(),
                                   structureFilterI.getRoots());
         vcsStructureChooser.show();
         if (vcsStructureChooser.getExitCode() == DialogWrapper.CANCEL_EXIT_CODE) return;
@@ -117,7 +117,7 @@
       myPanel.setToolTipText(STRUCTURE + " " + ALL);
     } else {
       final VcsStructureChooser vcsStructureChooser =
-        new VcsStructureChooser(GitVcs.getInstance(myProject), "Select folders to filter by", myStructureFilterI.getSelected(),
+        new VcsStructureChooser(myProject, "Select folders to filter by", myStructureFilterI.getSelected(),
                                 myStructureFilterI.getRoots());
       final Map<VirtualFile,String> modulesSet = vcsStructureChooser.getModulesSet();
       final String text = getText(selected, modulesSet);
diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/VcsStructureChooser.java b/plugins/git4idea/src/git4idea/history/wholeTree/VcsStructureChooser.java
deleted file mode 100644
index ec0ae8e..0000000
--- a/plugins/git4idea/src/git4idea/history/wholeTree/VcsStructureChooser.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * 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.
- */
-package git4idea.history.wholeTree;
-
-import com.intellij.ide.util.treeView.AbstractTreeUi;
-import com.intellij.ide.util.treeView.NodeDescriptor;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diff.impl.patch.formove.FilePathComparator;
-import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
-import com.intellij.openapi.fileChooser.ex.FileNodeDescriptor;
-import com.intellij.openapi.fileChooser.ex.FileSystemTreeImpl;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ModuleRootManager;
-import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.ui.Splitter;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.vcs.AbstractVcs;
-import com.intellij.openapi.vcs.FilePath;
-import com.intellij.openapi.vcs.changes.ui.VirtualFileListCellRenderer;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.*;
-import com.intellij.ui.components.JBList;
-import com.intellij.ui.components.JBScrollPane;
-import com.intellij.ui.treeStructure.Tree;
-import com.intellij.util.PlatformIcons;
-import com.intellij.util.PlusMinus;
-import com.intellij.util.TreeNodeState;
-import com.intellij.util.containers.Convertor;
-import com.intellij.util.containers.hash.HashSet;
-import com.intellij.util.treeWithCheckedNodes.SelectionManager;
-import com.intellij.util.ui.UIUtil;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import javax.swing.border.Border;
-import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.TreeCellRenderer;
-import javax.swing.tree.TreePath;
-import java.awt.*;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.util.*;
-import java.util.List;
-
-/**
- * @author irengrig
- *         Date: 2/3/11
- *         Time: 12:04 PM
- */
-public class VcsStructureChooser extends DialogWrapper {
-  private final static int MAX_FOLDERS = 10;
-  public static final Border BORDER = IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.LEFT);
-  public static final String DEFAULT_TEXT = "<html>Selected:</html>";
-  public static final String CAN_NOT_ADD_TEXT = "<html>Selected: <font color=red>(You have added " + MAX_FOLDERS + " elements. No more is allowed.)</font></html>";
-  private final AbstractVcs myVcs;
-  private Set<VirtualFile> myRoots;
-  private Map<VirtualFile, String> myModulesSet;
-  private SelectionManager mySelectionManager;
-  private DefaultMutableTreeNode myRoot;
-  private JBList mySelectedList;
-  private JLabel mySelectedLabel;
-  private Tree myTree;
-  private final List<VirtualFile> myInitialRoots;
-
-  public VcsStructureChooser(final AbstractVcs vcs,
-                             final String title,
-                             final Collection<VirtualFile> initialSelection,
-                             List<VirtualFile> initialRoots) {
-    super(vcs.getProject(), true);
-    myInitialRoots = initialRoots;
-    setTitle(title);
-    myVcs = vcs;
-    mySelectionManager = new SelectionManager(MAX_FOLDERS, 500, MyNodeConvertor.getInstance());
-    init();
-    mySelectionManager.setSelection(initialSelection);
-    checkEmptyness();
-  }
-
-  private void calculateRoots() {
-    final ModuleManager moduleManager = ModuleManager.getInstance(myVcs.getProject());
-    // assertion for read access inside
-    final Module[] modules = ApplicationManager.getApplication().runReadAction(new Computable<Module[]>() {
-      public Module[] compute() {
-        return moduleManager.getModules();
-      }
-    });
-
-    final TreeSet<VirtualFile> checkSet = new TreeSet<VirtualFile>(FilePathComparator.getInstance());
-    myRoots = new HashSet<VirtualFile>();
-    myRoots.addAll(myInitialRoots);
-    checkSet.addAll(myInitialRoots);
-    myModulesSet = new HashMap<VirtualFile, String>();
-    for (Module module : modules) {
-      final VirtualFile[] files = ModuleRootManager.getInstance(module).getContentRoots();
-      for (VirtualFile file : files) {
-        final VirtualFile floor = checkSet.floor(file);
-        if (floor != null) {
-          myModulesSet.put(file, module.getName());
-          myRoots.add(file);
-        }
-      }
-    }
-  }
-
-  public Map<VirtualFile, String> getModulesSet() {
-    return myModulesSet;
-  }
-
-  public Collection<VirtualFile> getSelectedFiles() {
-    return ((CollectionListModel) mySelectedList.getModel()).getItems();
-  }
-
-  private void checkEmptyness() {
-    setOKActionEnabled(mySelectedList.getModel().getSize() > 0);
-  }
-
-  @Override
-  protected String getDimensionServiceKey() {
-    return "git4idea.history.wholeTree.VcsStructureChooser";
-  }
-
-  @Override
-  public JComponent getPreferredFocusedComponent() {
-    return myTree;
-  }
-
-  @Override
-  protected JComponent createCenterPanel() {
-    final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createAllButJarContentsDescriptor();
-    calculateRoots();
-    final ArrayList<VirtualFile> list = new ArrayList<VirtualFile>(myRoots);
-    final Comparator<VirtualFile> comparator = new Comparator<VirtualFile>() {
-      @Override
-      public int compare(VirtualFile o1, VirtualFile o2) {
-        final boolean isDir1 = o1.isDirectory();
-        final boolean isDir2 = o2.isDirectory();
-        if (isDir1 != isDir2) return isDir1 ? -1 : 1;
-
-        final String module1 = myModulesSet.get(o1);
-        final String path1 = module1 != null ? module1 : o1.getPath();
-        final String module2 = myModulesSet.get(o2);
-        final String path2 = module2 != null ? module2 : o2.getPath();
-        return path1.compareToIgnoreCase(path2);
-      }
-    };
-    descriptor.setRoots(list);
-    myTree = new Tree();
-    myTree.setMinimumSize(new Dimension(200, 200));
-    myTree.setBorder(BORDER);
-    myTree.setShowsRootHandles(true);
-    myTree.setRootVisible(true);
-    myTree.getExpandableItemsHandler().setEnabled(false);
-    final MyCheckboxTreeCellRenderer cellRenderer = new MyCheckboxTreeCellRenderer(mySelectionManager, myModulesSet, myVcs.getProject(),
-                                                                                   myTree, myRoots);
-    final FileSystemTreeImpl fileSystemTree = new FileSystemTreeImpl(myVcs.getProject(), descriptor, myTree, cellRenderer, null, new Convertor<TreePath, String>() {
-      @Override
-      public String convert(TreePath o) {
-        final DefaultMutableTreeNode lastPathComponent = ((DefaultMutableTreeNode) o.getLastPathComponent());
-        final Object uo = lastPathComponent.getUserObject();
-        if (uo instanceof FileNodeDescriptor) {
-          final VirtualFile file = ((FileNodeDescriptor)uo).getElement().getFile();
-          final String module = myModulesSet.get(file);
-          if (module != null) return module;
-          return file == null ? "" : file.getName();
-        }
-        return o.toString();
-      }
-    });
-    final AbstractTreeUi ui = fileSystemTree.getTreeBuilder().getUi();
-    ui.setNodeDescriptorComparator(new Comparator<NodeDescriptor>() {
-      @Override
-      public int compare(NodeDescriptor o1, NodeDescriptor o2) {
-        if (o1 instanceof FileNodeDescriptor && o2 instanceof FileNodeDescriptor) {
-          final VirtualFile f1 = ((FileNodeDescriptor)o1).getElement().getFile();
-          final VirtualFile f2 = ((FileNodeDescriptor)o2).getElement().getFile();
-          return comparator.compare(f1, f2);
-        }
-        return o1.getIndex() - o2.getIndex();
-      }
-    });
-    myRoot = (DefaultMutableTreeNode)myTree.getModel().getRoot();
-
-    new ClickListener() {
-      @Override
-      public boolean onClick(MouseEvent e, int clickCount) {
-        int row = myTree.getRowForLocation(e.getX(), e.getY());
-        if (row < 0) return false;
-        final Object o = myTree.getPathForRow(row).getLastPathComponent();
-        if (myRoot == o || getFile(o) == null) return false;
-
-        Rectangle rowBounds = myTree.getRowBounds(row);
-        cellRenderer.setBounds(rowBounds);
-        Rectangle checkBounds = cellRenderer.myCheckbox.getBounds();
-        checkBounds.setLocation(rowBounds.getLocation());
-
-        if (checkBounds.height == 0) checkBounds.height = rowBounds.height;
-
-        if (checkBounds.contains(e.getPoint())) {
-          mySelectionManager.toggleSelection((DefaultMutableTreeNode)o);
-          myTree.revalidate();
-          myTree.repaint();
-        }
-        return true;
-      }
-    }.installOn(myTree);
-
-    myTree.addKeyListener(new KeyAdapter() {
-      public void keyPressed(KeyEvent e) {
-        if (e.getKeyCode() == KeyEvent.VK_SPACE) {
-          TreePath treePath = myTree.getLeadSelectionPath();
-          if (treePath == null) return;
-          final Object o = treePath.getLastPathComponent();
-          if (myRoot == o || getFile(o) == null) return;
-           mySelectionManager.toggleSelection((DefaultMutableTreeNode)o);
-          myTree.revalidate();
-          myTree.repaint();
-          e.consume();
-        }
-      }
-    });
-
-    final Splitter splitter = new Splitter(true, 0.7f);
-    splitter.setFirstComponent(new JBScrollPane(fileSystemTree.getTree()));
-    final JPanel wrapper = new JPanel(new BorderLayout());
-    mySelectedLabel = new JLabel(DEFAULT_TEXT);
-    mySelectedLabel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0));
-    wrapper.add(mySelectedLabel, BorderLayout.NORTH);
-    mySelectedList = new JBList(new CollectionListModel(new ArrayList<VirtualFile>()));
-    mySelectedList.setCellRenderer(new WithModulesListCellRenderer(myVcs.getProject(), myModulesSet));
-    wrapper.add(ScrollPaneFactory.createScrollPane(mySelectedList), BorderLayout.CENTER);
-    splitter.setSecondComponent(wrapper);
-
-    mySelectionManager.setSelectionChangeListener(new PlusMinus<VirtualFile>() {
-      @Override
-      public void plus(VirtualFile virtualFile) {
-        final CollectionListModel model = (CollectionListModel)mySelectedList.getModel();
-        model.add(virtualFile);
-        model.sort(FilePathComparator.getInstance());
-        recalculateErrorText();
-        mySelectedList.revalidate();
-        mySelectedList.repaint();
-      }
-
-      private void recalculateErrorText() {
-        checkEmptyness();
-        if (mySelectionManager.canAddSelection()) {
-          mySelectedLabel.setText(DEFAULT_TEXT);
-        } else {
-          mySelectedLabel.setText(CAN_NOT_ADD_TEXT);
-        }
-        mySelectedLabel.revalidate();
-      }
-
-      @Override
-      public void minus(VirtualFile virtualFile) {
-        final CollectionListModel defaultListModel = (CollectionListModel)mySelectedList.getModel();
-        for (int i = 0; i < defaultListModel.getSize(); i++) {
-          final VirtualFile elementAt = (VirtualFile)defaultListModel.getElementAt(i);
-          if (virtualFile.equals(elementAt)) {
-            defaultListModel.remove(i);
-            break;
-          }
-        }
-        defaultListModel.sort(FilePathComparator.getInstance());
-        recalculateErrorText();
-        mySelectedList.revalidate();
-        mySelectedList.repaint();
-      }
-    });
-    mySelectedList.addKeyListener(new KeyAdapter() {
-      @Override
-      public void keyReleased(KeyEvent e) {
-        if (e.getModifiers() == 0 && e.getKeyCode() == KeyEvent.VK_DELETE) {
-          final int[] idx = mySelectedList.getSelectedIndices();
-          if (idx != null && idx.length > 0) {
-            final int answer = Messages
-              .showYesNoDialog(myVcs.getProject(), "Remove selected paths from filter?", "Remove from filter", Messages.getQuestionIcon());
-            if (Messages.OK == answer) {
-              Arrays.sort(idx);
-              for (int i = idx.length - 1; i >= 0; --i) {
-                int i1 = idx[i];
-                mySelectionManager.removeSelection((VirtualFile)((CollectionListModel) mySelectedList.getModel()).getElementAt(i1));
-                myTree.revalidate();
-                myTree.repaint();
-              }
-            }
-          }
-        }
-      }
-    });
-
-    return splitter;
-  }
-
-  @Nullable
-  private static VirtualFile getFile(final Object node) {
-    if (! (((DefaultMutableTreeNode)node).getUserObject() instanceof FileNodeDescriptor)) return null;
-    final FileNodeDescriptor descriptor = (FileNodeDescriptor)((DefaultMutableTreeNode)node).getUserObject();
-    if (descriptor.getElement().getFile() == null) return null;
-    return descriptor.getElement().getFile();
-  }
-
-  private static class MyCheckboxTreeCellRenderer extends JPanel implements TreeCellRenderer {
-    private final WithModulesListCellRenderer myTextRenderer;
-    public final JCheckBox myCheckbox;
-    private final SelectionManager mySelectionManager;
-    private final Map<VirtualFile, String> myModulesSet;
-    private final Collection<VirtualFile> myRoots;
-    private final ColoredTreeCellRenderer myColoredRenderer;
-    private final JLabel myEmpty;
-    private final JList myFictive;
-
-    private MyCheckboxTreeCellRenderer(final SelectionManager selectionManager, Map<VirtualFile, String> modulesSet, final Project project,
-                                       final JTree tree, final Collection<VirtualFile> roots) {
-      super(new BorderLayout());
-      mySelectionManager = selectionManager;
-      myModulesSet = modulesSet;
-      myRoots = roots;
-      setBackground(tree.getBackground());
-      myColoredRenderer = new ColoredTreeCellRenderer() {
-        @Override
-        public void customizeCellRenderer(JTree tree,
-                                          Object value,
-                                          boolean selected,
-                                          boolean expanded,
-                                          boolean leaf,
-                                          int row,
-                                          boolean hasFocus) {
-          append(value.toString());
-        }
-      };
-      myFictive = new JBList();
-      myFictive.setBackground(tree.getBackground());
-      myFictive.setSelectionBackground(UIUtil.getListSelectionBackground());
-      myFictive.setSelectionForeground(UIUtil.getListSelectionForeground());
-
-      myTextRenderer = new WithModulesListCellRenderer(project, myModulesSet) {
-        @Override
-        protected void putParentPath(Object value, FilePath path, FilePath self) {
-          if (myRoots.contains(self.getVirtualFile())) {
-            super.putParentPath(value, path, self);
-          }
-        }
-      };
-      myTextRenderer.setBackground(tree.getBackground());
-
-      myCheckbox = new JCheckBox();
-      myCheckbox.setBackground(tree.getBackground());
-      myEmpty = new JLabel("");
-
-      add(myCheckbox, BorderLayout.WEST);
-      add(myTextRenderer, BorderLayout.CENTER);
-      myCheckbox.setVisible(true);
-    }
-
-    @Override
-    public Component getTreeCellRendererComponent(JTree tree,
-                                                  Object value,
-                                                  boolean selected,
-                                                  boolean expanded,
-                                                  boolean leaf,
-                                                  int row,
-                                                  boolean hasFocus) {
-      invalidate();
-      final VirtualFile file = getFile(value);
-      final DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
-      if (file == null) {
-        if (value instanceof DefaultMutableTreeNode) {
-          final Object uo = node.getUserObject();
-          if (uo instanceof String) {
-            myColoredRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
-            return myColoredRenderer;
-          }
-        }
-        return myEmpty;
-      }
-      myCheckbox.setVisible(true);
-      final TreeNodeState state = mySelectionManager.getState(node);
-      myCheckbox.setEnabled(TreeNodeState.CLEAR.equals(state) || TreeNodeState.SELECTED.equals(state));
-      myCheckbox.setSelected(!TreeNodeState.CLEAR.equals(state));
-      myTextRenderer.getListCellRendererComponent(myFictive, file, 0, selected, hasFocus);
-      revalidate();
-      return this;
-    }
-  }
-
-  private static class MyNodeConvertor implements Convertor<DefaultMutableTreeNode, VirtualFile> {
-    private final static MyNodeConvertor ourInstance = new MyNodeConvertor();
-
-    public static MyNodeConvertor getInstance() {
-      return ourInstance;
-    }
-
-    @Override
-    public VirtualFile convert(DefaultMutableTreeNode o) {
-      return ((FileNodeDescriptor)o.getUserObject()).getElement().getFile();
-    }
-  }
-
-  private static class WithModulesListCellRenderer extends VirtualFileListCellRenderer {
-    private final Map<VirtualFile, String> myModules;
-
-    private WithModulesListCellRenderer(Project project, final Map<VirtualFile, String> modules) {
-      super(project, true);
-      myModules = modules;
-    }
-
-    @Override
-    protected String getName(FilePath path) {
-      final String module = myModules.get(path.getVirtualFile());
-      if (module != null) {
-        return module;
-      }
-      return super.getName(path);
-    }
-
-    @Override
-    protected void renderIcon(FilePath path) {
-      final String module = myModules.get(path.getVirtualFile());
-      if (module != null) {
-        setIcon(PlatformIcons.CONTENT_ROOT_ICON_CLOSED);
-      } else {
-        if (path.isDirectory()) {
-          setIcon(PlatformIcons.DIRECTORY_CLOSED_ICON);
-        } else {
-          setIcon(path.getFileType().getIcon());
-        }
-      }
-    }
-
-    @Override
-    protected void putParentPathImpl(Object value, String parentPath, FilePath self) {
-      append(self.getPath(), SimpleTextAttributes.GRAYED_ATTRIBUTES);
-    }
-  }
-}
diff --git a/plugins/git4idea/src/git4idea/log/GitLogProvider.java b/plugins/git4idea/src/git4idea/log/GitLogProvider.java
index 1f3e723..c259035 100644
--- a/plugins/git4idea/src/git4idea/log/GitLogProvider.java
+++ b/plugins/git4idea/src/git4idea/log/GitLogProvider.java
@@ -23,13 +23,15 @@
 import com.intellij.openapi.vcs.VcsKey;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.ArrayUtil;
+import com.intellij.util.Consumer;
 import com.intellij.util.Function;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.vcs.log.*;
 import com.intellij.vcs.log.data.VcsLogBranchFilter;
+import com.intellij.vcs.log.data.VcsLogDateFilter;
+import com.intellij.vcs.log.data.VcsLogStructureFilter;
 import com.intellij.vcs.log.data.VcsLogUserFilter;
 import com.intellij.vcs.log.impl.HashImpl;
-import com.intellij.vcs.log.impl.VcsRefImpl;
 import com.intellij.vcs.log.ui.filter.VcsLogTextFilter;
 import git4idea.GitLocalBranch;
 import git4idea.GitRemoteBranch;
@@ -66,7 +68,7 @@
     myProject = project;
     myRepositoryManager = repositoryManager;
     myRefSorter = new GitRefManager(myRepositoryManager);
-    myVcsObjectsFactory = ServiceManager.getService(VcsLogObjectsFactory.class);
+    myVcsObjectsFactory = ServiceManager.getService(myProject, VcsLogObjectsFactory.class);
   }
 
   @NotNull
@@ -83,8 +85,8 @@
 
   @NotNull
   @Override
-  public List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root) throws VcsException {
-    return GitHistoryUtils.readAllHashes(myProject, root);
+  public List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException {
+    return GitHistoryUtils.readAllHashes(myProject, root, userRegistry);
   }
 
   @NotNull
@@ -114,15 +116,15 @@
     Collection<GitRemoteBranch> remoteBranches = repository.getBranches().getRemoteBranches();
     Collection<VcsRef> refs = new ArrayList<VcsRef>(localBranches.size() + remoteBranches.size());
     for (GitLocalBranch localBranch : localBranches) {
-      refs.add(new VcsRefImpl(HashImpl.build(localBranch.getHash()), localBranch.getName(), GitRefManager.LOCAL_BRANCH, root));
+      refs.add(myVcsObjectsFactory.createRef(HashImpl.build(localBranch.getHash()), localBranch.getName(), GitRefManager.LOCAL_BRANCH, root));
     }
     for (GitRemoteBranch remoteBranch : remoteBranches) {
-      refs.add(new VcsRefImpl(HashImpl.build(remoteBranch.getHash()), remoteBranch.getNameForLocalOperations(),
+      refs.add(myVcsObjectsFactory.createRef(HashImpl.build(remoteBranch.getHash()), remoteBranch.getNameForLocalOperations(),
                           GitRefManager.REMOTE_BRANCH, root));
     }
     String currentRevision = repository.getCurrentRevision();
     if (currentRevision != null) { // null => fresh repository
-      refs.add(new VcsRefImpl(HashImpl.build(currentRevision), "HEAD", GitRefManager.HEAD, root));
+      refs.add(myVcsObjectsFactory.createRef(HashImpl.build(currentRevision), "HEAD", GitRefManager.HEAD, root));
     }
 
     refs.addAll(readTags(root));
@@ -138,7 +140,7 @@
     Collection<VcsRef> refs = new ArrayList<VcsRef>();
     for (String record : out.split(GitLogParser.RECORD_START)) {
       if (!StringUtil.isEmptyOrSpaces(record)) {
-        refs.addAll(RefParser.parseCommitRefs(record.trim(), root));
+        refs.addAll(new RefParser(myVcsObjectsFactory).parseCommitRefs(record.trim(), root));
       }
     }
     return refs;
@@ -200,6 +202,18 @@
       filterParameters.add(prepareParameter("author", authorFilter));
     }
 
+    List<VcsLogDateFilter> dateFilters = ContainerUtil.findAll(filters, VcsLogDateFilter.class);
+    if (!dateFilters.isEmpty()) {
+      // assuming there is only one date filter, until filter expressions are defined
+      VcsLogDateFilter filter = dateFilters.iterator().next();
+      if (filter.getAfter() != null) {
+        filterParameters.add("--after=" + filter.getAfter().toString());
+      }
+      if (filter.getBefore() != null) {
+        filterParameters.add("--before=" + filter.getBefore().toString());
+      }
+    }
+
     List<VcsLogTextFilter> textFilters = ContainerUtil.findAll(filters, VcsLogTextFilter.class);
     if (textFilters.size() > 1) {
       LOG.warn("Expected only one text filter: " + textFilters);
@@ -209,7 +223,19 @@
       filterParameters.add(prepareParameter("grep", textFilter));
     }
 
-    filterParameters.add("--regexp-ignore-case"); // affects case sensitivity of any filter
+    filterParameters.add("--regexp-ignore-case"); // affects case sensitivity of any filter (except file filter)
+
+    // note: this filter must be the last parameter, because it uses "--" which separates parameters from paths
+    List<VcsLogStructureFilter> structureFilters = ContainerUtil.findAll(filters, VcsLogStructureFilter.class);
+    if (!structureFilters.isEmpty()) {
+      filterParameters.add("--");
+      for (VcsLogStructureFilter filter : structureFilters) {
+        for (VirtualFile file : filter.getFiles(root)) {
+          filterParameters.add(file.getPath());
+        }
+      }
+    }
+
     return GitHistoryUtils.getAllDetails(myProject, root, filterParameters);
   }
 
@@ -217,7 +243,8 @@
   @Override
   public VcsUser getCurrentUser(@NotNull VirtualFile root) throws VcsException {
     String userName = GitConfigUtil.getValue(myProject, root, GitConfigUtil.USER_NAME);
-    return userName == null ? null : myVcsObjectsFactory.createUser(userName);
+    String userEmail = StringUtil.notNullize(GitConfigUtil.getValue(myProject, root, GitConfigUtil.USER_EMAIL));
+    return userName == null ? null : myVcsObjectsFactory.createUser(userName, userEmail);
   }
 
   private static String prepareParameter(String paramName, String value) {
diff --git a/plugins/git4idea/src/git4idea/log/RefParser.java b/plugins/git4idea/src/git4idea/log/RefParser.java
index 018dab3..dfef6f3 100644
--- a/plugins/git4idea/src/git4idea/log/RefParser.java
+++ b/plugins/git4idea/src/git4idea/log/RefParser.java
@@ -2,8 +2,8 @@
 
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.vcs.log.Hash;
+import com.intellij.vcs.log.VcsLogObjectsFactory;
 import com.intellij.vcs.log.VcsRef;
-import com.intellij.vcs.log.impl.VcsRefImpl;
 import com.intellij.vcs.log.impl.HashImpl;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -19,8 +19,14 @@
  */
 class RefParser {
 
+  private final VcsLogObjectsFactory myFactory;
+
+  public RefParser(VcsLogObjectsFactory factory) {
+    myFactory = factory;
+  }
+
   // e25b7d8f (HEAD, refs/remotes/origin/master, refs/remotes/origin/HEAD, refs/heads/master)
-  public static List<VcsRef> parseCommitRefs(@NotNull String input, @NotNull VirtualFile root) {
+  public List<VcsRef> parseCommitRefs(@NotNull String input, @NotNull VirtualFile root) {
     int firstSpaceIndex = input.indexOf(' ');
     String strHash = input.substring(0, firstSpaceIndex);
     Hash hash = HashImpl.build(strHash);
@@ -52,10 +58,10 @@
 
   // example input: fb29c80 refs/tags/92.29
   @Nullable
-  private static VcsRef createRef(@NotNull Hash hash, @NotNull String longRefPath, @NotNull VirtualFile root) {
+  private VcsRef createRef(@NotNull Hash hash, @NotNull String longRefPath, @NotNull VirtualFile root) {
     String name = getRefName(longRefPath, "refs/tags/");
     if (name != null) {
-      return new VcsRefImpl(hash, name, GitRefManager.TAG, root);
+      return myFactory.createRef(hash, name, GitRefManager.TAG, root);
     }
 
     return null;
diff --git a/plugins/git4idea/src/git4idea/push/GitPushLog.java b/plugins/git4idea/src/git4idea/push/GitPushLog.java
index 335665f..b4e8f1c 100644
--- a/plugins/git4idea/src/git4idea/push/GitPushLog.java
+++ b/plugins/git4idea/src/git4idea/push/GitPushLog.java
@@ -96,7 +96,7 @@
         Object userObject = ((DefaultMutableTreeNode)node).getUserObject();
         if (userObject instanceof GitCommit) {
           GitCommit commit = (GitCommit)userObject;
-          return getHashString(commit) + "  " + getDateString(commit) + "  by " + commit.getAuthorName() + "\n\n" +
+          return getHashString(commit) + "  " + getDateString(commit) + "  by " + commit.getAuthor().getName() + "\n\n" +
                  IssueLinkHtmlRenderer.formatTextWithLinks(myProject, commit.getFullMessage());
         }
         return "";
diff --git a/plugins/git4idea/src/git4idea/repo/GitRepoInfo.java b/plugins/git4idea/src/git4idea/repo/GitRepoInfo.java
index cbeb0c4..33dc6a7 100644
--- a/plugins/git4idea/src/git4idea/repo/GitRepoInfo.java
+++ b/plugins/git4idea/src/git4idea/repo/GitRepoInfo.java
@@ -16,8 +16,11 @@
 package git4idea.repo;
 
 import com.intellij.dvcs.repo.Repository;
+import git4idea.GitBranch;
 import git4idea.GitLocalBranch;
 import git4idea.GitRemoteBranch;
+import gnu.trove.THashSet;
+import gnu.trove.TObjectHashingStrategy;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -97,8 +100,8 @@
     if (myCurrentBranch != null ? !myCurrentBranch.equals(info.myCurrentBranch) : info.myCurrentBranch != null) return false;
     if (!myRemotes.equals(info.myRemotes)) return false;
     if (!myBranchTrackInfos.equals(info.myBranchTrackInfos)) return false;
-    if (!myLocalBranches.equals(info.myLocalBranches)) return false;
-    if (!myRemoteBranches.equals(info.myRemoteBranches)) return false;
+    if (!areEqual(myLocalBranches, info.myLocalBranches)) return false;
+    if (!areEqual(myRemoteBranches, info.myRemoteBranches)) return false;
 
     return true;
   }
@@ -120,4 +123,32 @@
     return String.format("GitRepoInfo{current=%s, remotes=%s, localBranches=%s, remoteBranches=%s, trackInfos=%s}",
                          myCurrentBranch, myRemotes, myLocalBranches, myRemoteBranches, myBranchTrackInfos);
   }
+
+  private static <T extends GitBranch> boolean areEqual(Collection<T> c1, Collection<T> c2) {
+    // GitBranch has perverted equals contract (see the comment there)
+    // until GitBranch is created only from a single place with correctly defined Hash, we can't change its equals
+    THashSet<GitBranch> set1 = new THashSet<GitBranch>(c1, new BranchesComparingStrategy());
+    THashSet<GitBranch> set2 = new THashSet<GitBranch>(c2, new BranchesComparingStrategy());
+    return set1.equals(set2);
+  }
+
+  private static class BranchesComparingStrategy implements TObjectHashingStrategy<GitBranch> {
+
+    @Override
+    public int computeHashCode(@NotNull GitBranch branch) {
+      return 31 * branch.getName().hashCode() + branch.getHash().hashCode();
+    }
+
+    @Override
+    public boolean equals(@NotNull GitBranch b1, @NotNull GitBranch b2) {
+      if (b1 == b2) {
+        return true;
+      }
+      if (b1.getClass() != b2.getClass()) {
+        return false;
+      }
+      return b1.getName().equals(b2.getName()) && b1.getHash().equals(b2.getHash());
+    }
+  }
+
 }
diff --git a/plugins/git4idea/src/git4idea/ui/GitCommitListPanel.java b/plugins/git4idea/src/git4idea/ui/GitCommitListPanel.java
index c91efbd..4e774d3 100644
--- a/plugins/git4idea/src/git4idea/ui/GitCommitListPanel.java
+++ b/plugins/git4idea/src/git4idea/ui/GitCommitListPanel.java
@@ -202,7 +202,7 @@
   }
 
   private static String getAuthor(GitCommit commit) {
-    return commit.getAuthorName();
+    return commit.getAuthor().getName();
   }
 
   private static String getTime(GitCommit commit) {
diff --git a/plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java b/plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java
index f750427..5e22069 100644
--- a/plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java
+++ b/plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java
@@ -262,7 +262,7 @@
   private static VcsFullCommitDetails mockCommit(String hash, String message) {
     List<Change> changes = new ArrayList<Change>();
     changes.add(new Change(null, new MockContentRevision(new FilePathImpl(new MockVirtualFile("name")), VcsRevisionNumber.NULL)));
-    return ServiceManager.getService(VcsLogObjectsFactory.class).createFullDetails(
+    return ServiceManager.getService(myProject, VcsLogObjectsFactory.class).createFullDetails(
       HashImpl.build(hash), Collections.<Hash>emptyList(), 0, NullVirtualFile.INSTANCE, message, "John Smith", "[email protected]", message,
       "John Smith", "[email protected]", 0, changes, GitContentRevisionFactory.getInstance(myProject));
   }
diff --git a/plugins/git4idea/tests/git4idea/log/GitLogRefSorterTest.java b/plugins/git4idea/tests/git4idea/log/GitLogRefSorterTest.java
index 7346852..74f914c 100644
--- a/plugins/git4idea/tests/git4idea/log/GitLogRefSorterTest.java
+++ b/plugins/git4idea/tests/git4idea/log/GitLogRefSorterTest.java
@@ -6,7 +6,9 @@
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.testFramework.UsefulTestCase;
 import com.intellij.util.Function;
+import com.intellij.util.NotNullFunction;
 import com.intellij.util.containers.ContainerUtil;
+import com.intellij.vcs.log.Hash;
 import com.intellij.vcs.log.VcsRef;
 import com.intellij.vcs.log.VcsRefType;
 import com.intellij.vcs.log.impl.HashImpl;
@@ -135,7 +137,13 @@
   }
 
   private static VcsRef ref(String hash, String name, VcsRefType type) {
-    return new VcsRefImpl(HashImpl.build(hash), name, type, MOCK_VIRTUAL_FILE);
+    return new VcsRefImpl(new NotNullFunction<Hash, Integer>() {
+      @NotNull
+      @Override
+      public Integer fun(Hash hash) {
+        return Integer.parseInt(hash.asString().substring(0, Math.min(4, hash.asString().length())), 16);
+      }
+    }, HashImpl.build(hash), name, type, MOCK_VIRTUAL_FILE);
   }
 
   private static void check(Collection<VcsRef> unsorted, List<VcsRef> expected) {
diff --git a/plugins/git4idea/tests/git4idea/log/RefParserTest.java b/plugins/git4idea/tests/git4idea/log/RefParserTest.java
index ea393fe..c56aeb5 100644
--- a/plugins/git4idea/tests/git4idea/log/RefParserTest.java
+++ b/plugins/git4idea/tests/git4idea/log/RefParserTest.java
@@ -1,7 +1,12 @@
 package git4idea.log;
 
+import com.intellij.openapi.vcs.changes.Change;
+import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.newvfs.impl.NullVirtualFile;
-import com.intellij.vcs.log.VcsRef;
+import com.intellij.util.NotNullFunction;
+import com.intellij.vcs.log.*;
+import com.intellij.vcs.log.impl.VcsRefImpl;
+import org.jetbrains.annotations.NotNull;
 import org.junit.Test;
 
 import java.util.List;
@@ -18,7 +23,7 @@
   }
 
   public void runTest(String inputStr, String outStr) {
-    List<VcsRef> refs = RefParser.parseCommitRefs(inputStr, NullVirtualFile.INSTANCE);
+    List<VcsRef> refs = new RefParser(new TestLogObjectsFactory()).parseCommitRefs(inputStr, NullVirtualFile.INSTANCE);
     StringBuilder s = new StringBuilder();
     for (VcsRef ref : refs) {
       if (s.length() > 0) {
@@ -61,4 +66,58 @@
   }
 
 
+  private class TestLogObjectsFactory implements VcsLogObjectsFactory {
+    @NotNull
+    @Override
+    public Hash createHash(@NotNull String stringHash) {
+      throw new UnsupportedOperationException();
+    }
+
+    @NotNull
+    @Override
+    public VcsCommit createCommit(@NotNull Hash hash, @NotNull List<Hash> parents) {
+      throw new UnsupportedOperationException();
+    }
+
+    @NotNull
+    @Override
+    public TimedVcsCommit createTimedCommit(@NotNull Hash hash, @NotNull List<Hash> parents, long timeStamp) {
+      throw new UnsupportedOperationException();
+    }
+
+    @NotNull
+    @Override
+    public VcsShortCommitDetails createShortDetails(@NotNull Hash hash, @NotNull List<Hash> parents, long timeStamp, VirtualFile root,
+                                                    @NotNull String subject, @NotNull String authorName, String authorEmail) {
+      throw new UnsupportedOperationException();
+    }
+
+    @NotNull
+    @Override
+    public VcsFullCommitDetails createFullDetails(@NotNull Hash hash, @NotNull List<Hash> parents, long authorTime, VirtualFile root,
+                                                  @NotNull String subject, @NotNull String authorName, @NotNull String authorEmail,
+                                                  @NotNull String message, @NotNull String committerName, @NotNull String committerEmail,
+                                                  long commitTime, @NotNull List<Change> changes,
+                                                  @NotNull ContentRevisionFactory contentRevisionFactory) {
+      throw new UnsupportedOperationException();
+    }
+
+    @NotNull
+    @Override
+    public VcsUser createUser(@NotNull String name, @NotNull String email) {
+      throw new UnsupportedOperationException();
+    }
+
+    @NotNull
+    @Override
+    public VcsRef createRef(@NotNull Hash commitHash, @NotNull String name, @NotNull VcsRefType type, @NotNull VirtualFile root) {
+      return new VcsRefImpl(new NotNullFunction<Hash, Integer>() {
+        @NotNull
+        @Override
+        public Integer fun(Hash dom) {
+          return Integer.parseInt(dom.asString().substring(0, Math.min(4, dom.asString().length())), 16);
+        }
+      }, commitHash, name, type, root);
+    }
+  }
 }
diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserFromLogAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserFromLogAction.java
index 7b3d9a1..06392ba 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserFromLogAction.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserFromLogAction.java
@@ -70,7 +70,7 @@
   private static VcsShortCommitDetails getCurrentlySelectedCommitInTheLog(AnActionEvent e) {
     GitHeavyCommit heavyCommit = e.getData(GitVcs.GIT_COMMIT);
     if (heavyCommit != null) {
-      final VcsLogObjectsFactory factory = ServiceManager.getService(VcsLogObjectsFactory.class);
+      final VcsLogObjectsFactory factory = ServiceManager.getService(e.getProject(), VcsLogObjectsFactory.class);
       List<Hash> parents = ContainerUtil.map(heavyCommit.getParentsHashes(), new Function<String, Hash>() {
         @Override
         public Hash fun(String s) {
@@ -78,7 +78,8 @@
         }
       });
       return factory.createShortDetails(factory.createHash(heavyCommit.getHash().getValue()), parents, heavyCommit.getAuthorTime(),
-                                        heavyCommit.getRoot(), heavyCommit.getSubject(), heavyCommit.getAuthor());
+                                        heavyCommit.getRoot(), heavyCommit.getSubject(), heavyCommit.getAuthor(),
+                                        heavyCommit.getAuthorEmail());
     }
     VcsLog log = e.getData(VcsLogDataKeys.VSC_LOG);
     if (log == null) {
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
index 69f6efb..885f252 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
@@ -671,7 +671,7 @@
                                                    @NotNull String repo,
                                                    @Nullable String query) throws IOException {
     try {
-      query = URLEncoder.encode("@" + user + "/" + repo + " " + query, "UTF-8");
+      query = URLEncoder.encode("repo:" + user + "/" + repo + " " + query, "UTF-8");
       String path = "/search/issues?q=" + query;
 
       //TODO: Use bodyHtml for issues - GitHub does not support this feature for SearchApi yet
diff --git a/plugins/gradle/gradle.iml b/plugins/gradle/gradle.iml
index fba8a60..cc1787c 100644
--- a/plugins/gradle/gradle.iml
+++ b/plugins/gradle/gradle.iml
@@ -26,100 +26,100 @@
     <orderEntry type="module-library" exported="">
       <library name="Gradle">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/lib/gradle-base-services-1.9-rc-2.jar!/" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-core-1.9-rc-2.jar!/" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-messaging-1.9-rc-2.jar!/" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-tooling-api-1.9-rc-2.jar!/" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-wrapper-1.9-rc-2.jar!/" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-plugins-1.9-rc-2.jar!/" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-build-init-1.9-rc-2.jar!/" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-native-1.9-rc-2.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-base-services-1.9-rc-3.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-core-1.9-rc-3.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-messaging-1.9-rc-3.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-tooling-api-1.9-rc-3.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-wrapper-1.9-rc-3.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-plugins-1.9-rc-3.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-build-init-1.9-rc-3.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-native-1.9-rc-3.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/buildSrc/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/buildSrc/src/test/resources" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/ui/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/ui/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/ui/src/integTest/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/cli/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/cpp/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/cpp/src/integTest/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/ear/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/ide/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/ide/src/main/resources" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/tasks" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/plugins" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/ivy/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/core/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/core/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/core/src/integTest/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/core/src/testFixtures/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/osgi/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/osgi/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/antlr/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/jetty/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/maven/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/maven/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/scala/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/scala/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/jacoco/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/native/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/plugins/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/plugins/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/plugins/src/testFixtures/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/publish/src/main/groovy/org/gradle/api/publish/plugins" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/publish/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/wrapper/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/wrapper/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/announce/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/launcher/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/launcher/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/launcher/src/integTest/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/open-api/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/open-api/src/integTest/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/core-impl/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/core-impl/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/messaging/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/messaging/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/reporting/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/resources/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/javascript/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/testjar/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/testjar/src/test/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/multiModule/webinar-api/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/multiModule/webinar-impl/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/multiModule/webinar-impl/src/test/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/singleModule/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/singleModule/src/test/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/enforcerplugin/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-api/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-impl/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-impl/src/test/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/diagnostics/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/diagnostics/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/diagnostics/src/integTest/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/performance/src/configPlugin" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/performance/src/testFixtures/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/tooling-api/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/tooling-api/src/integTest/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/tooling-api/src/testFixtures/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/code-quality/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/language-jvm/src/main/groovy/org/gradle/language/jvm/tasks" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/language-jvm/src/main/groovy/org/gradle/language/jvm/plugins" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/language-jvm/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/base-services/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/base-services/src/test/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/language-base/src/main/groovy/org/gradle/language/base/plugins" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/language-base/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-comparison/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-comparison/src/integTest/resources/org/gradle/api/plugins/buildcomparison/gradle/BuildComparisonIntegrationSpec/compareArchives/source/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/build-comparison/src/integTest/resources/org/gradle/api/plugins/buildcomparison/gradle/BuildComparisonIntegrationSpec/compareArchives/target/src/main/java" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/internal-testing/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/base-services-groovy/src/main/groovy" />
-          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-2-src.zip!/gradle-1.9-rc-2/subprojects/base-services-groovy/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/buildSrc/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/buildSrc/src/test/resources" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/ui/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/ui/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/ui/src/integTest/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/cli/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/cpp/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/cpp/src/integTest/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/ear/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/ide/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/ide/src/main/resources" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/tasks" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/plugins" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/ivy/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/core/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/core/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/core/src/integTest/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/core/src/testFixtures/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/osgi/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/osgi/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/antlr/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/jetty/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/maven/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/maven/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/scala/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/scala/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/jacoco/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/native/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/plugins/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/plugins/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/plugins/src/testFixtures/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/publish/src/main/groovy/org/gradle/api/publish/plugins" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/publish/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/wrapper/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/wrapper/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/announce/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/launcher/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/launcher/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/launcher/src/integTest/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/open-api/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/open-api/src/integTest/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/core-impl/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/core-impl/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/messaging/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/messaging/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/reporting/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/resources/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/javascript/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/testjar/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/testjar/src/test/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/multiModule/webinar-api/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/multiModule/webinar-impl/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/multiModule/webinar-impl/src/test/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/singleModule/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/singleModule/src/test/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/enforcerplugin/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-api/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-impl/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-impl/src/test/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/diagnostics/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/diagnostics/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/diagnostics/src/integTest/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/performance/src/configPlugin" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/performance/src/testFixtures/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/tooling-api/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/tooling-api/src/integTest/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/tooling-api/src/testFixtures/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/code-quality/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/language-jvm/src/main/groovy/org/gradle/language/jvm/tasks" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/language-jvm/src/main/groovy/org/gradle/language/jvm/plugins" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/language-jvm/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/base-services/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/base-services/src/test/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/language-base/src/main/groovy/org/gradle/language/base/plugins" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/language-base/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-comparison/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-comparison/src/integTest/resources/org/gradle/api/plugins/buildcomparison/gradle/BuildComparisonIntegrationSpec/compareArchives/source/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/build-comparison/src/integTest/resources/org/gradle/api/plugins/buildcomparison/gradle/BuildComparisonIntegrationSpec/compareArchives/target/src/main/java" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/internal-testing/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/base-services-groovy/src/main/groovy" />
+          <root url="jar://$MODULE_DIR$/lib/gradle-1.9-rc-3-src.zip!/gradle-1.9-rc-3/subprojects/base-services-groovy/src/test/groovy" />
         </SOURCES>
       </library>
     </orderEntry>
@@ -136,12 +136,10 @@
     <orderEntry type="module-library" exported="">
       <library name="GradleGuava">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/lib/guava-11.0.2.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/guava-jdk5-14.0.1.jar!/" />
         </CLASSES>
         <JAVADOC />
-        <SOURCES>
-          <root url="jar://$USER_HOME$/.ideaLibSources/guava-11.0.2-sources.jar!/" />
-        </SOURCES>
+        <SOURCES />
       </library>
     </orderEntry>
     <orderEntry type="module-library">
@@ -171,9 +169,20 @@
         <CLASSES>
           <root url="jar://$MODULE_DIR$/lib/jna-3.2.7.jar!/" />
           <root url="jar://$MODULE_DIR$/lib/jna-posix-1.0.3.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/native-platform-0.3-rc-2.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/native-platform-linux-amd64-0.3-rc-2.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/native-platform-linux-i386-0.3-rc-2.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/native-platform-osx-universal-0.3-rc-2.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/native-platform-windows-amd64-0.3-rc-2.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/native-platform-windows-i386-0.3-rc-2.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES />
+        <jarDirectory url="jar://$MODULE_DIR$/lib/native-platform-linux-amd64-0.3-rc-2.jar!/" recursive="false" />
+        <jarDirectory url="jar://$MODULE_DIR$/lib/native-platform-linux-i386-0.3-rc-2.jar!/" recursive="false" />
+        <jarDirectory url="jar://$MODULE_DIR$/lib/native-platform-osx-universal-0.3-rc-2.jar!/" recursive="false" />
+        <jarDirectory url="jar://$MODULE_DIR$/lib/native-platform-windows-amd64-0.3-rc-2.jar!/" recursive="false" />
+        <jarDirectory url="jar://$MODULE_DIR$/lib/native-platform-windows-i386-0.3-rc-2.jar!/" recursive="false" />
       </library>
     </orderEntry>
     <orderEntry type="module" module-name="testFramework-java" scope="TEST" />
diff --git a/plugins/gradle/lib/gradle-1.8-src.zip b/plugins/gradle/lib/gradle-1.8-src.zip
deleted file mode 100644
index d4857b6..0000000
--- a/plugins/gradle/lib/gradle-1.8-src.zip
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/lib/gradle-1.9-rc-2-src.zip b/plugins/gradle/lib/gradle-1.9-rc-3-src.zip
similarity index 85%
rename from plugins/gradle/lib/gradle-1.9-rc-2-src.zip
rename to plugins/gradle/lib/gradle-1.9-rc-3-src.zip
index 912d335..0401dfc 100644
--- a/plugins/gradle/lib/gradle-1.9-rc-2-src.zip
+++ b/plugins/gradle/lib/gradle-1.9-rc-3-src.zip
Binary files differ
diff --git a/plugins/gradle/lib/gradle-base-services-1.8.jar b/plugins/gradle/lib/gradle-base-services-1.8.jar
deleted file mode 100644
index 8f1c65d..0000000
--- a/plugins/gradle/lib/gradle-base-services-1.8.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/lib/gradle-base-services-1.9-rc-2.jar b/plugins/gradle/lib/gradle-base-services-1.9-rc-3.jar
similarity index 84%
rename from plugins/gradle/lib/gradle-base-services-1.9-rc-2.jar
rename to plugins/gradle/lib/gradle-base-services-1.9-rc-3.jar
index 01da1fd..fbc2d9d 100644
--- a/plugins/gradle/lib/gradle-base-services-1.9-rc-2.jar
+++ b/plugins/gradle/lib/gradle-base-services-1.9-rc-3.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-build-init-1.9-rc-2.jar b/plugins/gradle/lib/gradle-build-init-1.9-rc-3.jar
similarity index 62%
rename from plugins/gradle/lib/gradle-build-init-1.9-rc-2.jar
rename to plugins/gradle/lib/gradle-build-init-1.9-rc-3.jar
index 2cc1814..c776e9b 100644
--- a/plugins/gradle/lib/gradle-build-init-1.9-rc-2.jar
+++ b/plugins/gradle/lib/gradle-build-init-1.9-rc-3.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-build-setup-1.8.jar b/plugins/gradle/lib/gradle-build-setup-1.8.jar
deleted file mode 100644
index 5a92990..0000000
--- a/plugins/gradle/lib/gradle-build-setup-1.8.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/lib/gradle-core-1.8.jar b/plugins/gradle/lib/gradle-core-1.8.jar
deleted file mode 100644
index e0fda00..0000000
--- a/plugins/gradle/lib/gradle-core-1.8.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/lib/gradle-core-1.9-rc-2.jar b/plugins/gradle/lib/gradle-core-1.9-rc-3.jar
similarity index 82%
rename from plugins/gradle/lib/gradle-core-1.9-rc-2.jar
rename to plugins/gradle/lib/gradle-core-1.9-rc-3.jar
index ac7d868..f9efe10 100644
--- a/plugins/gradle/lib/gradle-core-1.9-rc-2.jar
+++ b/plugins/gradle/lib/gradle-core-1.9-rc-3.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-messaging-1.8.jar b/plugins/gradle/lib/gradle-messaging-1.8.jar
deleted file mode 100644
index 9cf71f5..0000000
--- a/plugins/gradle/lib/gradle-messaging-1.8.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/lib/gradle-messaging-1.9-rc-2.jar b/plugins/gradle/lib/gradle-messaging-1.9-rc-3.jar
similarity index 87%
rename from plugins/gradle/lib/gradle-messaging-1.9-rc-2.jar
rename to plugins/gradle/lib/gradle-messaging-1.9-rc-3.jar
index ec97203..b255624 100644
--- a/plugins/gradle/lib/gradle-messaging-1.9-rc-2.jar
+++ b/plugins/gradle/lib/gradle-messaging-1.9-rc-3.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-native-1.8.jar b/plugins/gradle/lib/gradle-native-1.8.jar
deleted file mode 100644
index 84b4bf7..0000000
--- a/plugins/gradle/lib/gradle-native-1.8.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/lib/gradle-native-1.9-rc-2.jar b/plugins/gradle/lib/gradle-native-1.9-rc-3.jar
similarity index 84%
rename from plugins/gradle/lib/gradle-native-1.9-rc-2.jar
rename to plugins/gradle/lib/gradle-native-1.9-rc-3.jar
index 46a9b34..6909e53 100644
--- a/plugins/gradle/lib/gradle-native-1.9-rc-2.jar
+++ b/plugins/gradle/lib/gradle-native-1.9-rc-3.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-plugins-1.8.jar b/plugins/gradle/lib/gradle-plugins-1.8.jar
deleted file mode 100644
index 071d1c1..0000000
--- a/plugins/gradle/lib/gradle-plugins-1.8.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/lib/gradle-plugins-1.9-rc-2.jar b/plugins/gradle/lib/gradle-plugins-1.9-rc-3.jar
similarity index 75%
rename from plugins/gradle/lib/gradle-plugins-1.9-rc-2.jar
rename to plugins/gradle/lib/gradle-plugins-1.9-rc-3.jar
index 53c7139..2906284 100644
--- a/plugins/gradle/lib/gradle-plugins-1.9-rc-2.jar
+++ b/plugins/gradle/lib/gradle-plugins-1.9-rc-3.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-tooling-api-1.8.jar b/plugins/gradle/lib/gradle-tooling-api-1.8.jar
deleted file mode 100644
index 7e744bb..0000000
--- a/plugins/gradle/lib/gradle-tooling-api-1.8.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/lib/gradle-tooling-api-1.9-rc-2.jar b/plugins/gradle/lib/gradle-tooling-api-1.9-rc-3.jar
similarity index 82%
rename from plugins/gradle/lib/gradle-tooling-api-1.9-rc-2.jar
rename to plugins/gradle/lib/gradle-tooling-api-1.9-rc-3.jar
index 673c6f1..8902ddd 100644
--- a/plugins/gradle/lib/gradle-tooling-api-1.9-rc-2.jar
+++ b/plugins/gradle/lib/gradle-tooling-api-1.9-rc-3.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-wrapper-1.8.jar b/plugins/gradle/lib/gradle-wrapper-1.8.jar
deleted file mode 100644
index 31e2d66..0000000
--- a/plugins/gradle/lib/gradle-wrapper-1.8.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/lib/gradle-wrapper-1.9-rc-2.jar b/plugins/gradle/lib/gradle-wrapper-1.9-rc-3.jar
similarity index 90%
rename from plugins/gradle/lib/gradle-wrapper-1.9-rc-2.jar
rename to plugins/gradle/lib/gradle-wrapper-1.9-rc-3.jar
index f8ef3d6..1ada72a 100644
--- a/plugins/gradle/lib/gradle-wrapper-1.9-rc-2.jar
+++ b/plugins/gradle/lib/gradle-wrapper-1.9-rc-3.jar
Binary files differ
diff --git a/plugins/gradle/lib/guava-11.0.2.jar b/plugins/gradle/lib/guava-11.0.2.jar
deleted file mode 100644
index c8c8d5d..0000000
--- a/plugins/gradle/lib/guava-11.0.2.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/lib/guava-jdk5-14.0.1.jar b/plugins/gradle/lib/guava-jdk5-14.0.1.jar
new file mode 100644
index 0000000..af66ab0
--- /dev/null
+++ b/plugins/gradle/lib/guava-jdk5-14.0.1.jar
Binary files differ
diff --git a/plugins/gradle/lib/native-platform-0.3-rc-2.jar b/plugins/gradle/lib/native-platform-0.3-rc-2.jar
new file mode 100644
index 0000000..ede1eca
--- /dev/null
+++ b/plugins/gradle/lib/native-platform-0.3-rc-2.jar
Binary files differ
diff --git a/plugins/gradle/lib/native-platform-linux-amd64-0.3-rc-2.jar b/plugins/gradle/lib/native-platform-linux-amd64-0.3-rc-2.jar
new file mode 100644
index 0000000..14508de
--- /dev/null
+++ b/plugins/gradle/lib/native-platform-linux-amd64-0.3-rc-2.jar
Binary files differ
diff --git a/plugins/gradle/lib/native-platform-linux-i386-0.3-rc-2.jar b/plugins/gradle/lib/native-platform-linux-i386-0.3-rc-2.jar
new file mode 100644
index 0000000..4e8c6db
--- /dev/null
+++ b/plugins/gradle/lib/native-platform-linux-i386-0.3-rc-2.jar
Binary files differ
diff --git a/plugins/gradle/lib/native-platform-osx-universal-0.3-rc-2.jar b/plugins/gradle/lib/native-platform-osx-universal-0.3-rc-2.jar
new file mode 100644
index 0000000..5942383
--- /dev/null
+++ b/plugins/gradle/lib/native-platform-osx-universal-0.3-rc-2.jar
Binary files differ
diff --git a/plugins/gradle/lib/native-platform-windows-amd64-0.3-rc-2.jar b/plugins/gradle/lib/native-platform-windows-amd64-0.3-rc-2.jar
new file mode 100644
index 0000000..d048493
--- /dev/null
+++ b/plugins/gradle/lib/native-platform-windows-amd64-0.3-rc-2.jar
Binary files differ
diff --git a/plugins/gradle/lib/native-platform-windows-i386-0.3-rc-2.jar b/plugins/gradle/lib/native-platform-windows-i386-0.3-rc-2.jar
new file mode 100644
index 0000000..47b6430
--- /dev/null
+++ b/plugins/gradle/lib/native-platform-windows-i386-0.3-rc-2.jar
Binary files differ
diff --git a/plugins/gradle/src/META-INF/gradle-javaee-plugin.xml b/plugins/gradle/src/META-INF/gradle-javaee-plugin.xml
new file mode 100644
index 0000000..2a8b4d5
--- /dev/null
+++ b/plugins/gradle/src/META-INF/gradle-javaee-plugin.xml
@@ -0,0 +1,8 @@
+<idea-plugin>
+  <extensions defaultExtensionNs="com.intellij">
+    <externalProjectDataService implementation="org.jetbrains.plugins.gradle.service.project.data.javaee.WebModuleGradleDataService"/>
+  </extensions>
+  <extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
+    <projectResolve implementation="org.jetbrains.plugins.gradle.integrations.javaee.JavaEEGradleProjectResolverExtension"/>
+  </extensions>
+</idea-plugin>
diff --git a/plugins/gradle/src/META-INF/services/org.jetbrains.plugins.gradle.model.ModelBuilderService b/plugins/gradle/src/META-INF/services/org.jetbrains.plugins.gradle.model.ModelBuilderService
new file mode 100644
index 0000000..9d8e690
--- /dev/null
+++ b/plugins/gradle/src/META-INF/services/org.jetbrains.plugins.gradle.model.ModelBuilderService
@@ -0,0 +1,16 @@
+#
+# 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.
+#
+org.jetbrains.plugins.gradle.model.impl.WarModelBuilderImpl
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java
index 4013ee3..d109ded 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java
@@ -17,8 +17,6 @@
 
 import com.intellij.execution.ExecutionException;
 import com.intellij.execution.configurations.SimpleJavaParameters;
-import com.intellij.externalSystem.JavaProjectData;
-import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.externalSystem.ExternalSystemAutoImportAware;
@@ -39,14 +37,11 @@
 import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
 import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware;
 import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager;
+import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange;
 import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
 import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
 import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.module.EmptyModuleType;
-import com.intellij.openapi.module.JavaModuleType;
-import com.intellij.openapi.module.ModuleType;
-import com.intellij.openapi.module.StdModuleTypes;
 import com.intellij.openapi.options.Configurable;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
@@ -55,14 +50,10 @@
 import com.intellij.openapi.util.NotNullLazyValue;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.pom.java.LanguageLevel;
 import com.intellij.util.Function;
-import com.intellij.util.PathUtil;
-import com.intellij.util.PathsList;
 import com.intellij.util.containers.ContainerUtilRt;
 import com.intellij.util.messages.MessageBusConnection;
 import icons.GradleIcons;
-import org.gradle.tooling.ProjectConnection;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.gradle.config.GradleSettingsListenerAdapter;
@@ -74,13 +65,11 @@
 import org.jetbrains.plugins.gradle.service.settings.GradleConfigurable;
 import org.jetbrains.plugins.gradle.service.task.GradleTaskManager;
 import org.jetbrains.plugins.gradle.settings.*;
-import org.jetbrains.plugins.gradle.util.GradleBundle;
 import org.jetbrains.plugins.gradle.util.GradleConstants;
 import org.jetbrains.plugins.gradle.util.GradleUtil;
 
 import javax.swing.*;
 import java.io.File;
-import java.io.FilenameFilter;
 import java.io.IOException;
 import java.net.URL;
 import java.util.Collection;
@@ -291,9 +280,9 @@
                 if (externalProject == null) {
                   return;
                 }
-                ExternalSystemApiUtil.executeProjectChangeAction(true, new Runnable() {
+                ExternalSystemApiUtil.executeProjectChangeAction(true, new DisposeAwareProjectChange(project) {
                   @Override
-                  public void run() {
+                  public void execute() {
                     ProjectRootManagerEx.getInstanceEx(project).mergeRootsChangesDuring(new Runnable() {
                       @Override
                       public void run() {
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java
index e343850..592b668 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java
@@ -22,6 +22,7 @@
 import com.intellij.openapi.externalSystem.model.project.ProjectData;
 import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
 import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
+import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange;
 import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
 import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
 import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
@@ -127,9 +128,9 @@
                   if (externalProject == null) {
                     return;
                   }
-                  ExternalSystemApiUtil.executeProjectChangeAction(true, new Runnable() {
+                  ExternalSystemApiUtil.executeProjectChangeAction(true, new DisposeAwareProjectChange(module.getProject()) {
                     @Override
-                    public void run() {
+                    public void execute() {
                       ProjectRootManagerEx.getInstanceEx(module.getProject()).mergeRootsChangesDuring(new Runnable() {
                         @Override
                         public void run() {
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/javaee/JavaEEGradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/javaee/JavaEEGradleProjectResolverExtension.java
new file mode 100644
index 0000000..07621c6
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/javaee/JavaEEGradleProjectResolverExtension.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.gradle.integrations.javaee;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.project.ModuleData;
+import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
+import com.intellij.openapi.externalSystem.util.Order;
+import com.intellij.util.containers.ContainerUtil;
+import org.gradle.tooling.model.idea.IdeaModule;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.model.WarModel;
+import org.jetbrains.plugins.gradle.model.data.WarModelData;
+import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
+
+import java.util.Set;
+
+/**
+ * {@link JavaEEGradleProjectResolverExtension} provides JavaEE project info based on gradle tooling API models.
+ *
+ * @author Vladislav.Soroka
+ * @since 10/14/13
+ */
+@Order(ExternalSystemConstants.UNORDERED)
+public class JavaEEGradleProjectResolverExtension extends AbstractProjectResolverExtension {
+  private static final Logger LOG = Logger.getInstance(JavaEEGradleProjectResolverExtension.class);
+
+  @Override
+  public void populateModuleExtraModels(@NotNull IdeaModule gradleModule, @NotNull DataNode<ModuleData> ideModule) {
+    WarModel warModel = resolverCtx.getExtraProject(gradleModule, WarModel.class);
+    if (warModel != null) {
+      WarModelData warModelData = new WarModelData(GradleConstants.SYSTEM_ID, warModel.getWebAppDirName(), warModel.getWebAppDir());
+      warModelData.setWebXml(warModel.getWebXml());
+      warModelData.setWebRoots(warModel.getWebRoots());
+      ideModule.createChild(WarModelData.KEY, warModelData);
+    }
+
+    nextResolver.populateModuleExtraModels(gradleModule, ideModule);
+  }
+
+  @NotNull
+  @Override
+  public Set<Class> getExtraProjectModelClasses() {
+    return ContainerUtil.<Class>set(WarModel.class);
+  }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/ModelBuilderService.java
similarity index 65%
copy from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java
copy to plugins/gradle/src/org/jetbrains/plugins/gradle/model/ModelBuilderService.java
index bed999e..3a76dbe 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/ModelBuilderService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -13,12 +13,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jetbrains.plugins.groovy.lang;
+package org.jetbrains.plugins.gradle.model;
 
-import com.intellij.ide.hierarchy.type.JavaTypeHierarchyProvider;
+import org.gradle.api.Project;
 
 /**
- * @author peter
+ * @author Vladislav.Soroka
+ * @since 11/5/13
  */
-public class GroovyTypeHierarchyProvider extends JavaTypeHierarchyProvider{
+public interface ModelBuilderService {
+  boolean canBuild(String modelName);
+
+  Object buildAll(String modelName, Project project);
 }
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/WarModel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/WarModel.java
new file mode 100644
index 0000000..2986494
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/WarModel.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.gradle.model;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/5/13
+ */
+public interface WarModel extends Serializable {
+  String getWebAppDirName();
+
+  File getWebAppDir();
+
+  File getWebXml();
+
+  Map<String, Set<String>> getWebRoots();
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WarModelData.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WarModelData.java
new file mode 100644
index 0000000..80eef6e
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WarModelData.java
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.gradle.model.data;
+
+import com.intellij.openapi.externalSystem.model.Key;
+import com.intellij.openapi.externalSystem.model.ProjectKeys;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/6/13
+ */
+public class WarModelData extends AbstractExternalEntityData {
+  private static final long serialVersionUID = 1L;
+
+  @NotNull
+  public static final Key<WarModelData> KEY = Key.create(WarModelData.class, ProjectKeys.MODULE.getProcessingWeight() + 1);
+  @NotNull
+  private final String myWebAppDirName;
+  @Nullable
+  private final File myWebAppDir;
+  @Nullable
+  private File myWebXml;
+  @NotNull
+  private Map<String, Set<String>> myWebRoots;
+
+
+  public WarModelData(@NotNull ProjectSystemId owner, @NotNull String webAppDirName, @Nullable File webAppDir) {
+    super(owner);
+    myWebAppDirName = webAppDirName;
+    myWebAppDir = webAppDir;
+    myWebRoots = Collections.emptyMap();
+  }
+
+  @NotNull
+  public String getWebAppDirName() {
+    return myWebAppDirName;
+  }
+
+  @Nullable
+  public File getWebAppDir() {
+    return myWebAppDir;
+  }
+
+  public void setWebXml(@Nullable File webXml) {
+    myWebXml = webXml;
+  }
+
+  @Nullable
+  public File getWebXml() {
+    return myWebXml;
+  }
+
+  public void setWebRoots(@Nullable Map<String, Set<String>> webRoots) {
+    myWebRoots = webRoots == null ? Collections.<String, Set<String>>emptyMap() : webRoots;
+  }
+
+  @NotNull
+  public Map<String, Set<String>> getWebRoots() {
+    return myWebRoots;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    if (!super.equals(o)) return false;
+
+    WarModelData that = (WarModelData)o;
+
+    if (myWebAppDir != null ? !myWebAppDir.equals(that.myWebAppDir) : that.myWebAppDir != null) return false;
+    if (!myWebAppDirName.equals(that.myWebAppDirName)) return false;
+    if (!myWebRoots.equals(that.myWebRoots)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = super.hashCode();
+    result = 31 * result + myWebAppDirName.hashCode();
+    result = 31 * result + myWebRoots.hashCode();
+    return result;
+  }
+
+  @Override
+  public String toString() {
+    return "WarModelData{" +
+           "myWebAppDirName='" + myWebAppDirName + '\'' +
+           ", myWebAppDir=" + myWebAppDir +
+           ", myWebXml=" + myWebXml +
+           ", myWebRoots=" + myWebRoots +
+           '}';
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/impl/WarModelBuilderImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/impl/WarModelBuilderImpl.java
new file mode 100644
index 0000000..0e55d6b
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/impl/WarModelBuilderImpl.java
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.gradle.model.impl;
+
+import org.gradle.api.Action;
+import org.gradle.api.Project;
+import org.gradle.api.Task;
+import org.gradle.api.file.FileVisitDetails;
+import org.gradle.api.file.FileVisitor;
+import org.gradle.api.internal.file.copy.CopySpecInternal;
+import org.gradle.api.plugins.WarPlugin;
+import org.gradle.api.tasks.bundling.War;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.model.ModelBuilderService;
+import org.jetbrains.plugins.gradle.model.WarModel;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/5/13
+ */
+public class WarModelBuilderImpl implements ModelBuilderService {
+
+  private static final String WEB_APP_DIR_PROPERTY = "webAppDir";
+  private static final String WEB_APP_DIR_NAME_PROPERTY = "webAppDirName";
+
+  @Override
+  public boolean canBuild(String modelName) {
+    return WarModel.class.getName().equals(modelName);
+  }
+
+  @Nullable
+  @Override
+  public Object buildAll(String modelName, Project project) {
+    final WarPlugin warPlugin = project.getPlugins().findPlugin(WarPlugin.class);
+    if (warPlugin == null) return null;
+
+    final String webAppDirName = !project.hasProperty(WEB_APP_DIR_NAME_PROPERTY) ?
+                                 "src/main/webapp" : String.valueOf(project.property(WEB_APP_DIR_NAME_PROPERTY));
+
+    final File webAppDir = !project.hasProperty(WEB_APP_DIR_PROPERTY) ? null : (File)project.property(WEB_APP_DIR_PROPERTY);
+
+    WarModelImpl warModel = new WarModelImpl(webAppDirName, webAppDir);
+
+    for (Task task : project.getTasks()) {
+      if (task instanceof War) {
+        final War warTask = (War)task;
+        warModel.setWebXml(warTask.getWebXml());
+
+        final Map<String, Set<String>> webRoots = new HashMap<String, Set<String>>();
+        warTask.getRootSpec().walk(new Action<CopySpecInternal>() {
+          @Override
+          public void execute(CopySpecInternal internal) {
+            final String relativePath = internal.getDestPath().getPathString();
+            internal.getSource().visit(new FileVisitor() {
+              @Override
+              public void visitDir(FileVisitDetails dirDetails) {
+                try {
+                  addPath(webRoots, relativePath, dirDetails.getFile().getPath());
+                }
+                catch (Exception ignore) {
+                }
+              }
+
+              @Override
+              public void visitFile(FileVisitDetails fileDetails) {
+                try {
+                  if (warTask.getWebXml() == null ||
+                      !fileDetails.getFile().getCanonicalPath().equals(warTask.getWebXml().getCanonicalPath())) {
+                    addPath(webRoots, relativePath, fileDetails.getFile().getParent());
+                  }
+                }
+                catch (Exception ignore) {
+                }
+              }
+            });
+          }
+        });
+
+        warModel.setWebRoots(webRoots);
+        break;
+      }
+    }
+
+    return warModel;
+  }
+
+  private static void addPath(Map<String, Set<String>> webRoots, String relativePath, String path) {
+    relativePath = relativePath == null ? "" : relativePath;
+    Set<String> paths = webRoots.get(relativePath);
+    if (paths == null) {
+      paths = new LinkedHashSet<String>();
+      webRoots.put(relativePath, paths);
+    }
+    paths.add(path);
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/impl/WarModelImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/impl/WarModelImpl.java
new file mode 100644
index 0000000..47aa662
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/impl/WarModelImpl.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.gradle.model.impl;
+
+import org.jetbrains.plugins.gradle.model.WarModel;
+
+import java.io.File;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/5/13
+ */
+public class WarModelImpl implements WarModel {
+  private final String myWebAppDirName;
+  private final File myWebAppDir;
+  private File myWebXml;
+  private Map<String, Set<String>> myWebRoots;
+
+  public WarModelImpl(String webAppDirName, File webAppDir) {
+    myWebAppDirName = webAppDirName;
+    myWebAppDir = webAppDir;
+  }
+
+  @Override
+  public String getWebAppDirName() {
+    return myWebAppDirName;
+  }
+
+  @Override
+  public File getWebAppDir() {
+    return myWebAppDir;
+  }
+
+  public void setWebXml(File webXml) {
+    myWebXml = webXml;
+  }
+
+  @Override
+  public File getWebXml() {
+    return myWebXml;
+  }
+
+  @Override
+  public Map<String, Set<String>> getWebRoots() {
+    return myWebRoots;
+  }
+
+  public void setWebRoots(Map<String, Set<String>> webRoots) {
+    myWebRoots = webRoots;
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/ExtraModelBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/ExtraModelBuilder.java
new file mode 100644
index 0000000..2619557
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/ExtraModelBuilder.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.gradle.model.internal;
+
+import org.gradle.api.Project;
+import org.gradle.tooling.provider.model.ToolingModelBuilder;
+import org.jetbrains.plugins.gradle.model.ModelBuilderService;
+
+import java.util.ServiceLoader;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/5/13
+ */
+@SuppressWarnings("UnusedDeclaration")
+public class ExtraModelBuilder implements ToolingModelBuilder {
+  private static ServiceLoader<ModelBuilderService> buildersLoader =
+    ServiceLoader.load(ModelBuilderService.class, ExtraModelBuilder.class.getClassLoader());
+
+  @Override
+  public boolean canBuild(String modelName) {
+    for (ModelBuilderService service : buildersLoader) {
+      if (service.canBuild(modelName)) return true;
+    }
+    return false;
+  }
+
+  @Override
+  public Object buildAll(String modelName, Project project) {
+    for (ModelBuilderService service : buildersLoader) {
+      if (service.canBuild(modelName)) {
+        return service.buildAll(modelName, project);
+      }
+    }
+    throw new IllegalArgumentException("Unsupported model: " + modelName);
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle
new file mode 100644
index 0000000..a788cb8
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle
@@ -0,0 +1,42 @@
+/*
+ * 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.gradle.tooling.provider.model.ToolingModelBuilderRegistry
+
+@SuppressWarnings("GrPackage")
+class JetGradlePlugin implements Plugin<Project> {
+  private final ToolingModelBuilderRegistry registry
+
+  @javax.inject.Inject
+  public JetGradlePlugin(ToolingModelBuilderRegistry registry) {
+    this.registry = registry
+  }
+
+  public void apply(Project project) {
+    registry.register(project.jetExtraModelBuilderClass.newInstance())
+  }
+}
+
+try {
+  URL[] urls = [new File("${JAR_PATH}").toURI().toURL()]
+  URLClassLoader classLoader = new URLClassLoader(urls, getClass().classLoader)
+  Class modelClass = classLoader.loadClass('org.jetbrains.plugins.gradle.model.internal.ExtraModelBuilder')
+  allprojects {
+    ext.jetExtraModelBuilderClass = modelClass
+    apply plugin: JetGradlePlugin
+  }
+}
+catch (all) {
+}
\ No newline at end of file
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java
new file mode 100644
index 0000000..cde2278
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.gradle.service.project;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.SimpleJavaParameters;
+import com.intellij.externalSystem.JavaProjectData;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.ExternalSystemException;
+import com.intellij.openapi.externalSystem.model.project.ModuleData;
+import com.intellij.openapi.externalSystem.model.project.ProjectData;
+import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
+import com.intellij.openapi.externalSystem.util.Order;
+import com.intellij.openapi.util.KeyValue;
+import org.gradle.tooling.model.idea.IdeaModule;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.net.URL;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * {@link org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension} provides dummy implementation of Gradle project resolver.
+ *
+ * @author Vladislav.Soroka
+ * @since 10/14/13
+ */
+@Order(ExternalSystemConstants.UNORDERED)
+public abstract class AbstractProjectResolverExtension implements GradleProjectResolverExtension {
+
+  @NotNull protected ProjectResolverContext resolverCtx;
+  @NotNull protected GradleProjectResolverExtension nextResolver;
+
+  @Override
+  public void setProjectResolverContext(@NotNull ProjectResolverContext projectResolverContext) {
+    resolverCtx = projectResolverContext;
+  }
+
+  @Override
+  public void setNext(@Nullable GradleProjectResolverExtension next) {
+    // there always should be at least gradle basic resolver further in the chain
+    //noinspection ConstantConditions
+    assert next != null;
+    nextResolver = next;
+  }
+
+  @Nullable
+  @Override
+  public GradleProjectResolverExtension getNext() {
+    return nextResolver;
+  }
+
+  @NotNull
+  @Override
+  public ProjectData createProject() {
+    return nextResolver.createProject();
+  }
+
+  @NotNull
+  @Override
+  public JavaProjectData createJavaProjectData() {
+    return nextResolver.createJavaProjectData();
+  }
+
+  @NotNull
+  @Override
+  public ModuleData createModule(@NotNull IdeaModule gradleModule, @NotNull ProjectData projectData) {
+    return nextResolver.createModule(gradleModule, projectData);
+  }
+
+  @Override
+  public void populateModuleExtraModels(@NotNull IdeaModule gradleModule, @NotNull DataNode<ModuleData> ideModule) {
+    nextResolver.populateModuleExtraModels(gradleModule, ideModule);
+  }
+
+  @Override
+  public void populateModuleContentRoots(@NotNull IdeaModule gradleModule,
+                                         @NotNull DataNode<ModuleData> ideModule) {
+    nextResolver.populateModuleContentRoots(gradleModule, ideModule);
+  }
+
+
+  @Override
+  public void populateModuleCompileOutputSettings(@NotNull IdeaModule gradleModule,
+                                                  @NotNull DataNode<ModuleData> ideModule) {
+    nextResolver.populateModuleCompileOutputSettings(gradleModule, ideModule);
+  }
+
+  @Override
+  public void populateModuleDependencies(@NotNull IdeaModule gradleModule,
+                                         @NotNull DataNode<ModuleData> ideModule,
+                                         @NotNull DataNode<ProjectData> ideProject) {
+    nextResolver.populateModuleDependencies(gradleModule, ideModule, ideProject);
+  }
+
+  @NotNull
+  @Override
+  public Collection<TaskData> populateModuleTasks(@NotNull IdeaModule gradleModule,
+                                                  @NotNull DataNode<ModuleData> ideModule,
+                                                  @NotNull DataNode<ProjectData> ideProject)
+    throws IllegalArgumentException, IllegalStateException {
+    return nextResolver.populateModuleTasks(gradleModule, ideModule, ideProject);
+  }
+
+  @NotNull
+  @Override
+  public Collection<TaskData> filterRootProjectTasks(@NotNull List<TaskData> allTasks) {
+    return nextResolver.filterRootProjectTasks(allTasks);
+  }
+
+  @NotNull
+  @Override
+  public Set<Class> getExtraProjectModelClasses() {
+    return Collections.emptySet();
+  }
+
+  @NotNull
+  @Override
+  public List<KeyValue<String, String>> getExtraJvmArgs() {
+    return Collections.emptyList();
+  }
+
+  @NotNull
+  @Override
+  public ExternalSystemException getUserFriendlyError(@NotNull Throwable error,
+                                                      @NotNull String projectPath,
+                                                      @Nullable String buildFilePath) {
+    return nextResolver.getUserFriendlyError(error, projectPath, buildFilePath);
+  }
+
+  @Override
+  public void enhanceRemoteProcessing(@NotNull SimpleJavaParameters parameters) throws ExecutionException {
+  }
+
+  @Override
+  public void enhanceLocalProcessing(@NotNull List<URL> urls) {
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
index 9ede224..1738364 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
@@ -127,11 +127,15 @@
     return new ModuleData(GradleConstants.SYSTEM_ID,
                           StdModuleTypes.JAVA.getId(),
                           moduleName,
-                          projectData.getIdeProjectFileDirectoryPath(),
+                          moduleConfigPath,
                           moduleConfigPath);
   }
 
   @Override
+  public void populateModuleExtraModels(@NotNull IdeaModule gradleModule, @NotNull DataNode<ModuleData> ideModule) {
+  }
+
+  @Override
   public void populateModuleContentRoots(@NotNull IdeaModule gradleModule,
                                          @NotNull DataNode<ModuleData> ideModule) {
     DomainObjectSet<? extends IdeaContentRoot> contentRoots = gradleModule.getContentRoots();
@@ -139,13 +143,11 @@
       return;
     }
     for (IdeaContentRoot gradleContentRoot : contentRoots) {
-      if (gradleContentRoot == null) {
-        continue;
-      }
+      if (gradleContentRoot == null) continue;
+
       File rootDirectory = gradleContentRoot.getRootDirectory();
-      if (rootDirectory == null) {
-        continue;
-      }
+      if (rootDirectory == null) continue;
+
       ContentRootData ideContentRoot = new ContentRootData(GradleConstants.SYSTEM_ID, rootDirectory.getAbsolutePath());
       ideModule.getData().setModuleFileDirectoryPath(ideContentRoot.getRootPath());
       populateContentRoot(ideContentRoot, ExternalSystemSourceType.SOURCE, gradleContentRoot.getSourceDirectories());
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java
index 8c01c62..77d2e46 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java
@@ -16,6 +16,7 @@
 package org.jetbrains.plugins.gradle.service.project;
 
 import com.intellij.execution.configurations.CommandLineTokenizer;
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.externalSystem.model.ExternalSystemException;
 import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
 import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationEvent;
@@ -24,6 +25,7 @@
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.ArrayUtilRt;
 import com.intellij.util.Function;
+import com.intellij.util.PathUtil;
 import com.intellij.util.SystemProperties;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.ContainerUtilRt;
@@ -42,6 +44,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.reflect.Field;
 import java.util.List;
@@ -53,6 +56,7 @@
  */
 public class GradleExecutionHelper {
 
+  private static final Logger LOG = Logger.getInstance(GradleExecutionHelper.class);
 
   @SuppressWarnings("MethodMayBeStatic")
   @NotNull
@@ -61,8 +65,7 @@
                                              @Nullable GradleExecutionSettings settings,
                                              @NotNull ProjectConnection connection,
                                              @NotNull ExternalSystemTaskNotificationListener listener,
-                                             @NotNull List<String> extraJvmArgs)
-  {
+                                             @NotNull List<String> extraJvmArgs) {
     ModelBuilder<T> result = connection.model(modelType);
     prepare(result, id, settings, listener, extraJvmArgs, connection);
     return result;
@@ -74,8 +77,7 @@
                                         @NotNull ProjectConnection connection,
                                         @Nullable GradleExecutionSettings settings,
                                         @NotNull ExternalSystemTaskNotificationListener listener,
-                                        @Nullable final String vmOptions)
-  {
+                                        @Nullable final String vmOptions) {
     BuildLauncher result = connection.newBuild();
     List<String> extraJvmArgs = vmOptions == null ? ContainerUtil.<String>emptyList() : ContainerUtil.newArrayList(vmOptions.trim());
     prepare(result, id, settings, listener, extraJvmArgs, connection);
@@ -90,8 +92,7 @@
                                         @NotNull ExternalSystemTaskNotificationListener listener,
                                         @Nullable final String vmOptions,
                                         @NotNull final OutputStream standardOutput,
-                                        @NotNull final OutputStream standardError)
-  {
+                                        @NotNull final OutputStream standardError) {
     BuildLauncher result = connection.newBuild();
     List<String> extraJvmArgs = vmOptions == null ? ContainerUtil.<String>emptyList() : ContainerUtil.newArrayList(vmOptions.trim());
     prepare(result, id, settings, listener, extraJvmArgs, connection, standardOutput, standardError);
@@ -118,8 +119,7 @@
                              @NotNull List<String> extraJvmArgs,
                              @NotNull ProjectConnection connection,
                              @NotNull final OutputStream standardOutput,
-                             @NotNull final OutputStream standardError)
-  {
+                             @NotNull final OutputStream standardError) {
     if (settings == null) {
       return;
     }
@@ -129,7 +129,7 @@
     String vmOptions = settings.getDaemonVmOptions();
     if (!StringUtil.isEmpty(vmOptions)) {
       CommandLineTokenizer tokenizer = new CommandLineTokenizer(vmOptions);
-      while(tokenizer.hasMoreTokens()) {
+      while (tokenizer.hasMoreTokens()) {
         String vmOption = tokenizer.nextToken();
         if (!StringUtil.isEmpty(vmOption)) {
           jvmArgs.add(vmOption);
@@ -140,8 +140,9 @@
     jvmArgs.addAll(extraJvmArgs);
 
     if (!jvmArgs.isEmpty()) {
-      List<String> args = connection.getModel(BuildEnvironment.class).getJava().getJvmArguments();
-      List<String> merged = mergeJvmArgs(args, jvmArgs);
+      BuildEnvironment buildEnvironment = getBuildEnvironment(connection);
+      List<String> merged =
+        buildEnvironment != null ? mergeJvmArgs(buildEnvironment.getJava().getJvmArguments(), jvmArgs) : jvmArgs;
       operation.setJvmArguments(ArrayUtilRt.toStringArray(merged));
     }
 
@@ -167,14 +168,15 @@
     if (projectPathFile.isFile() && projectPath.endsWith(GradleConstants.EXTENSION)
         && projectPathFile.getParent() != null) {
       projectDir = projectPathFile.getParent();
-    } else {
+    }
+    else {
       projectDir = projectPath;
     }
 
     // This is a workaround to get right base dir in case of 'PROJECT' setting used in case custom wrapper property file location
     // see org.gradle.wrapper.PathAssembler#getBaseDir for details
     String userDir = null;
-    if(settings != null && settings.getDistributionType() == DistributionType.WRAPPED) {
+    if (settings != null && settings.getDistributionType() == DistributionType.WRAPPED) {
       try {
         userDir = System.getProperty("user.dir");
         System.setProperty("user.dir", projectDir);
@@ -227,7 +229,9 @@
           "gradle.taskGraph.afterTask { Task task ->",
           "    if (task instanceof Wrapper) {",
           "        def wrapperPropertyFileLocation = task.jarFile.getCanonicalPath() - '.jar' + '.properties'",
-          "        new File('" + StringUtil.escapeBackSlashes(wrapperPropertyFileLocation.getCanonicalPath()) + "').write wrapperPropertyFileLocation",
+          "        new File('" +
+          StringUtil.escapeBackSlashes(wrapperPropertyFileLocation.getCanonicalPath()) +
+          "').write wrapperPropertyFileLocation",
           "}}",
         };
         FileUtil.writeToFile(tempFile, StringUtil.join(lines, SystemProperties.getLineSeparator()));
@@ -263,21 +267,20 @@
   /**
    * Allows to retrieve gradle api connection to use for the given project.
    *
-   * @param projectPath            target project path
-   * @param settings               execution settings to use
+   * @param projectPath target project path
+   * @param settings    execution settings to use
    * @return connection to use
    * @throws IllegalStateException if it's not possible to create the connection
    */
   @NotNull
   private static ProjectConnection getConnection(@NotNull String projectPath,
                                                  @Nullable GradleExecutionSettings settings)
-    throws IllegalStateException
-  {
+    throws IllegalStateException {
     File projectDir = new File(projectPath);
     GradleConnector connector = GradleConnector.newConnector();
     int ttl = -1;
 
-    if(settings != null) {
+    if (settings != null) {
       //noinspection EnumSwitchStatementWhichMissesCases
       switch (settings.getDistributionType()) {
         case LOCAL:
@@ -357,4 +360,35 @@
     field.set(obj, fieldValue);
     field.setAccessible(isAccessible);
   }
+
+  @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
+  public static void setInitScript(LongRunningOperation longRunningOperation) {
+    try {
+      InputStream stream = GradleProjectResolver.class.getResourceAsStream("/org/jetbrains/plugins/gradle/model/internal/init.gradle");
+      if (stream == null) return;
+
+      String jarPath = PathUtil.getCanonicalPath(PathUtil.getJarPathForClass(GradleProjectResolver.class));
+      String s = FileUtil.loadTextAndClose(stream).replace("${JAR_PATH}", jarPath);
+
+      final File tempFile = FileUtil.createTempFile("ijinit", '.' + GradleConstants.EXTENSION, true);
+      FileUtil.writeToFile(tempFile, s);
+
+      String[] buildExecutorArgs = new String[]{"--init-script", tempFile.getAbsolutePath()};
+      longRunningOperation.withArguments(buildExecutorArgs);
+    }
+    catch (Exception e) {
+      LOG.warn("Can't use IJ gradle init script", e);
+    }
+  }
+
+  @Nullable
+  private static BuildEnvironment getBuildEnvironment(@NotNull ProjectConnection connection) {
+    try {
+      return connection.getModel(BuildEnvironment.class);
+    }
+    catch (Exception e) {
+      LOG.warn("can not get BuildEnvironment model", e);
+      return null;
+    }
+  }
 }
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
index 34f044c..4da7f14 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
@@ -49,6 +49,7 @@
 import org.jetbrains.plugins.gradle.settings.ClassHolder;
 import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings;
 import org.jetbrains.plugins.gradle.util.GradleConstants;
+import org.jetbrains.plugins.gradle.util.GradleEnvironment;
 
 import java.util.*;
 
@@ -152,6 +153,11 @@
       resolverCtx.getSettings(), resolverCtx.getListener(),
       parametersList.getParameters(), resolverCtx.getConnection());
 
+    // TODO [vlad] remove the check
+    if (GradleEnvironment.USE_ENHANCED_TOOLING_API) {
+      GradleExecutionHelper.setInitScript(buildActionExecutor);
+    }
+
     ProjectImportAction.AllModels allModels;
     try {
       allModels = buildActionExecutor.run();
@@ -220,6 +226,7 @@
     for (final Pair<DataNode<ModuleData>, IdeaModule> pair : moduleMap.values()) {
       final DataNode<ModuleData> moduleDataNode = pair.first;
       final IdeaModule ideaModule = pair.second;
+      projectResolverChain.populateModuleExtraModels(ideaModule, moduleDataNode);
       projectResolverChain.populateModuleContentRoots(ideaModule, moduleDataNode);
       projectResolverChain.populateModuleCompileOutputSettings(ideaModule, moduleDataNode);
       projectResolverChain.populateModuleDependencies(ideaModule, moduleDataNode, projectDataNode);
@@ -251,7 +258,8 @@
   private static BuildEnvironment getBuildEnvironment(@NotNull ProjectResolverContext resolverCtx) {
     try {
       return resolverCtx.getConnection().getModel(BuildEnvironment.class);
-    } catch (Exception e) {
+    }
+    catch (Exception e) {
       return null;
     }
   }
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java
index 377a128..b663dbc 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java
@@ -67,6 +67,13 @@
   ModuleData createModule(@NotNull IdeaModule gradleModule, @NotNull ProjectData projectData);
 
   /**
+   * Populates extra models of the given ide module on the basis of the information provided by {@link org.jetbrains.plugins.gradle.model.ModelBuilderService}
+   *
+   * @param ideModule corresponding module from intellij gradle plugin domain
+   */
+  void populateModuleExtraModels(@NotNull IdeaModule gradleModule, @NotNull DataNode<ModuleData> ideModule);
+
+  /**
    * Populates {@link com.intellij.openapi.externalSystem.model.ProjectKeys#CONTENT_ROOT) content roots} of the given ide module on the basis of the information
    * contained at the given gradle module.
    *
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java
index 1279557..ef446f1 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java
@@ -40,6 +40,7 @@
   @NonNls public static final String GRADLE_API_DEFAULT_TASK = "org.gradle.api.DefaultTask";
   @NonNls public static final String GRADLE_API_TASKS_DELETE = "org.gradle.api.tasks.Delete";
   @NonNls public static final String GRADLE_API_TASKS_BUNDLING_JAR = "org.gradle.api.tasks.bundling.Jar";
+  @NonNls public static final String GRADLE_API_TASKS_BUNDLING_WAR = "org.gradle.api.tasks.bundling.War";
   @NonNls public static final String GRADLE_API_TASKS_COMPILE_JAVA_COMPILE = "org.gradle.api.tasks.compile.JavaCompile";
   @NonNls public static final String GRADLE_API_TASKS_WRAPPER_WRAPPER = "org.gradle.api.tasks.wrapper.Wrapper";
   @NonNls public static final String GRADLE_API_TASKS_JAVADOC_JAVADOC = "org.gradle.api.tasks.javadoc.Javadoc";
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java
index c64b19e..84ab010 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java
@@ -56,6 +56,7 @@
     new Pair<String, String>("buildNeeded", GRADLE_API_DEFAULT_TASK),
     new Pair<String, String>("clean", GRADLE_API_TASKS_DELETE),
     new Pair<String, String>("jar", GRADLE_API_TASKS_BUNDLING_JAR),
+    new Pair<String, String>("war", GRADLE_API_TASKS_BUNDLING_WAR),
     new Pair<String, String>("classes", GRADLE_API_DEFAULT_TASK),
     new Pair<String, String>("compileJava", GRADLE_API_TASKS_COMPILE_JAVA_COMPILE),
     new Pair<String, String>("compileTestJava", GRADLE_API_DEFAULT_TASK),
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleEnvironment.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleEnvironment.java
index e511485..0a91825 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleEnvironment.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleEnvironment.java
@@ -10,6 +10,7 @@
 public class GradleEnvironment {
 
   @NonNls public static final boolean DEBUG_GRADLE_HOME_PROCESSING = Boolean.getBoolean("gradle.debug.home.processing");
+  @NonNls public static final boolean USE_ENHANCED_TOOLING_API = Boolean.getBoolean("gradle.use.enhanced.tooling.api");
 
   private GradleEnvironment() {
   }
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index d835e45..d9f86bf 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -413,7 +413,8 @@
     <langCodeStyleSettingsProvider implementation="org.jetbrains.plugins.groovy.codeStyle.GroovyLanguageCodeStyleSettingsProvider"/>
     <codeStyleSettingsProvider implementation="org.jetbrains.plugins.groovy.codeStyle.GroovyCodeStyleSettingsProvider"/>
 
-    <typeHierarchyProvider language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.GroovyTypeHierarchyProvider"/>
+    <typeHierarchyProvider language="Groovy" implementationClass="org.jetbrains.plugins.groovy.hierarchy.type.GroovyTypeHierarchyProvider"/>
+    <callHierarchyProvider language="Groovy" implementationClass="org.jetbrains.plugins.groovy.hierarchy.call.GrCallHierarchyProvider"/>
 
     <lang.unwrapDescriptor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.unwrap.GroovyUnwrapDescriptor"/>
 
@@ -985,14 +986,6 @@
                      displayName="Method parameter naming convention"
                      groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
                      implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyParameterNamingConventionInspection"/>
-    <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyGetterCallCanBePropertyAccess"
-                     displayName="Getter call can be property access"
-                     groupName="GPath inspections" enabledByDefault="false" level="WARNING"
-                     implementationClass="org.jetbrains.plugins.groovy.codeInspection.gpath.GroovyGetterCallCanBePropertyAccessInspection"/>
-    <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySetterCallCanBePropertyAccess"
-                     displayName="Setter call can be property access"
-                     groupName="GPath inspections" enabledByDefault="false" level="WARNING"
-                     implementationClass="org.jetbrains.plugins.groovy.codeInspection.gpath.GroovySetterCallCanBePropertyAccessInspection"/>
     <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMapGetCanBeKeyedAccess"
                      displayName="Call to Map.get can be keyed access"
                      groupName="GPath inspections" enabledByDefault="false" level="WARNING"
@@ -1458,6 +1451,7 @@
     <refactoring.pullUpHelperFactory language="Groovy"
                                      implementationClass="org.jetbrains.plugins.groovy.refactoring.memberPullUp.GrPullUpHelperFactory"/>
     <classTypePointerFactory implementation="org.jetbrains.plugins.groovy.lang.psi.impl.smartPointers.GrClassReferenceTypePointerFactory"/>
+    <hierarchy.referenceProcessor implementation="org.jetbrains.plugins.groovy.hierarchy.call.GrCallReferenceProcessor"/>
   </extensions>
 
   <extensions defaultExtensionNs="com.intellij.debugger">
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyGetterCallCanBePropertyAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyGetterCallCanBePropertyAccessInspection.java
deleted file mode 100644
index 2345790..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyGetterCallCanBePropertyAccessInspection.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2007-2008 Dave Griffith
- *
- * 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.
- */
-package org.jetbrains.plugins.groovy.codeInspection.gpath;
-
-import com.intellij.codeInspection.ProblemDescriptor;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.PsiElement;
-import com.intellij.util.IncorrectOperationException;
-import org.jetbrains.annotations.Nls;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
-import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
-import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
-import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
-import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
-
-public class GroovyGetterCallCanBePropertyAccessInspection extends BaseInspection {
-
-  @Nls
-  @NotNull
-  public String getGroupDisplayName() {
-    return GPATH;
-  }
-
-  @Nls
-  @NotNull
-  public String getDisplayName() {
-    return "Getter call can be property access";
-  }
-
-  @Nullable
-  protected String buildErrorString(Object... args) {
-    return "Call to '#ref' can be property access #loc";
-  }
-
-  public BaseInspectionVisitor buildVisitor() {
-    return new Visitor();
-  }
-
-  public GroovyFix buildFix(PsiElement location) {
-    return new ReplaceWithPropertyAccessFix();
-  }
-
-  private static class ReplaceWithPropertyAccessFix extends GroovyFix {
-
-    @NotNull
-    public String getName() {
-      return "Replace with property access";
-    }
-
-    public void doFix(Project project, ProblemDescriptor descriptor)
-        throws IncorrectOperationException {
-      final PsiElement referenceName = descriptor.getPsiElement();
-      final String getterName = referenceName.getText();
-      final String propertyName = Character.toLowerCase(getterName.charAt(3)) + getterName.substring(4);
-      final GrReferenceExpression invokedExpression = (GrReferenceExpression) referenceName.getParent();
-      final GrMethodCallExpression callExpression = (GrMethodCallExpression) invokedExpression.getParent();
-      replaceExpression(callExpression, invokedExpression.getQualifierExpression().getText() + '.' + propertyName);
-    }
-  }
-
-  private static class Visitor extends BaseInspectionVisitor {
-    @NonNls private static final String GET_PREFIX = "get";
-
-    public void visitMethodCallExpression(GrMethodCallExpression grMethodCallExpression) {
-      super.visitMethodCallExpression(grMethodCallExpression);
-      final GrArgumentList args = grMethodCallExpression.getArgumentList();
-      if (args == null) {
-        return;
-      }
-      if (PsiImplUtil.hasExpressionArguments(args)) {
-        return;
-      }
-      if (PsiImplUtil.hasNamedArguments(args)) {
-        return;
-      }
-      final GrExpression methodExpression = grMethodCallExpression.getInvokedExpression();
-      if (!(methodExpression instanceof GrReferenceExpression)) {
-        return;
-      }
-      final GrReferenceExpression referenceExpression = (GrReferenceExpression)methodExpression;
-      final String name = referenceExpression.getReferenceName();
-      if (name == null || !name.startsWith(GET_PREFIX)) {
-        return;
-      }
-      if (name.equals(GET_PREFIX)) {
-        return;
-      }
-      String tail = StringUtil.trimStart(name, GET_PREFIX);
-      // If doesn't conform to getter's convention
-      if (!tail.equals(StringUtil.capitalize(tail))) {
-        return;
-      }
-      final GrExpression qualifier = referenceExpression.getQualifierExpression();
-      if (qualifier == null) return;
-      if (PsiUtil.isThisOrSuperRef(qualifier)) return;
-      registerMethodCallError(grMethodCallExpression);
-    }
-  }
-}
\ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovySetterCallCanBePropertyAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovySetterCallCanBePropertyAccessInspection.java
deleted file mode 100644
index c8ffcde..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovySetterCallCanBePropertyAccessInspection.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright 2007-2008 Dave Griffith
- *
- * 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.
- */
-package org.jetbrains.plugins.groovy.codeInspection.gpath;
-
-import com.intellij.codeInspection.ProblemDescriptor;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.PsiElement;
-import com.intellij.util.IncorrectOperationException;
-import org.jetbrains.annotations.Nls;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
-import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
-import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
-import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
-import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
-
-public class GroovySetterCallCanBePropertyAccessInspection extends BaseInspection {
-  private final ReplaceWithPropertyAccessFix fix = new ReplaceWithPropertyAccessFix();
-
-  @Nls
-  @NotNull
-  public String getGroupDisplayName() {
-    return GPATH;
-  }
-
-  @Nls
-  @NotNull
-  public String getDisplayName() {
-    return "Setter call can be property access";
-  }
-
-  @Nullable
-  protected String buildErrorString(Object... args) {
-    return "Call to '#ref' can be property access #loc";
-  }
-
-  public BaseInspectionVisitor buildVisitor() {
-    return new Visitor();
-  }
-
-  public GroovyFix buildFix(PsiElement location) {
-    return fix;
-  }
-
-  private static class
-      ReplaceWithPropertyAccessFix extends GroovyFix {
-    @NotNull
-    public String getName() {
-      return "Replace with property access";
-    }
-
-    public void doFix(Project project, ProblemDescriptor descriptor)
-        throws IncorrectOperationException {
-      final PsiElement referenceName = descriptor.getPsiElement();
-      final String setter = referenceName.getText();
-      final String propertyName = Character.toLowerCase(setter.charAt(3)) + setter.substring(4);
-      final GrReferenceExpression invokedExpression = (GrReferenceExpression) referenceName.getParent();
-      final GrMethodCallExpression callExpression = (GrMethodCallExpression) invokedExpression.getParent();
-      final GrArgumentList args = callExpression.getArgumentList();
-      assert args != null;
-      final GrExpression arg = args.getExpressionArguments()[0];
-      replaceExpression(callExpression, invokedExpression.getQualifierExpression().getText() + '.' + propertyName + " = " + arg.getText());
-    }
-  }
-
-  private static class Visitor extends BaseInspectionVisitor {
-    @NonNls private static final String SET_PREFIX = "set";
-
-    public void visitMethodCallExpression(GrMethodCallExpression grMethodCallExpression) {
-      super.visitMethodCallExpression(grMethodCallExpression);
-      final GrArgumentList args = grMethodCallExpression.getArgumentList();
-      if (args == null) {
-        return;
-      }
-      if (args.getExpressionArguments().length != 1) {
-        return;
-      }
-      if (PsiImplUtil.hasNamedArguments(args)) {
-        return;
-      }
-      final GrExpression methodExpression = grMethodCallExpression.getInvokedExpression();
-      if (!(methodExpression instanceof GrReferenceExpression)) {
-        return;
-      }
-      final GrReferenceExpression referenceExpression = (GrReferenceExpression) methodExpression;
-      final String name = referenceExpression.getReferenceName();
-      if (name == null || !name.startsWith(SET_PREFIX)) {
-        return;
-      }
-      if (SET_PREFIX.equals(name)) {
-        return;
-      }
-      String tail = StringUtil.trimStart(name, SET_PREFIX);
-      // If doesn't conform to getter's convention
-      if (!tail.equals(StringUtil.capitalize(tail))) {
-        return;
-      }
-      final GrExpression qualifier = referenceExpression.getQualifierExpression();
-      if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
-        return;
-      }
-      registerMethodCallError(grMethodCallExpression);
-    }
-  }
-}
\ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/style/JavaStylePropertiesInvocationInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/style/JavaStylePropertiesInvocationInspection.java
index f0152ec..48c98b1 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/style/JavaStylePropertiesInvocationInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/style/JavaStylePropertiesInvocationInspection.java
@@ -1,8 +1,24 @@
+/*
+ * 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.
+ */
 package org.jetbrains.plugins.groovy.codeInspection.style;
 
 import com.intellij.codeInspection.LocalQuickFix;
 import com.intellij.codeInspection.ProblemHighlightType;
 import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
 import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
 import org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle;
@@ -14,6 +30,7 @@
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
 
 public class JavaStylePropertiesInvocationInspection extends BaseInspection {
+  @NotNull
   @Override
   protected BaseInspectionVisitor buildVisitor() {
     return new BaseInspectionVisitor() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/JavaStylePropertiesUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/JavaStylePropertiesUtil.java
index 8715a5c..0e54ffd 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/JavaStylePropertiesUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/JavaStylePropertiesUtil.java
@@ -20,6 +20,7 @@
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiManager;
 import com.intellij.psi.PsiMethod;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
@@ -132,7 +133,7 @@
     return false;
   }
 
-  private static boolean isGetterInvocation(GrMethodCall call) {
+  private static boolean isGetterInvocation(@NotNull GrMethodCall call) {
     GrExpression expr = call.getInvokedExpression();
     if (!(expr instanceof GrReferenceExpression)) return false;
 
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyAwareModuleBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyAwareModuleBuilder.java
index 8cece08..978d7c7 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyAwareModuleBuilder.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyAwareModuleBuilder.java
@@ -18,8 +18,6 @@
 import com.intellij.ide.util.projectWizard.JavaModuleBuilder;
 import com.intellij.ide.util.projectWizard.ModuleWizardStep;
 import com.intellij.ide.util.projectWizard.SettingsStep;
-import com.intellij.ide.util.projectWizard.WizardContext;
-import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
 import icons.JetgroovyIcons;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -49,11 +47,6 @@
     myBigIcon = bigIcon;
   }
 
-  @Override
-  public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) {
-    return new ModuleWizardStep[]{new GroovySdkForNewModuleWizardStep(this, wizardContext, getFramework(), null)};
-  }
-
   @Nullable
   @Override
   public ModuleWizardStep modifySettingsStep(@NotNull SettingsStep settingsStep) {
@@ -90,6 +83,7 @@
     return "Groovy";
   }
 
+  @Nullable
   protected MvcFramework getFramework() {
     return null;
   }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryDescription.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryDescription.java
index f375045..76205a8 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryDescription.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryDescription.java
@@ -126,7 +126,7 @@
     final String sdkVersion = provider.getSDKVersion(path);
     if (AbstractConfigUtils.UNDEFINED_VERSION.equals(sdkVersion)) {
       Messages.showErrorDialog(parentComponent,
-                               "Looks like " + myFrameworkName + " distribution in specified path is broken. Cannot determinate version.",
+                               "Looks like " + myFrameworkName + " distribution in specified path is broken. Cannot determine version.",
                                "Failed to Create Library");
       return null;
     }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/hierarchy/call/GrCallHierarchyProvider.java
similarity index 68%
copy from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java
copy to plugins/groovy/src/org/jetbrains/plugins/groovy/hierarchy/call/GrCallHierarchyProvider.java
index bed999e..f4caaee 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/hierarchy/call/GrCallHierarchyProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -13,12 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jetbrains.plugins.groovy.lang;
+package org.jetbrains.plugins.groovy.hierarchy.call;
 
-import com.intellij.ide.hierarchy.type.JavaTypeHierarchyProvider;
+import com.intellij.ide.hierarchy.call.JavaCallHierarchyProvider;
 
 /**
- * @author peter
+ * Created by Max Medvedev on 10/5/13
  */
-public class GroovyTypeHierarchyProvider extends JavaTypeHierarchyProvider{
+public class GrCallHierarchyProvider extends JavaCallHierarchyProvider {
 }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/hierarchy/call/GrCallReferenceProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/hierarchy/call/GrCallReferenceProcessor.java
new file mode 100644
index 0000000..2b60ae7
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/hierarchy/call/GrCallReferenceProcessor.java
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.groovy.hierarchy.call;
+
+import com.intellij.ide.hierarchy.call.CallHierarchyNodeDescriptor;
+import com.intellij.ide.hierarchy.call.CallReferenceProcessor;
+import com.intellij.ide.hierarchy.call.JavaCallHierarchyData;
+import com.intellij.ide.util.treeView.NodeDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Created by Max Medvedev on 10/5/13
+ */
+public class GrCallReferenceProcessor implements CallReferenceProcessor {
+  @Override
+  public boolean process(@NotNull PsiReference reference, @NotNull JavaCallHierarchyData data) {
+    PsiClass originalClass = data.getOriginalClass();
+    PsiMethod method = data.getMethod();
+    Set<PsiMethod> methodsToFind = data.getMethodsToFind();
+    PsiMethod methodToFind = data.getMethodToFind();
+    PsiClassType originalType = data.getOriginalType();
+    Map<PsiMember, NodeDescriptor> methodToDescriptorMap = data.getResultMap();
+    Project project = data.getProject();
+
+    if (reference instanceof GrReferenceExpression) {
+      final GrExpression qualifier = ((GrReferenceExpression)reference).getQualifierExpression();
+      if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(qualifier)) { // filter super.foo() call inside foo() and similar cases (bug 8411)
+        assert qualifier != null;
+        final PsiClass superClass = PsiUtil.resolveClassInType(qualifier.getType());
+        if (originalClass == null || originalClass.isInheritor(superClass, true)) {
+          return true;
+        }
+      }
+      if (qualifier != null && !methodToFind.hasModifierProperty(PsiModifier.STATIC)) {
+        final PsiType qualifierType = qualifier.getType();
+        if (qualifierType instanceof PsiClassType && !TypeConversionUtil.isAssignable(qualifierType, originalType) && methodToFind != method) {
+          final PsiClass psiClass = ((PsiClassType)qualifierType).resolve();
+          if (psiClass != null) {
+            final PsiMethod callee = psiClass.findMethodBySignature(methodToFind, true);
+            if (callee != null && !methodsToFind.contains(callee)) {
+              // skip sibling methods
+              return true;
+            }
+          }
+        }
+      }
+    }
+    else {
+      if (!(reference instanceof PsiElement)) {
+        return true;
+      }
+
+      final PsiElement parent = ((PsiElement)reference).getParent();
+      if (parent instanceof PsiNewExpression) {
+        if (((PsiNewExpression)parent).getClassReference() != reference) {
+          return true;
+        }
+      }
+      else if (parent instanceof GrAnonymousClassDefinition) {
+        if (((GrAnonymousClassDefinition)parent).getBaseClassReferenceGroovy() != reference) {
+          return true;
+        }
+      }
+      else {
+        return true;
+      }
+    }
+
+    final PsiElement element = reference.getElement();
+    final PsiMember key = CallHierarchyNodeDescriptor.getEnclosingElement(element);
+
+    synchronized (methodToDescriptorMap) {
+      CallHierarchyNodeDescriptor d = (CallHierarchyNodeDescriptor)methodToDescriptorMap.get(key);
+      if (d == null) {
+        d = new CallHierarchyNodeDescriptor(project, (CallHierarchyNodeDescriptor)data.getNodeDescriptor(), element, false, true);
+        methodToDescriptorMap.put(key, d);
+      }
+      else if (!d.hasReference(reference)) {
+        d.incrementUsageCount();
+      }
+      d.addReference(reference);
+    }
+    return true;
+  }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/hierarchy/type/GroovyTypeHierarchyProvider.java
similarity index 88%
rename from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java
rename to plugins/groovy/src/org/jetbrains/plugins/groovy/hierarchy/type/GroovyTypeHierarchyProvider.java
index bed999e..da42de7 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/hierarchy/type/GroovyTypeHierarchyProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jetbrains.plugins.groovy.lang;
+package org.jetbrains.plugins.groovy.hierarchy.type;
 
 import com.intellij.ide.hierarchy.type.JavaTypeHierarchyProvider;
 
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkForNewModuleWizardStep.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkForNewModuleWizardStep.java
index 3551692..6ed51ed 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkForNewModuleWizardStep.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkForNewModuleWizardStep.java
@@ -33,13 +33,13 @@
 
   public GroovySdkForNewModuleWizardStep(ModuleBuilder moduleBuilder,
                                          WizardContext wizardContext,
-                                         final MvcFramework framework,
+                                         @Nullable MvcFramework framework,
                                          SettingsStep settingsStep) {
     super(framework, wizardContext, moduleBuilder.getContentEntryPath());
     moduleBuilder.addModuleConfigurationUpdater(createModuleConfigurationUpdater());
     if (settingsStep != null) {
       myJavaStep = JavaModuleType.getModuleType().modifySettingsStep(settingsStep, moduleBuilder);
-      settingsStep.addSettingsField("\u001BGroovy library:", getPanel().getSimplePanel());
+      settingsStep.addSettingsField("\u001B" + (framework == null ? "Groovy" : framework.getDisplayName()) + " library:", getPanel().getSimplePanel());
     }
   }
 
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleBuilder.java
index ea0dae6..399a99d 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleBuilder.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleBuilder.java
@@ -15,13 +15,6 @@
  */
 package org.jetbrains.plugins.groovy.mvc;
 
-import com.intellij.ide.util.projectWizard.ModuleWizardStep;
-import com.intellij.ide.util.projectWizard.SdkSettingsStep;
-import com.intellij.ide.util.projectWizard.SettingsStep;
-import com.intellij.openapi.projectRoots.SdkTypeId;
-import com.intellij.openapi.util.Condition;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.config.GroovyAwareModuleBuilder;
 
 import javax.swing.*;
@@ -42,15 +35,4 @@
   protected MvcFramework getFramework() {
     return myFramework;
   }
-
-  @Nullable
-  @Override
-  public ModuleWizardStep modifySettingsStep(@NotNull SettingsStep settingsStep) {
-    return new SdkSettingsStep(settingsStep, this, new Condition<SdkTypeId>() {
-          @Override
-          public boolean value(SdkTypeId sdkType) {
-            return isSuitableSdkType(sdkType);
-          }
-        });
-  }
 }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcProjectWithoutLibraryNotificator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcProjectWithoutLibraryNotificator.java
index f5ba037..7445188 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcProjectWithoutLibraryNotificator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcProjectWithoutLibraryNotificator.java
@@ -27,38 +27,43 @@
 
   @Override
   public void runActivity(@NotNull final Project project) {
-    AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
+    ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+      @Override
+      public void run() {
+        AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
 
-    try {
-      if (JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_LANG_OBJECT, GlobalSearchScope.allScope(project)) == null) {
-        return; // If indexes is corrupted JavaPsiFacade.findClass() can't find classes during StartupActivity (may be it's a bug).
-                // So we can't determine whether exists Grails library or not.
+        try {
+          if (JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_LANG_OBJECT, GlobalSearchScope.allScope(project)) == null) {
+            return; // If indexes is corrupted JavaPsiFacade.findClass() can't find classes during StartupActivity (may be it's a bug).
+                    // So we can't determine whether exists Grails library or not.
+          }
+
+          Pair<Module, MvcFramework> pair = findModuleWithoutLibrary(project);
+
+          if (pair != null) {
+            final MvcFramework framework = pair.second;
+            final Module module = pair.first;
+
+            new Notification(framework.getFrameworkName() + ".Configure",
+                             framework.getFrameworkName() + " SDK not found.",
+                             "<html><body>Module '" +
+                             module.getName() +
+                             "' has no " +
+                             framework.getFrameworkName() +
+                             " SDK. <a href='create'>Configure SDK</a></body></html>", NotificationType.INFORMATION,
+                             new NotificationListener.Adapter() {
+                               @Override
+                               protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) {
+                                 MvcConfigureNotification.configure(framework, module);
+                               }
+                             }).notify(project);
+          }
+        }
+        finally {
+          accessToken.finish();
+        }
       }
-
-      Pair<Module, MvcFramework> pair = findModuleWithoutLibrary(project);
-
-      if (pair != null) {
-        final MvcFramework framework = pair.second;
-        final Module module = pair.first;
-
-        new Notification(framework.getFrameworkName() + ".Configure",
-                         framework.getFrameworkName() + " SDK not found.",
-                         "<html><body>Module '" +
-                         module.getName() +
-                         "' has no " +
-                         framework.getFrameworkName() +
-                         " SDK. <a href='create'>Configure SDK</a></body></html>", NotificationType.INFORMATION,
-                         new NotificationListener.Adapter() {
-                           @Override
-                           protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) {
-                             MvcConfigureNotification.configure(framework, module);
-                           }
-                         }).notify(project);
-      }
-    }
-    finally {
-      accessToken.finish();
-    }
+    });
   }
 
   @Nullable
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfigurationType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfigurationType.java
index da97279..fef7af5 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfigurationType.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfigurationType.java
@@ -21,9 +21,12 @@
 import com.intellij.execution.configurations.ConfigurationTypeUtil;
 import com.intellij.execution.configurations.RunConfiguration;
 import com.intellij.openapi.project.Project;
+import com.intellij.psi.search.FileTypeIndex;
+import com.intellij.psi.search.GlobalSearchScope;
 import icons.JetgroovyIcons;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.GroovyFileType;
 
 import javax.swing.*;
 
@@ -65,6 +68,11 @@
       super(type);
     }
 
+    @Override
+    public boolean isApplicable(@NotNull Project project) {
+      return FileTypeIndex.containsFileOfType(GroovyFileType.GROOVY_FILE_TYPE, GlobalSearchScope.allScope(project));
+    }
+
     public RunConfiguration createTemplateConfiguration(Project project) {
       return new GroovyScriptRunConfiguration("Groovy Script", project, this);
     }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java
index ec53534..b7872dcc 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java
@@ -24,6 +24,7 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.GroovyFileType;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
 import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
 import org.jetbrains.plugins.groovy.testIntegration.GroovyTestFramework;
 
@@ -65,9 +66,9 @@
 
   @Override
   public boolean isTestMethod(PsiElement element) {
-    if (!(element instanceof PsiMethod)) return false;
+    if (!(element instanceof GrMethod)) return false;
 
-    return GroovyPsiManager.isInheritorCached(((PsiMethod)element).getContainingClass(), SpockUtils.SPEC_CLASS_NAME)
+    return GroovyPsiManager.isInheritorCached(((GrMethod)element).getContainingClass(), SpockUtils.SPEC_CLASS_NAME)
            && JUnitUtil.getTestMethod(element) != null;
   }
 
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/SdkHomeSettings.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/SdkHomeSettings.java
index 2230270..e357762 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/SdkHomeSettings.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/SdkHomeSettings.java
@@ -36,19 +36,22 @@
  */
 public abstract class SdkHomeSettings implements PersistentStateComponent<SdkHomeConfigurable.SdkHomeBean> {
   private final PsiModificationTrackerImpl myTracker;
-  private SdkHomeConfigurable.SdkHomeBean mySdkPath;
+  private SdkHomeConfigurable.SdkHomeBean mySdkHome;
 
   protected SdkHomeSettings(Project project) {
     myTracker = (PsiModificationTrackerImpl)PsiManager.getInstance(project).getModificationTracker();
   }
 
   public SdkHomeConfigurable.SdkHomeBean getState() {
-    return mySdkPath;
+    return mySdkHome;
   }
 
   public void loadState(SdkHomeConfigurable.SdkHomeBean state) {
-    mySdkPath = state;
-    myTracker.incCounter();
+    SdkHomeConfigurable.SdkHomeBean oldState = mySdkHome;
+    mySdkHome = state;
+    if (oldState != null) {
+      myTracker.incCounter();
+    }
   }
 
   @Nullable
@@ -67,7 +70,7 @@
 
   @Nullable
   public VirtualFile getSdkHome() {
-    return calcHome(mySdkPath);
+    return calcHome(mySdkHome);
   }
 
   public List<VirtualFile> getClassRoots() {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/GrFindManagerTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/GrFindManagerTest.java
new file mode 100644
index 0000000..6112a21
--- /dev/null
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/GrFindManagerTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.groovy;
+
+import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase;
+import com.intellij.find.FindManager;
+import com.intellij.find.FindManagerTestUtils;
+import com.intellij.find.FindModel;
+
+public class GrFindManagerTest extends DaemonAnalyzerTestCase {
+  private FindManager myFindManager;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    myFindManager = FindManager.getInstance(myProject);
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    myFindManager = null;
+    super.tearDown();
+  }
+
+  public void testFindInJavaDocs() {
+    FindModel findModel = FindManagerTestUtils.configureFindModel("done");
+    String text = "/** done done done */";
+    FindManagerTestUtils.runFindForwardAndBackward(myFindManager, findModel, text, "groovy");
+  }
+
+  public void testFindInLiteralToSkipQuotes() {
+    FindModel findModel = FindManagerTestUtils.configureFindModel("^done$");
+    findModel.setRegularExpressions(true);
+    findModel.setInStringLiteralsOnly(true);
+    findModel.setInCommentsOnly(false);
+    String text = "def n = \"\"\"done\"\"\"\n def n = /done/\n def n = \"done\"\n def n = \"done2\"";
+    FindManagerTestUtils.runFindForwardAndBackward(myFindManager, findModel, text, "groovy");
+  }
+
+  public void testFindInShellCommentsOfGroovy() {
+    FindModel findModel = FindManagerTestUtils.configureFindModel("done");
+    findModel.setWholeWordsOnly(true);
+    findModel.setInCommentsOnly(true);
+    String text = "#! done done done\n";
+    FindManagerTestUtils.runFindForwardAndBackward(myFindManager, findModel, text, "groovy");
+  }
+}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyFixesTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyFixesTest.groovy
index 4d61175..b5fa168 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyFixesTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyFixesTest.groovy
@@ -1,12 +1,23 @@
 /*
- * Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
- * Use is subject to license terms.
+ * 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.
  */
 package org.jetbrains.plugins.groovy.lang
 import com.intellij.openapi.application.ApplicationManager
 import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
 import org.jetbrains.plugins.groovy.codeInspection.control.GroovyConstantIfStatementInspection
-import org.jetbrains.plugins.groovy.codeInspection.gpath.GroovySetterCallCanBePropertyAccessInspection
+import org.jetbrains.plugins.groovy.codeInspection.style.JavaStylePropertiesInvocationInspection
 import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection
 import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
 /**
@@ -28,7 +39,7 @@
   }
 
   public void testShallowChangeToGroovyStylePropertyAccess() throws Throwable {
-    myFixture.enableInspections new GroovySetterCallCanBePropertyAccessInspection()
+    myFixture.enableInspections new JavaStylePropertiesInvocationInspection()
     myFixture.configureByText "a.groovy", """class GroovyClasss {
   def initializer
   def foo() {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java
index ca3020f..a076635 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java
@@ -125,6 +125,10 @@
   public HgCommandResult executeInCurrentThread(@Nullable final VirtualFile repo, @NotNull final String operation,
                                                 @Nullable final List<String> arguments, @Nullable HgPromptHandler handler) {
     HgCommandResult result = executeInCurrentThread(repo, operation, arguments, handler, false);
+    if (HgErrorUtil.isUnknownEncodingError(result)) {
+      setCharset(Charset.forName("utf8"));
+      result = executeInCurrentThread(repo, operation, arguments, handler, false);
+    }
     if (HgErrorUtil.isAuthorizationError(result)) {
       if (HgErrorUtil.hasAuthorizationInDestinationPath(myDestination)) {
         new HgCommandResultNotifier(myProject)
@@ -195,7 +199,7 @@
     }
     if (HgVcs.HGENCODING == null) {
       cmdLine.add("--encoding");
-      cmdLine.add(myCharset.name());
+      cmdLine.add(HgEncodingUtil.getNameFor(myCharset));
     }
 
     HgCommandResult result;
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
index e8f170b..61e08e1 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
@@ -24,12 +24,12 @@
 import com.intellij.openapi.vcs.VcsKey;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.ArrayUtil;
+import com.intellij.util.Consumer;
 import com.intellij.util.Function;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.vcs.log.*;
 import com.intellij.vcs.log.data.VcsLogBranchFilter;
 import com.intellij.vcs.log.data.VcsLogUserFilter;
-import com.intellij.vcs.log.impl.VcsRefImpl;
 import com.intellij.vcs.log.ui.filter.VcsLogTextFilter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -62,25 +62,21 @@
     myProject = project;
     myRepositoryManager = repositoryManager;
     myRefSorter = new HgRefManager();
-    myVcsObjectsFactory = ServiceManager.getService(VcsLogObjectsFactory.class);
+    myVcsObjectsFactory = ServiceManager.getService(project, VcsLogObjectsFactory.class);
   }
 
   @NotNull
   @Override
   public List<? extends VcsFullCommitDetails> readFirstBlock(@NotNull VirtualFile root,
                                                              boolean ordered, int commitCount) throws VcsException {
-    String[] params = {"--encoding=UTF-8"};
-    if (!ordered) {
-      params = ArrayUtil.append(params, "-r");
-      params = ArrayUtil.append(params, "0:tip");
-    }
+    String[] params = ordered ? ArrayUtil.EMPTY_STRING_ARRAY : new String[]{"-r", "0:tip"};
     return HgHistoryUtil.history(myProject, root, commitCount, params);
   }
 
   @NotNull
   @Override
-  public List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root) throws VcsException {
-    return HgHistoryUtil.readAllHashes(myProject, root);
+  public List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException {
+    return HgHistoryUtil.readAllHashes(myProject, root, userRegistry);
   }
 
   @NotNull
@@ -115,21 +111,21 @@
     Collection<VcsRef> refs = new ArrayList<VcsRef>(branches.size() + bookmarks.size());
 
     for (HgNameWithHashInfo branchInfo : branches) {
-      refs.add(new VcsRefImpl(myVcsObjectsFactory.createHash(branchInfo.getHash()), branchInfo.getName(), HgRefManager.BRANCH, root));
+      refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(branchInfo.getHash()), branchInfo.getName(), HgRefManager.BRANCH, root));
     }
     for (HgNameWithHashInfo bookmarkInfo : bookmarks) {
-      refs.add(new VcsRefImpl(myVcsObjectsFactory.createHash(bookmarkInfo.getHash()), bookmarkInfo.getName(),
+      refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(bookmarkInfo.getHash()), bookmarkInfo.getName(),
                          HgRefManager.BOOKMARK, root));
     }
     String currentRevision = repository.getCurrentRevision();
     if (currentRevision != null) { // null => fresh repository
-      refs.add(new VcsRefImpl(myVcsObjectsFactory.createHash(currentRevision), "HEAD", HgRefManager.HEAD, root));
+      refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(currentRevision), "HEAD", HgRefManager.HEAD, root));
     }
     for (HgNameWithHashInfo tagInfo : tags) {
-      refs.add(new VcsRefImpl(myVcsObjectsFactory.createHash(tagInfo.getHash()), tagInfo.getName(), HgRefManager.TAG, root));
+      refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(tagInfo.getHash()), tagInfo.getName(), HgRefManager.TAG, root));
     }
     for (HgNameWithHashInfo localTagInfo : localTags) {
-      refs.add(new VcsRefImpl(myVcsObjectsFactory.createHash(localTagInfo.getHash()), localTagInfo.getName(),
+      refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(localTagInfo.getHash()), localTagInfo.getName(),
                               HgRefManager.LOCAL_TAG, root));
     }
     return refs;
@@ -206,7 +202,7 @@
     if (userName == null) {
       userName = System.getenv("HGUSER");
     }
-    return userName == null ? null : myVcsObjectsFactory.createUser(userName);
+    return userName == null ? null : myVcsObjectsFactory.createUser(userName, "");
   }
 
   private static String prepareParameter(String paramName, String value) {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
index 740df7d..7b99bda 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
@@ -51,7 +51,7 @@
     super(project, rootDir, parentDisposable);
     myHgDir = rootDir.findChild(HgUtil.DOT_HG);
     assert myHgDir != null : ".hg directory wasn't found under " + rootDir.getPresentableUrl();
-    myReader = new HgRepositoryReader(VfsUtilCore.virtualToIoFile(myHgDir));
+    myReader = new HgRepositoryReader(project, VfsUtilCore.virtualToIoFile(myHgDir));
     myConfig = HgConfig.getInstance(project, rootDir);
     update();
   }
@@ -137,7 +137,7 @@
 
   @Override
   public void update() {
-    HgRepoInfo currentInfo = readRepoInfo(myInfo);
+    HgRepoInfo currentInfo = readRepoInfo();
     // update only if something changed!!!   if update every time - new log will be refreshed every time, too.
     // Then blinking and do not work properly;
     if (!Disposer.isDisposed(getProject()) && currentInfo != null && !currentInfo.equals(myInfo)) {
@@ -153,11 +153,8 @@
   }
 
   @Nullable
-  private HgRepoInfo readRepoInfo(@Nullable HgRepoInfo previousInfo) {
+  private HgRepoInfo readRepoInfo() {
     myIsFresh = myIsFresh && myReader.checkIsFresh();
-    if (isFresh()) {
-      return previousInfo;
-    }
     //in GitRepositoryImpl there are temporary state object for reader fields storing! Todo Check;
     return
       new HgRepoInfo(myReader.readCurrentBranch(), myReader.readCurrentRevision(), myReader.readState(), myReader.readBranches(),
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java
index 39524ad..aaf7fb5 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java
@@ -19,6 +19,7 @@
 import com.intellij.dvcs.repo.Repository;
 import com.intellij.dvcs.repo.RepositoryUtil;
 import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
 import com.intellij.vcs.log.VcsLogObjectsFactory;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -49,7 +50,7 @@
   @NotNull private final File myLocalTagsFile;  // .hg/localtags
   @NotNull private final VcsLogObjectsFactory myVcsObjectsFactory;
 
-  public HgRepositoryReader(@NotNull File hgDir) {
+  public HgRepositoryReader(@NotNull Project project, @NotNull File hgDir) {
     myHgDir = hgDir;
     RepositoryUtil.assertFileExists(myHgDir, ".hg directory not found in " + myHgDir);
     File branchesFile = new File(new File(myHgDir, "cache"), "branchheads-served");  //branchheads-served exist after mercurial 2.5,
@@ -60,7 +61,7 @@
     myCurrentBookmark = new File(myHgDir, "bookmarks.current");
     myLocalTagsFile = new File(myHgDir, "localtags");
     myTagsFile = new File(myHgDir.getParentFile(), ".hgtags");
-    myVcsObjectsFactory = ServiceManager.getService(VcsLogObjectsFactory.class);
+    myVcsObjectsFactory = ServiceManager.getService(project, VcsLogObjectsFactory.class);
   }
 
   /**
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.java
index d936cb1..0a66ab7 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.java
@@ -24,8 +24,8 @@
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.vcsUtil.VcsUtil;
 import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.util.HgUtil;
 import org.zmlx.hg4idea.HgVcsMessages;
+import org.zmlx.hg4idea.util.HgUtil;
 
 import javax.swing.*;
 import javax.swing.event.CaretEvent;
@@ -111,7 +111,8 @@
   public void show() {
     if (myShowDialog) {
       super.show();
-    } else {
+    }
+    else {
       mySelectedDir = FileChooser.chooseFile(myFileDescriptor, myProject, null);
     }
   }
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgEncodingUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgEncodingUtil.java
index c5ad072..af7d0c2 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgEncodingUtil.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgEncodingUtil.java
@@ -26,4 +26,14 @@
     }
     return Charset.defaultCharset();
   }
+
+  @NotNull
+  public static String getNameFor(@NotNull Charset charset) {
+    //workaround for x_MacRoman encoding etc; todo: create map with encoding aliases because some encodings name are not supported by hg
+    String name = charset.name();
+    if (name.startsWith("x-M")) {
+      return name.substring(2); // without "x-" prefix;
+    }
+    return name;
+  }
 }
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java
index 8558e81..ab2dba7 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java
@@ -93,4 +93,16 @@
       }
     };
   }
+
+  public static boolean isUnknownEncodingError(@Nullable HgCommandResult result) {
+    if (result == null) {
+      return false;
+    }
+    List<String> errorLines = result.getErrorLines();
+    if (errorLines.isEmpty()) {
+      return false;
+    }
+    String line = errorLines.get(0);
+    return !StringUtil.isEmptyOrSpaces(line) && (line.contains("abort") && line.contains("unknown encoding"));
+  }
 }
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgHistoryUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgHistoryUtil.java
index 4873558..65d5d2f 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgHistoryUtil.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgHistoryUtil.java
@@ -22,6 +22,7 @@
 import com.intellij.openapi.vcs.changes.Change;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.ArrayUtil;
+import com.intellij.util.Consumer;
 import com.intellij.util.Function;
 import com.intellij.util.SmartList;
 import com.intellij.util.containers.ContainerUtil;
@@ -120,7 +121,7 @@
   @NotNull
   public static List<? extends VcsShortCommitDetails> readMiniDetails(Project project, final VirtualFile root, List<String> hashes)
     throws VcsException {
-    final VcsLogObjectsFactory factory = ServiceManager.getService(VcsLogObjectsFactory.class);
+    final VcsLogObjectsFactory factory = ServiceManager.getService(project, VcsLogObjectsFactory.class);
     return ContainerUtil.map(getCommittedChangeList(project, root, -1, false, prepareHashes(hashes)),
                              new Function<HgCommittedChangeList, VcsShortCommitDetails>() {
                                @Override
@@ -132,15 +133,16 @@
                                  }
                                  return factory.createShortDetails(factory.createHash(revNumber.getChangeset()), parents,
                                                                    record.getCommitDate().getTime(), root,
-                                                                   revNumber.getSubject(), revNumber.getAuthor());
+                                                                   revNumber.getSubject(), revNumber.getAuthor(), "");
                                }
                              });
   }
 
   @NotNull
-  public static List<TimedVcsCommit> readAllHashes(@NotNull Project project, @NotNull VirtualFile root) throws VcsException {
+  public static List<TimedVcsCommit> readAllHashes(@NotNull Project project, @NotNull VirtualFile root,
+                                                   @NotNull final Consumer<VcsUser> userRegistry) throws VcsException {
 
-    final VcsLogObjectsFactory factory = ServiceManager.getService(VcsLogObjectsFactory.class);
+    final VcsLogObjectsFactory factory = ServiceManager.getService(project, VcsLogObjectsFactory.class);
     return ContainerUtil.map(getCommittedChangeList(project, root, -1, false, ""), new Function<HgCommittedChangeList, TimedVcsCommit>() {
       @Override
       public TimedVcsCommit fun(HgCommittedChangeList record) {
@@ -149,6 +151,7 @@
         for (HgRevisionNumber parent : revNumber.getParents()) {
           parents.add(factory.createHash(parent.getChangeset()));
         }
+        userRegistry.consume(factory.createUser(record.getRevision().getAuthor(), ""));
         return factory.createTimedCommit(factory.createHash(revNumber.getChangeset()),
                                          parents, record.getCommitDate().getTime());
       }
@@ -174,7 +177,7 @@
   private static VcsFullCommitDetails createCommit(@NotNull Project project, @NotNull VirtualFile root,
                                                    @NotNull HgCommittedChangeList record) {
 
-    final VcsLogObjectsFactory factory = ServiceManager.getService(VcsLogObjectsFactory.class);
+    final VcsLogObjectsFactory factory = ServiceManager.getService(project, VcsLogObjectsFactory.class);
     HgRevisionNumber revNumber = (HgRevisionNumber)record.getRevisionNumber();
 
     List<Hash> parents = ContainerUtil.map(revNumber.getParents(), new Function<HgRevisionNumber, Hash>() {
diff --git a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRealRepositoryReaderTest.java b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRealRepositoryReaderTest.java
index 73a1a58..079a6d2 100644
--- a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRealRepositoryReaderTest.java
+++ b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRealRepositoryReaderTest.java
@@ -41,7 +41,7 @@
     File hgDir = new File(myRepository.getPath(), ".hg");
     assertTrue(hgDir.exists());
     createBranchesAndTags();
-    myRepositoryReader = new HgRepositoryReader(hgDir);
+    myRepositoryReader = new HgRepositoryReader(myProject, hgDir);
   }
 
   public void testMergeState() {
diff --git a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java
index c7bc0f5..bb94270 100644
--- a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java
+++ b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java
@@ -63,7 +63,7 @@
     FileUtil.copy(testTagFile, new File(myHgDir.getParentFile(), ".hgtags"));
     FileUtil.copy(testLocalTagFile, new File(myHgDir, "localtags"));
 
-    myRepositoryReader = new HgRepositoryReader(myHgDir);
+    myRepositoryReader = new HgRepositoryReader(myProject, myHgDir);
     myBranches = readBranches();
     myBookmarks = readRefs(testBookmarkFile);
     myTags = readRefs(testTagFile);
diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenArtifactResourceConfiguration.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenArtifactResourceConfiguration.java
new file mode 100644
index 0000000..d0988e3
--- /dev/null
+++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenArtifactResourceConfiguration.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+package org.jetbrains.jps.maven.model.impl;
+
+import com.intellij.util.xmlb.annotations.AbstractCollection;
+import com.intellij.util.xmlb.annotations.Tag;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Sergey Evdokimov
+ */
+public class MavenArtifactResourceConfiguration {
+
+  public String webArtifactName;
+
+  @Tag("web-resources")
+  @AbstractCollection(surroundWithTag = false, elementTag = "resource")
+  public List<ResourceRootConfiguration> webResources = new ArrayList<ResourceRootConfiguration>();
+
+}
diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java
index a2f1bf9e..3c4c47c 100644
--- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java
+++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java
@@ -71,7 +71,6 @@
   @AbstractCollection(surroundWithTag = false, elementTag = "resource")
   public List<ResourceRootConfiguration> testResources = new ArrayList<ResourceRootConfiguration>();
 
-
   public Set<String> getFilteringExcludedExtensions() {
     if (filteringExclusions.isEmpty()) {
       return MavenProjectConfiguration.DEFAULT_FILTERING_EXCLUDED_EXTENSIONS;
diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenProjectConfiguration.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenProjectConfiguration.java
index adbc48e..91ff552 100644
--- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenProjectConfiguration.java
+++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenProjectConfiguration.java
@@ -49,6 +49,10 @@
   @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false, entryTagName = "maven-module", keyAttributeName = "name")
   public Map<String, MavenModuleResourceConfiguration> moduleConfigurations = new THashMap<String, MavenModuleResourceConfiguration>();
 
+  @Tag("web-resources")
+  @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false, entryTagName = "artifact", keyAttributeName = "name")
+  public Map<String, MavenArtifactResourceConfiguration> artifactsResources = new THashMap<String, MavenArtifactResourceConfiguration>();
+
   @Nullable
   public MavenModuleResourceConfiguration findProject(MavenIdBean id) {
     return getModuleConfigurationMap().get(id);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenArtifactCoordinatesArtifactIdConverter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenArtifactCoordinatesArtifactIdConverter.java
index 6245613..24fbf3b 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenArtifactCoordinatesArtifactIdConverter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenArtifactCoordinatesArtifactIdConverter.java
@@ -20,6 +20,7 @@
 import com.intellij.codeInsight.completion.InsertionContext;
 import com.intellij.codeInsight.lookup.LookupElement;
 import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.codeInsight.template.TemplateManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.PsiElement;
@@ -81,6 +82,10 @@
 
     @Override
     public void handleInsert(final InsertionContext context, LookupElement item) {
+      if (TemplateManager.getInstance(context.getProject()).getActiveTemplate(context.getEditor()) != null) {
+        return; // Don't brake the template.
+      }
+
       context.commitDocument();
 
       XmlFile xmlFile = (XmlFile)context.getFile();
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenArtifactCoordinatesGroupIdConverter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenArtifactCoordinatesGroupIdConverter.java
index 15b1b2f..3b89a83 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenArtifactCoordinatesGroupIdConverter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenArtifactCoordinatesGroupIdConverter.java
@@ -4,6 +4,7 @@
 import com.intellij.codeInsight.completion.InsertionContext;
 import com.intellij.codeInsight.lookup.LookupElement;
 import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.codeInsight.template.TemplateManager;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.util.PsiTreeUtil;
@@ -77,6 +78,10 @@
 
     @Override
     public void handleInsert(final InsertionContext context, LookupElement item) {
+      if (TemplateManager.getInstance(context.getProject()).getActiveTemplate(context.getEditor()) != null) {
+        return; // Don't brake the template.
+      }
+
       context.commitDocument();
 
       XmlFile xmlFile = (XmlFile)context.getFile();
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java
index 0558a36..d61b12b 100755
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java
@@ -25,7 +25,6 @@
 import com.intellij.openapi.roots.ModifiableRootModel;
 import com.intellij.openapi.roots.SourceFolder;
 import com.intellij.openapi.roots.impl.ModifiableModelCommitter;
-import com.intellij.openapi.roots.impl.SourceFolderImpl;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.util.ArrayUtil;
@@ -38,7 +37,7 @@
 import org.jetbrains.idea.maven.project.MavenImportingSettings;
 import org.jetbrains.idea.maven.project.MavenProject;
 import org.jetbrains.idea.maven.project.MavenProjectsManager;
-import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
 import org.jetbrains.jps.model.java.JavaResourceRootType;
 import org.jetbrains.jps.model.java.JavaSourceRootProperties;
 import org.jetbrains.jps.model.java.JavaSourceRootType;
@@ -269,8 +268,8 @@
   }
 
   private static boolean isGenerated(@NotNull  SourceFolder folder) {
-    JpsElement properties = ((SourceFolderImpl)folder).getJpsElement().getProperties();
-    return properties instanceof JavaSourceRootProperties && ((JavaSourceRootProperties)properties).isForGeneratedSources();
+    JavaSourceRootProperties properties = folder.getJpsElement().getProperties(JavaModuleSourceRootTypes.SOURCES);
+    return properties != null && properties.isForGeneratedSources();
   }
 
   private void addAllSubDirsAsGeneratedSources(@NotNull File dir, final JavaSourceRootType rootType) {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndices.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndices.java
index b13e2de..68a4539 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndices.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndices.java
@@ -112,8 +112,9 @@
         File f = new File(parent, name);
         if (!f.exists()) {
           boolean createSuccessFull = f.mkdirs();
-          assert createSuccessFull || f.exists();
-          return f;
+          if (createSuccessFull) {
+            return f;
+          }
         }
       }
       throw new RuntimeException("No available dir found");
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java
index 621af26..4089981 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java
@@ -17,6 +17,7 @@
 
 import com.intellij.openapi.application.AccessToken;
 import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ProjectFileIndex;
@@ -32,6 +33,8 @@
 import gnu.trove.THashSet;
 import gnu.trove.TObjectHashingStrategy;
 import org.jdom.Element;
+import org.jdom.output.Format;
+import org.jdom.output.XMLOutputter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.TestOnly;
@@ -49,6 +52,9 @@
 import java.util.zip.CRC32;
 
 public class MavenProjectsTree {
+
+  private static final Logger LOG = Logger.getInstance(MavenProjectsTree.class);
+
   private static final String STORAGE_VERSION = MavenProjectsTree.class.getSimpleName() + ".6";
 
   private final Object myStateLock = new Object();
@@ -884,7 +890,7 @@
 
     readLock();
     try {
-      CRC32 crc = new CRC32();
+      final CRC32 crc = new CRC32();
 
       Set<String> profiles = myExplicitProfiles;
       if (profiles != null) {
@@ -919,7 +925,7 @@
         updateCrc(crc, mavenProject.getDirectory());
         updateCrc(crc, MavenFilteredPropertyPsiReferenceProvider.getDelimitersPattern(mavenProject).pattern());
         updateCrc(crc, mavenProject.getModelMap().hashCode());
-        updateCrc(crc, mavenProject.getResources().hashCode() + 1); // @todo remove '+1' after 01.05.2013 (when 12.0.1 become out of date)
+        updateCrc(crc, mavenProject.getResources().hashCode());
         updateCrc(crc, mavenProject.getTestResources().hashCode());
         updateCrc(crc, getFilterExclusions(mavenProject).hashCode());
         updateCrc(crc, mavenProject.getProperties().hashCode());
@@ -929,9 +935,41 @@
           updateCrc(crc, file.lastModified());
         }
 
-        Element pluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-resources-plugin");
-        updateCrc(crc, MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeString"));
-        updateCrc(crc, MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeWindowsPaths"));
+        XMLOutputter outputter = new XMLOutputter(Format.getCompactFormat());
+
+        Writer crcWriter = new Writer() {
+          @Override
+          public void write(char[] cbuf, int off, int len) throws IOException {
+            for (int i = off, end = off + len; i < end; i++) {
+              crc.update(cbuf[i]);
+            }
+          }
+
+          @Override
+          public void flush() throws IOException {
+
+          }
+
+          @Override
+          public void close() throws IOException {
+
+          }
+        };
+
+        try {
+          Element resourcePluginCfg = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-resources-plugin");
+          if (resourcePluginCfg != null) {
+            outputter.output(resourcePluginCfg, crcWriter);
+          }
+
+          Element warPluginCfg = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-war-plugin");
+          if (warPluginCfg != null) {
+            outputter.output(warPluginCfg, crcWriter);
+          }
+        }
+        catch (IOException e) {
+          LOG.error(e);
+        }
       }
 
       return (int)crc.getValue();
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
index 12fb1d3..523d5cb 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
@@ -3,12 +3,14 @@
 import com.intellij.compiler.CompilerConfiguration;
 import com.intellij.compiler.CompilerConfigurationImpl;
 import com.intellij.compiler.server.BuildManager;
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.module.ModuleManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.*;
 import com.intellij.openapi.util.JDOMUtil;
 import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VfsUtil;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -16,15 +18,13 @@
 import com.intellij.util.xmlb.XmlSerializer;
 import org.jdom.Document;
 import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.idea.maven.dom.references.MavenFilteredPropertyPsiReferenceProvider;
 import org.jetbrains.idea.maven.model.MavenId;
 import org.jetbrains.idea.maven.model.MavenResource;
 import org.jetbrains.idea.maven.utils.MavenJDOMUtil;
 import org.jetbrains.idea.maven.utils.MavenUtil;
-import org.jetbrains.jps.maven.model.impl.MavenIdBean;
-import org.jetbrains.jps.maven.model.impl.MavenModuleResourceConfiguration;
-import org.jetbrains.jps.maven.model.impl.MavenProjectConfiguration;
-import org.jetbrains.jps.maven.model.impl.ResourceRootConfiguration;
+import org.jetbrains.jps.maven.model.impl.*;
 
 import java.io.*;
 import java.util.*;
@@ -36,6 +36,8 @@
  */
 public class MavenResourceCompilerConfigurationGenerator {
 
+  private static Logger LOG = Logger.getInstance(MavenResourceCompilerConfigurationGenerator.class);
+
   private static final Pattern SIMPLE_NEGATIVE_PATTERN = Pattern.compile("!\\?(\\*\\.\\w+)");
 
   private final Project myProject;
@@ -116,6 +118,9 @@
       }
       addResources(resourceConfig.resources, mavenProject.getResources());
       addResources(resourceConfig.testResources, mavenProject.getTestResources());
+
+      addWebResources(module, projectConfig, mavenProject);
+
       resourceConfig.filteringExclusions.addAll(MavenProjectsTree.getFilterExclusions(mavenProject));
 
       final Properties properties = getFilteringProperties(mavenProject);
@@ -220,6 +225,63 @@
     }
   }
 
+  private static void addWebResources(@NotNull Module module, MavenProjectConfiguration projectCfg, MavenProject mavenProject) {
+    Element warCfg = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-war-plugin");
+    if (warCfg == null) return;
+
+    Element webResources = warCfg.getChild("webResources");
+    if (webResources == null) return;
+
+    String webArtifactName = MavenUtil.getArtifactName("war", module, true);
+
+    MavenArtifactResourceConfiguration artifactResourceCfg = projectCfg.artifactsResources.get(webArtifactName);
+    if (artifactResourceCfg == null) {
+      artifactResourceCfg = new MavenArtifactResourceConfiguration();
+      artifactResourceCfg.webArtifactName = webArtifactName;
+      projectCfg.artifactsResources.put(webArtifactName, artifactResourceCfg);
+    }
+    else {
+      LOG.error("MavenArtifactResourceConfiguration already exists.");
+    }
+
+    for (Element resource : webResources.getChildren("resource")) {
+      ResourceRootConfiguration r = new ResourceRootConfiguration();
+      String directory = resource.getChildTextTrim("directory");
+      if (StringUtil.isEmptyOrSpaces(directory)) continue;
+
+      if (!FileUtil.isAbsolute(directory)) {
+        directory = mavenProject.getDirectory() + '/' + directory;
+      }
+
+      r.directory = directory;
+      r.isFiltered = Boolean.parseBoolean(resource.getChildTextTrim("filtering"));
+
+      r.targetPath = resource.getChildTextTrim("targetPath");
+
+      Element includes = resource.getChild("includes");
+      if (includes != null) {
+        for (Element include : includes.getChildren("include")) {
+          String includeText = include.getTextTrim();
+          if (!includeText.isEmpty()) {
+            r.includes.add(includeText);
+          }
+        }
+      }
+
+      Element excludes = resource.getChild("excludes");
+      if (excludes != null) {
+        for (Element exclude : excludes.getChildren("exclude")) {
+          String excludeText = exclude.getTextTrim();
+          if (!excludeText.isEmpty()) {
+            r.excludes.add(excludeText);
+          }
+        }
+      }
+
+      artifactResourceCfg.webResources.add(r);
+    }
+  }
+
   private void addNonMavenResources(MavenProjectConfiguration projectCfg) {
     Set<VirtualFile> processedRoots = new HashSet<VirtualFile>();
 
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerManager.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerManager.java
index 774bc83..b4c440b 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerManager.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerManager.java
@@ -25,6 +25,7 @@
 import com.intellij.execution.rmi.RemoteProcessSupport;
 import com.intellij.execution.runners.ProgramRunner;
 import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.components.*;
 import com.intellij.openapi.project.Project;
@@ -79,7 +80,7 @@
 
   private final Alarm myShutdownAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
 
-  private boolean useMaven2 = true;
+  private boolean useMaven2 = false;
   private String mavenEmbedderVMOptions = DEFAULT_VM_OPTIONS;
   private String embedderJdk = MavenRunnerSettings.USE_INTERNAL_JAVA;
 
@@ -294,19 +295,24 @@
     return new File(pluginFileOrDir.getParentFile(), "maven3");
   }
 
-  public static List<File> collectClassPathAndLibsFolder() {
+  public List<File> collectClassPathAndLibsFolder() {
     File pluginFileOrDir = new File(PathUtil.getJarPathForClass(MavenServerManager.class));
 
     List<File> classpath = new ArrayList<File>();
 
     String root = pluginFileOrDir.getParent();
 
+    boolean useMaven2 = this.useMaven2;
+    if (ApplicationManager.getApplication().isUnitTestMode()) {
+      useMaven2 = true;
+    }
+
     if (pluginFileOrDir.isDirectory()) {
       classpath.add(new File(root, "maven-server-api"));
 
       File luceneLib = new File(PathUtil.getJarPathForClass(Query.class));
 
-      if (getInstance().isUseMaven2()) {
+      if (useMaven2) {
         classpath.add(new File(root, "maven2-server-impl"));
         addDir(classpath, new File(luceneLib.getParentFile().getParentFile().getParentFile(), "maven2-server-impl/lib"));
       }
@@ -326,7 +332,7 @@
     else {
       classpath.add(new File(root, "maven-server-api.jar"));
 
-      if (getInstance().isUseMaven2()) {
+      if (useMaven2) {
         classpath.add(new File(root, "maven2-server-impl.jar"));
 
         addDir(classpath, new File(root, "maven2"));
@@ -499,7 +505,7 @@
   @Override
   public Element getState() {
     final Element element = new Element("maven-version");
-    element.setAttribute("version", useMaven2 ? "2" : "3");
+    element.setAttribute("version", useMaven2 ? "2.x" : "3.x");
     element.setAttribute("vmOptions", mavenEmbedderVMOptions);
     return element;
   }
@@ -507,7 +513,7 @@
   @Override
   public void loadState(Element state) {
     String version = state.getAttributeValue("version");
-    useMaven2 = !"3".equals(version);
+    useMaven2 = "2.x".equals(version);
 
     String vmOptions = state.getAttributeValue("vmOptions");
     mavenEmbedderVMOptions = vmOptions == null ? DEFAULT_VM_OPTIONS : vmOptions;
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java
index fba889c..71f22ec 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java
@@ -711,6 +711,7 @@
     }
     if (result == null) {
       result = doResolveSuperPomFile(MavenServerManager.getMavenLibDirectory());
+      assert result != null : "Super pom not found in: " + MavenServerManager.getMavenLibDirectory();
     }
     return result;
   }
@@ -926,4 +927,9 @@
     return (V)res;
   }
 
+  public static String getArtifactName(String packaging, Module module, boolean exploded) {
+    final String baseName = module.getName() + ":" + packaging;
+    return exploded ? baseName + " exploded" : baseName;
+  }
+
 }
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java
index 1da55a1..1f7a404 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java
@@ -34,7 +34,6 @@
 import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
 import com.intellij.openapi.roots.*;
-import com.intellij.openapi.roots.impl.SourceFolderImpl;
 import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
 import com.intellij.openapi.roots.libraries.Library;
 import com.intellij.openapi.ui.Messages;
@@ -130,7 +129,9 @@
     ContentEntry contentRoot = getContentRoot(moduleName);
     List<ContentFolder> folders = new ArrayList<ContentFolder>();
     for (SourceFolder folder : contentRoot.getSourceFolders(JavaSourceRootType.SOURCE)) {
-      if (((JavaSourceRootProperties)((SourceFolderImpl)folder).getJpsElement().getProperties()).isForGeneratedSources()) {
+      JavaSourceRootProperties properties = folder.getJpsElement().getProperties(JavaSourceRootType.SOURCE);
+      assertNotNull(properties);
+      if (properties.isForGeneratedSources()) {
         folders.add(folder);
       }
     }
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenFoldersImporterTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenFoldersImporterTest.java
index 2138756..e6e946e 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenFoldersImporterTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenFoldersImporterTest.java
@@ -18,13 +18,13 @@
 import com.intellij.ProjectTopics;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.roots.*;
-import com.intellij.openapi.roots.impl.SourceFolderImpl;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.Consumer;
 import org.jetbrains.idea.maven.MavenImportingTestCase;
 import org.jetbrains.idea.maven.importing.MavenDefaultModifiableModelsProvider;
 import org.jetbrains.idea.maven.importing.MavenFoldersImporter;
 import org.jetbrains.idea.maven.importing.MavenRootModelAdapter;
+import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
 import org.jetbrains.jps.model.java.JavaSourceRootProperties;
 import org.jetbrains.jps.model.java.JavaSourceRootType;
 
@@ -239,7 +239,9 @@
       @Override
       public void consume(ModifiableRootModel model) {
         for (SourceFolder folder : model.getContentEntries()[0].getSourceFolders()) {
-          ((JavaSourceRootProperties)((SourceFolderImpl)folder).getJpsElement().getProperties()).setForGeneratedSources(false);
+          JavaSourceRootProperties properties = folder.getJpsElement().getProperties(JavaModuleSourceRootTypes.SOURCES);
+          assertNotNull(properties);
+          properties.setForGeneratedSources(false);
         }
       }
     });
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
index 073bf57..ce734fd 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
@@ -15,6 +15,7 @@
  */
 package org.jetbrains.idea.svn;
 
+import com.intellij.notification.NotificationType;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.progress.ProcessCanceledException;
@@ -25,11 +26,13 @@
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.io.FileUtilRt;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.AbstractVcsHelper;
 import com.intellij.openapi.vcs.VcsException;
 import com.intellij.openapi.vcs.changes.Change;
 import com.intellij.openapi.vcs.changes.ChangesUtil;
+import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
 import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -57,6 +60,7 @@
 import org.tmatesoft.svn.core.wc2.SvnTarget;
 
 import java.io.File;
+import java.nio.channels.NonWritableChannelException;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -369,30 +373,34 @@
    */
   @NotNull
   public static WorkingCopyFormat getFormat(final File path) {
-    int format = 0;
+    WorkingCopyFormat result = null;
     File dbFile = resolveDatabase(path);
 
     if (dbFile != null) {
-      SqlJetDb db = null;
-      try {
-        db = SqlJetDb.open(dbFile, false);
-        format = db.getOptions().getUserVersion();
-      }
-      catch (SqlJetException e) {
-        LOG.error(e);
-      } finally {
-        if (db != null) {
-          try {
-            db.close();
-          }
-          catch (SqlJetException e) {
-            LOG.error(e);
-          }
-        }
+      result = FileUtilRt.doIOOperation(new WorkingCopyFormatOperation(dbFile));
+
+      if (result == null) {
+        notifyDatabaseError();
       }
     }
 
-    return WorkingCopyFormat.getInstance(format);
+    return result != null ? result : WorkingCopyFormat.UNKNOWN;
+  }
+
+  private static void close(@Nullable SqlJetDb db) {
+    if (db != null) {
+      try {
+        db.close();
+      }
+      catch (SqlJetException e) {
+        notifyDatabaseError();
+      }
+    }
+  }
+
+  private static void notifyDatabaseError() {
+    VcsBalloonProblemNotifier.NOTIFICATION_GROUP
+      .createNotification("Some errors occurred while accessing svn working copy database.", NotificationType.ERROR).notify(null);
   }
 
   private static File resolveDatabase(final File path) {
@@ -803,4 +811,40 @@
            // thrown when getting info from repository for non-existent item - like HEAD revision for deleted file
            SVNErrorCode.ILLEGAL_TARGET.equals(code);
   }
+
+  private static class WorkingCopyFormatOperation implements FileUtilRt.RepeatableIOOperation<WorkingCopyFormat, RuntimeException> {
+    @NotNull private final File myDbFile;
+
+    public WorkingCopyFormatOperation(@NotNull File dbFile) {
+      myDbFile = dbFile;
+    }
+
+    @Nullable
+    @Override
+    public WorkingCopyFormat execute(boolean lastAttempt) {
+      // TODO: rewrite it using sqlite jdbc driver
+      SqlJetDb db = null;
+      WorkingCopyFormat result = null;
+      try {
+        // "write" access is requested here for now as workaround - see some details
+        // in https://code.google.com/p/sqljet/issues/detail?id=25 and http://issues.tmatesoft.com/issue/SVNKIT-418.
+        // BUSY error is currently handled same way as others.
+        db = SqlJetDb.open(myDbFile, true);
+        result = WorkingCopyFormat.getInstance(db.getOptions().getUserVersion());
+      }
+      catch (NonWritableChannelException e) {
+        // Such exceptions could be thrown when db is opened in "read" mode, but the db file is readonly (for instance, locked
+        // by other process). See links above for some details.
+        // handle this exception type separately - not to break execution flow
+        LOG.info(e);
+      }
+      catch (SqlJetException e) {
+        LOG.info(e);
+      }
+      finally {
+        close(db);
+      }
+      return result;
+    }
+  }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/Command.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/Command.java
index e5d7dd6..ea623f4 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/Command.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/Command.java
@@ -41,6 +41,12 @@
     myParameters.addAll(parameters);
   }
 
+  public void putIfNotPresent(@NotNull String parameter) {
+    if (!myParameters.contains(parameter)) {
+      myParameters.add(parameter);
+    }
+  }
+
   @Nullable
   public File getConfigDir() {
     return myConfigDir;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java
index c015d025..5779ee4 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java
@@ -15,6 +15,7 @@
  */
 package org.jetbrains.idea.svn.commandLine;
 
+import com.intellij.execution.ExecutionException;
 import com.intellij.execution.configurations.GeneralCommandLine;
 import com.intellij.execution.process.*;
 import com.intellij.openapi.diagnostic.Logger;
@@ -25,6 +26,8 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.io.IOException;
+import java.io.OutputStreamWriter;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -40,9 +43,11 @@
 
   private boolean myIsDestroyed;
   private boolean myNeedsDestroy;
+  private volatile String myDestroyReason;
   protected final GeneralCommandLine myCommandLine;
-  private Process myProcess;
-  private OSProcessHandler myHandler;
+  protected Process myProcess;
+  protected OSProcessHandler myHandler;
+  private OutputStreamWriter myProcessWriter;
   // TODO: Try to implement commands in a way that they manually indicate if they need full output - to prevent situations
   // TODO: when large amount of data needs to be stored instead of just sequential processing.
   private CapturingProcessAdapter outputAdapter;
@@ -86,16 +91,21 @@
     return myIsDestroyed;
   }
 
+  public String getDestroyReason() {
+    return myDestroyReason;
+  }
+
   public void start() {
     synchronized (myLock) {
       checkNotStarted();
 
       try {
-        myProcess = myCommandLine.createProcess();
+        myProcess = createProcess();
         if (LOG.isDebugEnabled()) {
           LOG.debug(myCommandLine.toString());
         }
-        myHandler = new OSProcessHandler(myProcess, myCommandLine.getCommandLineString());
+        myHandler = createProcessHandler();
+        myProcessWriter = new OutputStreamWriter(myHandler.getProcessInput());
         startHandlingStreams();
       } catch (Throwable t) {
         listeners().startFailed(t);
@@ -104,7 +114,17 @@
     }
   }
 
-  private void startHandlingStreams() {
+  @NotNull
+  protected OSProcessHandler createProcessHandler() {
+    return new OSProcessHandler(myProcess, myCommandLine.getCommandLineString());
+  }
+
+  @NotNull
+  protected Process createProcess() throws ExecutionException {
+    return myCommandLine.createProcess();
+  }
+
+  protected void startHandlingStreams() {
     outputAdapter = new CapturingProcessAdapter();
     myHandler.addProcessListener(outputAdapter);
     myHandler.addProcessListener(new ProcessTracker());
@@ -121,6 +141,12 @@
     return outputAdapter.getOutput().getStderr();
   }
 
+  // TODO: Carefully here - do not modify command from threads other than the one started command execution
+  @NotNull
+  public Command getCommand() {
+    return myCommand;
+  }
+
   /**
    * Wait for process termination
    * @param timeout
@@ -183,6 +209,13 @@
     }
   }
 
+  public void destroyProcess(@Nullable String destroyReason) {
+    synchronized (myLock) {
+      myDestroyReason = destroyReason;
+      myNeedsDestroy = true;
+    }
+  }
+
   /**
    * ProcessHandler.destroyProcess() implementations could acquire read lock in its implementation - like OSProcessManager.getInstance().
    * Some commands are called under write lock - which is generally bad idea, but such logic is not refactored yet.
@@ -265,6 +298,23 @@
     }
   }
 
+  public void write(String value) throws SvnBindException {
+    try {
+      synchronized (myLock) {
+        myProcessWriter.write(value);
+        myProcessWriter.flush();
+      }
+    }
+    catch (IOException e) {
+      throw new SvnBindException(e);
+    }
+  }
+
+  public void logCommand() {
+    LOG.info("Command text " + getCommandText());
+    LOG.info("Command output " + getOutput());
+  }
+
   private class CommandCancelTracker extends LineCommandAdapter {
     @Override
     public void onLineAvailable(String line, Key outputType) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandParametersResolutionModule.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandParametersResolutionModule.java
index a76f0ec..2e9e420 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandParametersResolutionModule.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandParametersResolutionModule.java
@@ -44,7 +44,6 @@
       command.setWorkingDirectory(resolveWorkingDirectory(command));
     }
     command.setConfigDir(myAuthCallback.getSpecialConfigDir());
-    command.put("--non-interactive");
     command.saveOriginalParameters();
   }
 
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java
index be097b6..67867ea 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java
@@ -17,6 +17,8 @@
 
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -85,12 +87,20 @@
     if (exitCode == null || exitCode != 0) {
       logNullExitCode(executor, exitCode);
 
+      if (executor.isManuallyDestroyed()) {
+        cleanup(executor, command.getWorkingDirectory());
+
+        String destroyReason = executor.getDestroyReason();
+        if (!StringUtil.isEmpty(destroyReason)) {
+          throw new SvnBindException(destroyReason);
+        }
+      }
+
       if (executor.getErrorOutput().length() > 0) {
         // handle authentication
         final String errText = executor.getErrorOutput().trim();
-        final AuthCallbackCase callback = createCallback(errText, command.getRepositoryUrl());
+        final AuthCallbackCase callback = executor instanceof TerminalExecutor ? null : createCallback(errText, command.getRepositoryUrl());
         if (callback != null) {
-          cleanup(executor, command.getWorkingDirectory());
           if (callback.getCredentials(errText)) {
             if (myAuthCallback.getSpecialConfigDir() != null) {
               command.setConfigDir(myAuthCallback.getSpecialConfigDir());
@@ -107,6 +117,9 @@
         // no errors found in error stream => we treat null exitCode as successful, otherwise exception is thrown
         if (exitCode != null) {
           // here exitCode != null && exitCode != 0
+          LOG.info("Command - " + executor.getCommandText());
+          LOG.info("Command output - " + executor.getOutput());
+
           throw new SvnBindException("Svn process exited with error code: " + exitCode);
         }
       }
@@ -148,7 +161,7 @@
   }
 
   private void cleanup(@NotNull CommandExecutor executor, @NotNull File workingDirectory) throws SvnBindException {
-    if (executor.isManuallyDestroyed() && executor.getCommandName().isWriteable()) {
+    if (executor.getCommandName().isWriteable()) {
       File wcRoot = SvnUtil.getWorkingCopyRootNew(workingDirectory);
 
       // not all commands require cleanup - for instance, some commands operate only with repository - like "svn info <url>"
@@ -167,7 +180,19 @@
 
   @NotNull
   private CommandExecutor newExecutor(@NotNull Command command) {
-    return new CommandExecutor(exePath, command);
+    final CommandExecutor executor;
+
+    if (!Registry.is("svn.use.terminal")) {
+      command.putIfNotPresent("--non-interactive");
+      executor = new CommandExecutor(exePath, command);
+    }
+    else {
+      command.put("--force-interactive");
+      executor = new TerminalExecutor(exePath, command);
+      ((TerminalExecutor)executor).addInteractiveListener(new TerminalSshModule(this, executor));
+    }
+
+    return executor;
   }
 
   @NotNull
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/InteractiveCommandListener.java
similarity index 68%
copy from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java
copy to plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/InteractiveCommandListener.java
index bed999e..a9dc33a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/InteractiveCommandListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -13,12 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jetbrains.plugins.groovy.lang;
+package org.jetbrains.idea.svn.commandLine;
 
-import com.intellij.ide.hierarchy.type.JavaTypeHierarchyProvider;
+import com.intellij.openapi.util.Key;
 
 /**
- * @author peter
+ * @author Konstantin Kolosovsky.
  */
-public class GroovyTypeHierarchyProvider extends JavaTypeHierarchyProvider{
+public interface InteractiveCommandListener {
+
+  boolean handlePrompt(String line, Key outputType);
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
index 48dcfa5..860e858 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
@@ -171,6 +171,11 @@
       throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
     }
     catch (SAXException e) {
+      // status parsing errors are logged separately as sometimes there are parsing errors connected to terminal output handling.
+      // these errors primarily occur when status output is rather large.
+      // and status output could be large, for instance, when working copy is locked (seems that each file is listed in status output).
+      command.logCommand();
+
       throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
     }
   }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalExecutor.java
new file mode 100644
index 0000000..203b25c
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalExecutor.java
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+package org.jetbrains.idea.svn.commandLine;
+
+import com.intellij.execution.CommandLineUtil;
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.process.OSProcessHandler;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import com.pty4j.PtyProcess;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class TerminalExecutor extends CommandExecutor {
+
+  // max available value is 480
+  // if greater value is provided than the default value of 80 will be assumed
+  // this could provide unnecessary line breaks and thus could break parsing logic
+  private static final int TERMINAL_WINDOW_MAX_COLUMNS = 480;
+
+  static {
+    if (SystemInfo.isWindows) {
+      System.setProperty("win.pty.cols", String.valueOf(TERMINAL_WINDOW_MAX_COLUMNS));
+    }
+  }
+
+  private final List<InteractiveCommandListener> myInteractiveListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+
+  public TerminalExecutor(@NotNull @NonNls String exePath, @NotNull Command command) {
+    super(exePath, command);
+  }
+
+  public void addInteractiveListener(@NotNull InteractiveCommandListener listener) {
+    myInteractiveListeners.add(listener);
+  }
+
+  @Override
+  protected void startHandlingStreams() {
+    for (InteractiveCommandListener listener : myInteractiveListeners) {
+      ((TerminalProcessHandler)myHandler).addInteractiveListener(listener);
+    }
+
+    super.startHandlingStreams();
+  }
+
+  @NotNull
+  @Override
+  protected OSProcessHandler createProcessHandler() {
+    return new TerminalProcessHandler(myProcess);
+  }
+
+  @NotNull
+  @Override
+  protected Process createProcess() throws ExecutionException {
+    List<String> parameters =
+      escapeArguments(CommandLineUtil.toCommandLine(myCommandLine.getExePath(), myCommandLine.getParametersList().getList()));
+
+    try {
+      return PtyProcess
+        .exec(ArrayUtil.toStringArray(parameters), myCommandLine.getEnvironment(), myCommandLine.getWorkDirectory().getAbsolutePath());
+    }
+    catch (IOException e) {
+      throw new ExecutionException(e);
+    }
+  }
+
+  @Override
+  public void logCommand() {
+    super.logCommand();
+
+    LOG.info("Terminal output " + ((TerminalProcessHandler) myHandler).getTerminalOutput());
+  }
+
+  private static List<String> escapeArguments(List<String> collection) {
+    // TODO: Add additional checks like in java.lang.ProcessImpl constructor
+    return ContainerUtil.map(collection, new Function<String, String>() {
+      @Override
+      public String fun(String s) {
+        return s.contains(" ") ? "\"" + s + "\"" : s;
+      }
+    });
+  }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalProcessHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalProcessHandler.java
new file mode 100644
index 0000000..86fd039
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalProcessHandler.java
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+package org.jetbrains.idea.svn.commandLine;
+
+import com.intellij.execution.process.CapturingProcessAdapter;
+import com.intellij.execution.process.OSProcessHandler;
+import com.intellij.execution.process.ProcessEvent;
+import com.intellij.execution.process.ProcessOutputTypes;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnUtil;
+
+import java.util.List;
+import java.util.regex.Matcher;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class TerminalProcessHandler extends OSProcessHandler {
+
+  // see http://en.wikipedia.org/wiki/ANSI_escape_code
+  private static final String NON_CSI_ESCAPE_CODE = "\u001B.[@-_]";
+  private static final String CSI_ESCAPE_CODE = "\u001B\\[(.*?)[@-~]";
+
+  private final List<InteractiveCommandListener> myInteractiveListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+  private final CapturingProcessAdapter terminalOutputCapturer = new CapturingProcessAdapter();
+
+  private final StringBuilder outputLine = new StringBuilder();
+  private final StringBuilder errorLine = new StringBuilder();
+
+  public TerminalProcessHandler(@NotNull Process process) {
+    super(process);
+  }
+
+  public void addInteractiveListener(@NotNull InteractiveCommandListener listener) {
+    myInteractiveListeners.add(listener);
+  }
+
+  @Override
+  protected boolean processHasSeparateErrorStream() {
+    return false;
+  }
+
+  @Override
+  protected void destroyProcessImpl() {
+    final Process process = getProcess();
+    process.destroy();
+  }
+
+  @Override
+  public void notifyTextAvailable(String text, Key outputType) {
+    terminalOutputCapturer.onTextAvailable(new ProcessEvent(this, text), outputType);
+
+    // filter terminal escape codes - they are presented in the output for windows platform
+    String filteredText = text.replaceAll(CSI_ESCAPE_CODE, "").replaceAll(NON_CSI_ESCAPE_CODE, "");
+    // trim leading '\r' symbols - as they break xml parsing logic
+    filteredText = StringUtil.trimLeading(filteredText);
+
+    if (!StringUtil.isEmpty(filteredText)) {
+      StringBuilder lastLine = getLastLineFor(outputType);
+      String currentLine = lastLine.append(filteredText).toString();
+      lastLine.setLength(0);
+
+      // check if current line presents some interactive output
+      boolean handled = false;
+      for (InteractiveCommandListener listener : myInteractiveListeners) {
+        handled |= listener.handlePrompt(currentLine, outputType);
+      }
+
+      if (!handled) {
+        notify(currentLine, outputType, lastLine);
+      }
+    }
+  }
+
+  private void notify(@NotNull String text, @NotNull Key outputType, @NotNull StringBuilder lastLine) {
+    // for windows platform output is assumed in format suitable for terminal emulator
+    // for instance, same text could be returned twice with '\r' symbol in between (so in emulator output we'll still see correct
+    // text without duplication)
+    // because of this we manually process '\r' occurrences to get correct output
+    text = removeAllBeforeCaretReturn(text);
+
+    // text is not more than one line - either one line or part of the line
+    if (StringUtil.endsWith(text, "\n")) {
+      // we have full line - notify listeners
+      super.notifyTextAvailable(text, resolveOutputType(text, outputType));
+    }
+    else {
+      // save line part to lastLine
+      lastLine.append(text);
+    }
+  }
+
+  private static String removeAllBeforeCaretReturn(@NotNull String line) {
+    int caretReturn = line.lastIndexOf("\r");
+
+    while (caretReturn >= 0) {
+      if (caretReturn + 1 < line.length() && line.charAt(caretReturn + 1) != '\n') {
+        // next symbol is not '\n' - we should not treat text before found caret return symbol
+        line = line.substring(caretReturn + 1);
+        break;
+      }
+      caretReturn = line.lastIndexOf("\r", caretReturn - 1);
+    }
+
+    return line;
+  }
+
+  private static Key resolveOutputType(@NotNull String line, @NotNull Key outputType) {
+    Key result = outputType;
+
+    if (!ProcessOutputTypes.SYSTEM.equals(outputType)) {
+      Matcher errorMatcher = SvnUtil.ERROR_PATTERN.matcher(line);
+      Matcher warningMatcher = SvnUtil.WARNING_PATTERN.matcher(line);
+
+      result = errorMatcher.find() || warningMatcher.find() ? ProcessOutputTypes.STDERR : ProcessOutputTypes.STDOUT;
+    }
+
+    return result;
+  }
+
+  @NotNull
+  private StringBuilder getLastLineFor(Key outputType) {
+    if (ProcessOutputTypes.STDERR.equals(outputType)) {
+      return errorLine;
+    }
+    else if (ProcessOutputTypes.STDOUT.equals(outputType)) {
+      return outputLine;
+    }
+    else {
+      throw new IllegalArgumentException("Unknown process output type " + outputType);
+    }
+  }
+
+  public String getTerminalOutput() {
+    return terminalOutputCapturer.getOutput().getStdout();
+  }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalSshModule.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalSshModule.java
new file mode 100644
index 0000000..b957b9a
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalSshModule.java
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+package org.jetbrains.idea.svn.commandLine;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.Ref;
+import com.intellij.util.WaitForProgressToShow;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnBundle;
+import org.jetbrains.idea.svn.dialogs.ServerSSHDialog;
+import org.jetbrains.idea.svn.dialogs.SimpleCredentialsDialog;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class TerminalSshModule extends LineCommandAdapter implements CommandRuntimeModule, InteractiveCommandListener {
+
+  private static final Logger LOG = Logger.getInstance(TerminalSshModule.class);
+
+  private static final Pattern PASSPHRASE_PROMPT = Pattern.compile("Enter passphrase for key \\'(.*)\\':\\s?");
+  private static final Pattern PASSWORD_PROMPT = Pattern.compile("(.*)\\'s password:\\s?");
+
+  private static final Pattern UNKNOWN_HOST_MESSAGE =
+    Pattern.compile("The authenticity of host \\'((.*) \\((.*)\\))\\' can\\'t be established\\.\\s?");
+  private static final Pattern HOST_FINGERPRINT_MESSAGE = Pattern.compile("(\\w+) key fingerprint is (.*)\\.\\s?");
+  private static final Pattern ACCEPT_HOST_PROMPT = Pattern.compile("Are you sure you want to continue connecting \\(yes/no\\)\\?\\s?");
+
+  @NotNull private final CommandRuntime myRuntime;
+  @NotNull private final CommandExecutor myExecutor;
+
+  private String unknownHost;
+  private String fingerprintAlgorithm;
+  private String hostFingerprint;
+
+  // TODO: Do not accept executor here and make it as command runtime module
+  public TerminalSshModule(@NotNull CommandRuntime runtime, @NotNull CommandExecutor executor) {
+    myExecutor = executor;
+    myRuntime = runtime;
+  }
+
+  @Override
+  public void onStart(@NotNull Command command) throws SvnBindException {
+  }
+
+  @Override
+  public boolean handlePrompt(String line, Key outputType) {
+    return checkPassphrase(line) || checkPassword(line) || checkUnknownHost(line);
+  }
+
+  private boolean checkPassphrase(@NotNull String line) {
+    Matcher matcher = PASSPHRASE_PROMPT.matcher(line);
+
+    return matcher.matches() && handleAuthPrompt(SimpleCredentialsDialog.Mode.SSH_PASSPHRASE, matcher.group(1));
+  }
+
+  private boolean checkPassword(@NotNull String line) {
+    Matcher matcher = PASSWORD_PROMPT.matcher(line);
+
+    return matcher.matches() && handleAuthPrompt(SimpleCredentialsDialog.Mode.SSH_PASSWORD, matcher.group(1));
+  }
+
+  private boolean checkUnknownHost(@NotNull String line) {
+    Matcher unknownHostMatcher = UNKNOWN_HOST_MESSAGE.matcher(line);
+    Matcher hostFingerPrintMatcher = HOST_FINGERPRINT_MESSAGE.matcher(line);
+    Matcher acceptHostMatcher = ACCEPT_HOST_PROMPT.matcher(line);
+
+    if (unknownHostMatcher.matches()) {
+      unknownHost = unknownHostMatcher.group(1);
+    }
+    else if (hostFingerPrintMatcher.matches()) {
+      fingerprintAlgorithm = hostFingerPrintMatcher.group(1);
+      hostFingerprint = hostFingerPrintMatcher.group(2);
+    }
+    else if (acceptHostMatcher.matches()) {
+      handleUnknownHost();
+    }
+
+    return unknownHostMatcher.matches() || hostFingerPrintMatcher.matches() || acceptHostMatcher.matches();
+  }
+
+  private void handleUnknownHost() {
+    final Project project = myRuntime.getVcs().getProject();
+    final Ref<Integer> answer = new Ref<Integer>();
+
+    Runnable command = new Runnable() {
+      @Override
+      public void run() {
+        final ServerSSHDialog dialog = new ServerSSHDialog(project, true, unknownHost, fingerprintAlgorithm, hostFingerprint);
+        dialog.show();
+        answer.set(dialog.getResult());
+      }
+    };
+
+    WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(command);
+
+    unknownHost = null;
+    fingerprintAlgorithm = null;
+    hostFingerprint = null;
+
+    sendAnswer(answer.get() == ISVNAuthenticationProvider.REJECTED ? "no" : "yes");
+  }
+
+  private boolean handleAuthPrompt(@NotNull final SimpleCredentialsDialog.Mode mode, @NotNull final String key) {
+    @NotNull final SVNURL repositoryUrl = myExecutor.getCommand().getRepositoryUrl();
+    final Project project = myRuntime.getVcs().getProject();
+    final Ref<String> answer = new Ref<String>();
+
+    Runnable command = new Runnable() {
+      public void run() {
+        SimpleCredentialsDialog dialog = new SimpleCredentialsDialog(project);
+        dialog.setup(mode, repositoryUrl.toDecodedString(), key, true);
+        dialog.setTitle(SvnBundle.message("dialog.title.authentication.required"));
+        dialog.show();
+        if (dialog.isOK()) {
+          answer.set(dialog.getPassword());
+        }
+        // TODO: Correctly handle "cancel" - kill the process
+        // TODO: and perform "cleanup" on working copy
+      }
+    };
+
+    WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(command);
+
+    if (!answer.isNull()) {
+      sendAnswer(answer.get());
+    } else {
+      myExecutor.destroyProcess("Authentication canceled for repository: " + repositoryUrl);
+    }
+
+    return !answer.isNull();
+  }
+
+  private boolean sendAnswer(@NotNull String answer) {
+    try {
+      myExecutor.write(answer + "\n");
+      return true;
+    }
+    catch (SvnBindException e) {
+      // TODO: handle this more carefully
+      LOG.info(e);
+    }
+    return false;
+  }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/ServerSSHDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/ServerSSHDialog.java
index 30ef521..54e0265 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/ServerSSHDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/ServerSSHDialog.java
@@ -17,6 +17,7 @@
 
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.text.StringUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.SvnBundle;
@@ -41,12 +42,20 @@
 
   public ServerSSHDialog(Project project, boolean store, @NotNull final String host, @Nullable final String algorithm,
                          @NotNull final byte[] fingerprints) {
+    this(project, store, host, algorithm, SVNSSLUtil.getFingerprint(fingerprints, "SHA1"));
+  }
+
+  public ServerSSHDialog(Project project,
+                         boolean store,
+                         @NotNull final String host,
+                         @Nullable final String algorithm,
+                         @NotNull String fingerprints) {
     super(project, true);
     myStore = store;
     myHost = host;
-    myAlgorithm = algorithm == null ? "" : algorithm;
+    myAlgorithm = StringUtil.notNullize(algorithm);
     // todo ?
-    myFingerprints = SVNSSLUtil.getFingerprint(fingerprints, "SHA1");
+    myFingerprints = fingerprints;
     myResult = ISVNAuthenticationProvider.REJECTED;
     setOKButtonText(SvnBundle.message("button.text.ssh.accept"));
     setCancelButtonText(SvnBundle.message("button.text.ssh.reject"));
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SimpleCredentialsDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SimpleCredentialsDialog.java
index 3c11acb..f779c0c 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SimpleCredentialsDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SimpleCredentialsDialog.java
@@ -34,6 +34,7 @@
 public class SimpleCredentialsDialog extends DialogWrapper implements DocumentListener {
   private boolean myAllowSave;
   private String myUserName;
+  private Mode myMode;
 
   private String myRealm;
   private JTextField myUserNameText;
@@ -42,18 +43,24 @@
 
   @NonNls private static final String HELP_ID = "vcs.subversion.authentication";
 
-  protected SimpleCredentialsDialog(Project project) {
+  public SimpleCredentialsDialog(Project project) {
     super(project, true);
     setResizable(false);
   }
 
   public void setup(String realm, String userName, boolean allowSave) {
+    setup(Mode.DEFAULT, realm, userName, allowSave);
+  }
+
+  public void setup(Mode mode, String realm, String userName, boolean allowSave) {
+    myMode = mode;
     myRealm = realm;
     myUserName = userName;
     myAllowSave = allowSave;
     getHelpAction().setEnabled(true);
     init();
   }
+
   protected void doHelpAction() {
     HelpManager.getInstance().invokeHelp(HELP_ID);
   }
@@ -89,7 +96,7 @@
     gb.weightx = 0;
     gb.fill = GridBagConstraints.NONE;
 
-    label = new JLabel(SvnBundle.message("label.auth.user.name"));
+    label = new JLabel(SvnBundle.message(myMode.equals(Mode.SSH_PASSPHRASE) ? "label.ssh.key.file" : "label.auth.user.name"));
     panel.add(label, gb);
 
     // user name field
@@ -106,6 +113,7 @@
     }
     myUserNameText.selectAll();
     myUserNameText.getDocument().addDocumentListener(this);
+    myUserNameText.setEnabled(myMode.equals(Mode.DEFAULT));
 
     gb.gridy += 1;
     gb.weightx = 0;
@@ -113,7 +121,7 @@
     gb.fill = GridBagConstraints.NONE;
     gb.gridwidth = 1;
 
-    label = new JLabel(SvnBundle.message("label.auth.password"));
+    label = new JLabel(SvnBundle.message(myMode.equals(Mode.SSH_PASSPHRASE) ? "label.ssh.passphrase" : "label.auth.password"));
     panel.add(label, gb);
 
     // passworde field
@@ -152,7 +160,7 @@
   }
 
   public JComponent getPreferredFocusedComponent() {
-    return myUserNameText;
+    return myUserNameText.isEnabled() ? myUserNameText : myPasswordText;
   }
 
   public boolean shouldCloseOnCross() {
@@ -197,4 +205,10 @@
   private void updateOKButton() {
     getOKAction().setEnabled(isOKActionEnabled());
   }
+
+  public enum Mode {
+    SSH_PASSPHRASE,
+    SSH_PASSWORD,
+    DEFAULT
+  }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/ToBeMergedDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/ToBeMergedDialog.java
index 620bc38..19a8832 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/ToBeMergedDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/ToBeMergedDialog.java
@@ -296,7 +296,7 @@
     myRevisionsList.setShowGrid(false);
     final AbstractBaseTagMouseListener mouseListener = new AbstractBaseTagMouseListener() {
       @Override
-      protected Object getTagAt(MouseEvent e) {
+      public Object getTagAt(MouseEvent e) {
         Object tag = null;
         JTable table = (JTable)e.getSource();
         int row = table.rowAtPoint(e.getPoint());
diff --git a/plugins/svn4idea/svn4idea.iml b/plugins/svn4idea/svn4idea.iml
index 53dd661..1765d1a 100644
--- a/plugins/svn4idea/svn4idea.iml
+++ b/plugins/svn4idea/svn4idea.iml
@@ -76,6 +76,9 @@
         </SOURCES>
       </library>
     </orderEntry>
+    <orderEntry type="library" name="jna" level="project" />
+    <orderEntry type="library" name="pty4j" level="project" />
+    <orderEntry type="library" name="purejavacomm" level="project" />
   </component>
 </module>
 
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackIntellisense.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackIntellisense.java
index 3b2eaf0..609a8d7 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackIntellisense.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackIntellisense.java
@@ -56,7 +56,7 @@
     private final int myMaxSize;
 
     private SizeLimitedCache(int max) {
-      super((int)(max / 0.75) + 1);
+      super((int)(max / 0.75) + 1, true);
       myMaxSize = max;
     }
 
diff --git a/plugins/terminal/lib/jediterm-pty-0.08.jar b/plugins/terminal/lib/jediterm-pty-0.08.jar
deleted file mode 100644
index a801f88..0000000
--- a/plugins/terminal/lib/jediterm-pty-0.08.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/terminal/lib/jediterm-pty-1.0.jar b/plugins/terminal/lib/jediterm-pty-1.0.jar
new file mode 100644
index 0000000..bb04f22
--- /dev/null
+++ b/plugins/terminal/lib/jediterm-pty-1.0.jar
Binary files differ
diff --git a/plugins/terminal/lib/readme.txt b/plugins/terminal/lib/jediterm.txt
similarity index 100%
rename from plugins/terminal/lib/readme.txt
rename to plugins/terminal/lib/jediterm.txt
diff --git a/plugins/terminal/resources/META-INF/terminal.xml b/plugins/terminal/resources/META-INF/terminal.xml
index 36500b8..ed2a2b5 100644
--- a/plugins/terminal/resources/META-INF/terminal.xml
+++ b/plugins/terminal/resources/META-INF/terminal.xml
@@ -12,6 +12,8 @@
                 factoryClass="org.jetbrains.plugins.terminal.TerminalToolWindowFactory" secondary="false"/>
 
     <projectConfigurable instance="org.jetbrains.plugins.terminal.TerminalOptionsConfigurable"/>
+
+    <fileEditorProvider implementation="org.jetbrains.plugins.terminal.vfs.TerminalSessionEditorProvider"/>
   </extensions>
 
   <project-components>
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
index 5a3b607..121958b 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
@@ -7,6 +7,7 @@
 import com.intellij.execution.process.ProcessHandler;
 import com.intellij.execution.ui.RunContentDescriptor;
 import com.intellij.execution.ui.actions.CloseAction;
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.*;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.progress.ProgressIndicator;
@@ -82,15 +83,16 @@
 
   protected abstract ProcessHandler createProcessHandler(T process);
 
-  public JBTabbedTerminalWidget createTerminalWidget() {
+  @NotNull
+  public JBTabbedTerminalWidget createTerminalWidget(@NotNull Disposable parent) {
     final JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider();
-    JBTabbedTerminalWidget terminalWidget = new JBTabbedTerminalWidget(provider, new Predicate<TerminalWidget>() {
+    JBTabbedTerminalWidget terminalWidget = new JBTabbedTerminalWidget(myProject, provider, new Predicate<TerminalWidget>() {
       @Override
       public boolean apply(TerminalWidget widget) {
         openSession(widget);
         return true;
       }
-    });
+    }, parent);
     openSession(terminalWidget);
     return terminalWidget;
   }
@@ -100,21 +102,12 @@
     final DefaultActionGroup toolbarActions = new DefaultActionGroup();
     final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, false);
 
-    final JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider();
-    TerminalWidget widget = new JBTabbedTerminalWidget(provider, new Predicate<TerminalWidget>() {
-      @Override
-      public boolean apply(TerminalWidget widget) {
-        openSession(widget);
-        return true;
-      }
-    });
-
-    openSession(widget, createTtyConnector(process));
+    
 
     final JPanel panel = new JPanel(new BorderLayout());
     panel.add(actionToolbar.getComponent(), BorderLayout.WEST);
 
-    panel.add(widget.getComponent(), BorderLayout.CENTER);
+    
 
     actionToolbar.setTargetComponent(panel);
 
@@ -127,6 +120,19 @@
 
     toolbarActions.add(createCloseAction(defaultExecutor, contentDescriptor));
 
+    final JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider();
+    TerminalWidget widget = new JBTabbedTerminalWidget(myProject, provider, new Predicate<TerminalWidget>() {
+      @Override
+      public boolean apply(TerminalWidget widget) {
+        openSession(widget);
+        return true;
+      }
+    }, contentDescriptor);
+
+    openSession(widget, createTtyConnector(process));
+
+    panel.add(widget.getComponent(), BorderLayout.CENTER);
+
     showConsole(defaultExecutor, contentDescriptor, widget.getComponent());
 
     processHandler.startNotify();
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
index d46e858..f714c38 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
@@ -1,34 +1,60 @@
 package org.jetbrains.plugins.terminal;
 
 import com.google.common.base.Predicate;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.fileEditor.impl.EditorTabbedContainer;
+import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
 import com.intellij.openapi.project.DumbAwareAction;
-import com.jediterm.terminal.ui.JediTermWidget;
-import com.jediterm.terminal.ui.TabbedTerminalWidget;
-import com.jediterm.terminal.ui.TerminalAction;
-import com.jediterm.terminal.ui.TerminalWidget;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.ui.SimpleColoredComponent;
+import com.intellij.ui.components.JBTextField;
+import com.intellij.ui.docking.DockManager;
+import com.intellij.ui.docking.DragSession;
+import com.intellij.ui.tabs.TabInfo;
+import com.intellij.ui.tabs.TabsListener;
+import com.intellij.ui.tabs.impl.JBEditorTabs;
+import com.intellij.ui.tabs.impl.JBTabsImpl;
+import com.intellij.ui.tabs.impl.TabLabel;
+import com.jediterm.terminal.ui.*;
 import com.jediterm.terminal.ui.settings.SettingsProvider;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.terminal.vfs.TerminalSessionVirtualFileImpl;
 
 import javax.swing.*;
-import java.awt.event.KeyEvent;
+import java.awt.*;
+import java.awt.event.*;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArraySet;
 
 /**
  * @author traff
  */
-public class JBTabbedTerminalWidget extends TabbedTerminalWidget {
+public class JBTabbedTerminalWidget extends TabbedTerminalWidget implements Disposable{
 
+  private Project myProject;
   private final JBTerminalSystemSettingsProvider mySettingsProvider;
+  private Disposable myParent;
 
-  public JBTabbedTerminalWidget(@NotNull JBTerminalSystemSettingsProvider settingsProvider, @NotNull Predicate<TerminalWidget> createNewSessionAction) {
+  public JBTabbedTerminalWidget(@NotNull Project project,
+                                @NotNull JBTerminalSystemSettingsProvider settingsProvider,
+                                @NotNull Predicate<TerminalWidget> createNewSessionAction, @NotNull Disposable parent) {
     super(settingsProvider, createNewSessionAction);
-    
+    myProject = project;
+
     mySettingsProvider = settingsProvider;
+    myParent = parent;
 
     convertActions(this, getActions());
+
+    Disposer.register(parent, this);
+    Disposer.register(this, settingsProvider);
   }
 
   public static void convertActions(@NotNull JComponent component,
@@ -57,6 +83,300 @@
 
   @Override
   protected JediTermWidget createInnerTerminalWidget(SettingsProvider settingsProvider) {
-    return new JBTerminalWidget(mySettingsProvider);
+    return new JBTerminalWidget(mySettingsProvider, myParent);
+  }
+
+  @Override
+  protected TerminalTabs createTabbedPane() {
+    return new JBTerminalTabs(myProject, myParent);
+  }
+
+  public class JBTerminalTabs implements TerminalTabs {
+    private final JBEditorTabs myTabs;
+
+    private TabInfo.DragOutDelegate myDragDelegate = new MyDragOutDelegate();
+
+    private final CopyOnWriteArraySet<TabChangeListener> myListeners = new CopyOnWriteArraySet<TabChangeListener>();
+
+    public JBTerminalTabs(@NotNull Project project, @NotNull Disposable parent) {
+      final ActionManager actionManager = ActionManager.getInstance();
+      myTabs = new JBEditorTabs(project, actionManager, IdeFocusManager.getInstance(project), parent) {
+        @Override
+        protected TabLabel createTabLabel(TabInfo info) {
+          return new TerminalTabLabel(this, info);
+        }
+      };
+
+      myTabs.addListener(new TabsListener.Adapter() {
+        @Override
+        public void selectionChanged(TabInfo oldSelection, TabInfo newSelection) {
+          for (TabChangeListener each : myListeners) {
+            each.selectionChanged();
+          }
+        }
+
+        @Override
+        public void tabRemoved(TabInfo tabInfo) {
+          for (TabChangeListener each : myListeners) {
+            each.tabRemoved();
+          }
+        }
+      });
+
+      myTabs.setTabDraggingEnabled(true);
+    }
+
+    @Override
+    public int getSelectedIndex() {
+      return myTabs.getIndexOf(myTabs.getSelectedInfo());
+    }
+
+    @Override
+    public void setSelectedIndex(int index) {
+      myTabs.select(myTabs.getTabAt(index), true);
+    }
+
+    @Override
+    public void setTabComponentAt(int index, Component component) {
+      //nop
+    }
+
+    @Override
+    public int indexOfTabComponent(Component component) {
+      return 0; //nop
+    }
+
+
+    private TabInfo getTabAt(int index) {
+      checkIndex(index);
+      return myTabs.getTabAt(index);
+    }
+
+    private void checkIndex(int index) {
+      if (index < 0 || index >= getTabCount()) {
+        throw new ArrayIndexOutOfBoundsException("tabCount=" + getTabCount() + " index=" + index);
+      }
+    }
+
+
+    @Override
+    public JediTermWidget getComponentAt(int i) {
+      return (JediTermWidget)getTabAt(i).getComponent();
+    }
+
+    @Override
+    public void addChangeListener(TabChangeListener listener) {
+      myListeners.add(listener);
+    }
+
+    @Override
+    public void setTitleAt(int index, String title) {
+      getTabAt(index).setText(title);
+    }
+
+    @Override
+    public void setSelectedComponent(JediTermWidget terminal) {
+      TabInfo info = myTabs.findInfo(terminal);
+      if (info != null) {
+        myTabs.select(info, true);
+      }
+    }
+
+    @Override
+    public JComponent getComponent() {
+      return myTabs.getComponent();
+    }
+
+    @Override
+    public int getTabCount() {
+      return myTabs.getTabCount();
+    }
+
+    @Override
+    public void addTab(String name, JediTermWidget terminal) {
+      myTabs.addTab(createTabInfo(name, terminal));
+    }
+
+    private TabInfo createTabInfo(String name, JediTermWidget terminal) {
+      TabInfo tabInfo = new TabInfo(terminal).setText(name).setDragOutDelegate(myDragDelegate);
+      return tabInfo
+        .setObject(new TerminalSessionVirtualFileImpl(tabInfo, terminal, mySettingsProvider));
+    }
+
+    public String getTitleAt(int i) {
+      return getTabAt(i).getText();
+    }
+
+    public void removeAll() {
+      myTabs.removeAllTabs();
+    }
+
+    @Override
+    public void remove(JediTermWidget terminal) {
+      TabInfo info = myTabs.findInfo(terminal);
+      if (info != null) {
+        myTabs.removeTab(info);
+      }
+    }
+
+    private class TerminalTabLabel extends TabLabel {
+      public TerminalTabLabel(final JBTabsImpl tabs, TabInfo info) {
+        super(tabs, info);
+
+        setOpaque(false);
+
+        setFocusable(false);
+
+        SimpleColoredComponent label = myLabel;
+
+        //add more space between the label and the button
+        label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
+
+        label.addMouseListener(new MouseAdapter() {
+
+          @Override
+          public void mouseReleased(MouseEvent event) {
+            handleMouse(event);
+          }
+
+          @Override
+          public void mousePressed(MouseEvent event) {
+            handleMouse(event);
+          }
+
+          private void handleMouse(MouseEvent event) {
+            if (event.isPopupTrigger()) {
+              JPopupMenu menu = createPopup();
+              menu.show(event.getComponent(), event.getX(), event.getY());
+            }
+            else {
+              myTabs.select(getInfo(), true);
+
+              if (event.getClickCount() == 2 && !event.isConsumed()) {
+                event.consume();
+                renameTab();
+              }
+            }
+          }
+        });
+      }
+
+      protected JPopupMenu createPopup() {
+        JPopupMenu popupMenu = new JPopupMenu();
+
+        TerminalAction.addToMenu(popupMenu, JBTabbedTerminalWidget.this);
+
+        JMenuItem rename = new JMenuItem("Rename Tab");
+
+        rename.addActionListener(new ActionListener() {
+          @Override
+          public void actionPerformed(ActionEvent actionEvent) {
+            renameTab();
+          }
+        });
+
+        popupMenu.add(rename);
+
+        return popupMenu;
+      }
+
+      private void renameTab() {
+        new TabRenamer() {
+          @Override
+          protected JTextField createTextField() {
+            JBTextField textField = new JBTextField() {
+              private int myMinimalWidth;
+
+              @Override
+              public Dimension getPreferredSize() {
+                Dimension size = super.getPreferredSize();
+                if (size.width > myMinimalWidth) {
+                  myMinimalWidth = size.width;
+                }
+
+                return wider(size, myMinimalWidth);
+              }
+
+              private Dimension wider(Dimension size, int minimalWidth) {
+                return new Dimension(minimalWidth + 10, size.height);
+              }
+            };
+            textField.setOpaque(true);
+            return textField;
+          }
+        }.install(getSelectedIndex(), getInfo().getText(), myLabel, new TabRenamer.RenameCallBack() {
+          @Override
+          public void setComponent(Component c) {
+            myTabs.setTabDraggingEnabled(!(c instanceof JBTextField));
+
+            setPlaceholderContent(true, (JComponent)c);
+          }
+
+          @Override
+          public void setNewName(int index, String name) {
+            setTitleAt(index, name);
+          }
+        });
+      }
+    }
+
+    class MyDragOutDelegate implements TabInfo.DragOutDelegate {
+
+      private TerminalSessionVirtualFileImpl myFile;
+      private DragSession mySession;
+
+      @Override
+      public void dragOutStarted(MouseEvent mouseEvent, TabInfo info) {
+        final TabInfo previousSelection = info.getPreviousSelection();
+        final Image img = JBTabsImpl.getComponentImage(info);
+        info.setHidden(true);
+        if (previousSelection != null) {
+          myTabs.select(previousSelection, true);
+        }
+
+        myFile = (TerminalSessionVirtualFileImpl)info.getObject();
+        Presentation presentation = new Presentation(info.getText());
+        presentation.setIcon(info.getIcon());
+        mySession = getDockManager()
+          .createDragSession(mouseEvent, new EditorTabbedContainer.DockableEditor(myProject, img, myFile, presentation,
+                                                                                  info.getComponent().getPreferredSize(), false));
+      }
+
+      private DockManager getDockManager() {
+        return DockManager.getInstance(myProject);
+      }
+
+      @Override
+      public void processDragOut(MouseEvent event, TabInfo source) {
+        mySession.process(event);
+      }
+
+      @Override
+      public void dragOutFinished(MouseEvent event, TabInfo source) {
+        myFile.putUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN, Boolean.TRUE);
+        
+        
+        myTabs.removeTab(source);
+        
+        mySession.process(event);
+
+        myFile.putUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN, null);
+        
+
+        myFile = null;
+        mySession = null;
+      }
+
+      @Override
+      public void dragOutCancelled(TabInfo source) {
+        source.setHidden(false);
+        if (mySession != null) {
+          mySession.cancel();
+        }
+
+        myFile = null;
+        mySession = null;
+      }
+    }
   }
 }
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
index 1ae988d..767df1e 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
@@ -22,6 +22,7 @@
 import com.google.common.base.Predicate;
 import com.intellij.ide.GeneralSettings;
 import com.intellij.ide.ui.UISettings;
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.*;
 import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry;
 import com.intellij.openapi.editor.impl.FontInfo;
@@ -52,7 +53,7 @@
 import java.awt.image.ImageObserver;
 import java.io.IOException;
 
-public class JBTerminalPanel extends TerminalPanel implements FocusListener {
+public class JBTerminalPanel extends TerminalPanel implements FocusListener, TerminalSettingsListener, Disposable {
   private final JBTerminalSystemSettingsProvider mySettingsProvider;
 
   public JBTerminalPanel(@NotNull JBTerminalSystemSettingsProvider settingsProvider,
@@ -73,6 +74,8 @@
     registerKeymapActions(this);
 
     addFocusListener(this);
+    
+    mySettingsProvider.addListener(this);
   }
 
   private static void registerKeymapActions(final TerminalPanel terminalPanel) {
@@ -200,5 +203,15 @@
   public FontInfo fontForChar(final char c, @JdkConstants.FontStyle int style) {
     return ComplementaryFontsRegistry.getFontAbleToDisplay(c, style, mySettingsProvider.getColorScheme().getConsoleFontPreferences());
   }
+
+  @Override
+  public void fontChanged() {
+    reinitFontAndResize();
+  }
+
+  @Override
+  public void dispose() {
+    mySettingsProvider.removeListener(this);
+  }
 }
 
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
index f2fe5dd..4adeb3c 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
@@ -1,8 +1,10 @@
 package org.jetbrains.plugins.terminal;
 
-import com.intellij.application.options.OptionsConstants;
+import com.google.common.collect.Sets;
 import com.intellij.execution.ui.ConsoleViewContentType;
 import com.intellij.ide.ui.UISettings;
+import com.intellij.ide.ui.UISettingsListener;
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.KeyboardShortcut;
 import com.intellij.openapi.actionSystem.Shortcut;
 import com.intellij.openapi.editor.colors.*;
@@ -25,20 +27,37 @@
 
 import javax.swing.*;
 import java.awt.*;
-import java.util.ArrayList;
-import java.util.EnumMap;
+import java.util.*;
 import java.util.List;
-import java.util.Map;
 
 /**
  * @author traff
  */
-class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider {
-
-  private final EditorColorsScheme myColorScheme;
+class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider implements Disposable {
+  private Set<TerminalSettingsListener> myListeners = Sets.newHashSet();
+  
+  private final MyColorSchemeDelegate myColorScheme;
 
   JBTerminalSystemSettingsProvider() {
     myColorScheme = createBoundColorSchemeDelegate(null);
+
+    UISettings.getInstance().addUISettingsListener(new UISettingsListener() {
+      @Override
+      public void uiSettingsChanged(UISettings source) {
+        int size;
+        if (UISettings.getInstance().PRESENTATION_MODE) {
+          size = UISettings.getInstance().PRESENTATION_MODE_FONT_SIZE;
+        }
+        else {
+          size = myColorScheme.getGlobal().getConsoleFontSize();
+        }
+
+        if (myColorScheme.getConsoleFontSize() != size) {
+          myColorScheme.setConsoleFontSize(size);
+          fireFontChanged();
+        }
+      }
+    }, this);
   }
 
   @Override
@@ -52,6 +71,16 @@
   }
 
   @Override
+  public KeyStroke[] getNextTabKeyStrokes() {
+    return getKeyStrokesByActionId("NextTab");
+  }
+
+  @Override
+  public KeyStroke[] getPreviousTabKeyStrokes() {
+    return getKeyStrokesByActionId("PreviousTab");
+  }
+
+  @Override
   public ColorPalette getTerminalColorPalette() {
     return new JBTerminalSchemeColorPalette(myColorScheme);
   }
@@ -181,10 +210,15 @@
   }
 
   @NotNull
-  public EditorColorsScheme createBoundColorSchemeDelegate(@Nullable final EditorColorsScheme customGlobalScheme) {
+  private static MyColorSchemeDelegate createBoundColorSchemeDelegate(@Nullable final EditorColorsScheme customGlobalScheme) {
     return new MyColorSchemeDelegate(customGlobalScheme);
   }
 
+  @Override
+  public void dispose() {
+
+  }
+
   private static class MyColorSchemeDelegate implements EditorColorsScheme {
 
     private final FontPreferences myFontPreferences = new FontPreferences();
@@ -192,14 +226,15 @@
     private final HashMap<ColorKey, Color> myOwnColors = new HashMap<ColorKey, Color>();
     private final EditorColorsScheme myCustomGlobalScheme;
     private Map<EditorFontType, Font> myFontsMap = null;
-    private int myMaxFontSize = OptionsConstants.MAX_EDITOR_FONT_SIZE;
-    private int myFontSize = -1;
     private String myFaceName = null;
     private EditorColorsScheme myGlobalScheme;
 
+    private int myConsoleFontSize = -1;
+
     private MyColorSchemeDelegate(@Nullable final EditorColorsScheme globalScheme) {
       myCustomGlobalScheme = globalScheme;
       updateGlobalScheme();
+      initFonts();
     }
 
     private EditorColorsScheme getGlobal() {
@@ -213,17 +248,17 @@
 
 
     protected void initFonts() {
-      String editorFontName = getEditorFontName();
-      int editorFontSize = getEditorFontSize();
+      String consoleFontName = getConsoleFontName();
+      int consoleFontSize = getConsoleFontSize();
       myFontPreferences.clear();
-      myFontPreferences.register(editorFontName, editorFontSize);
+      myFontPreferences.register(consoleFontName, consoleFontSize);
 
       myFontsMap = new EnumMap<EditorFontType, Font>(EditorFontType.class);
 
-      Font plainFont = new Font(editorFontName, Font.PLAIN, editorFontSize);
-      Font boldFont = new Font(editorFontName, Font.BOLD, editorFontSize);
-      Font italicFont = new Font(editorFontName, Font.ITALIC, editorFontSize);
-      Font boldItalicFont = new Font(editorFontName, Font.BOLD | Font.ITALIC, editorFontSize);
+      Font plainFont = new Font(consoleFontName, Font.PLAIN, consoleFontSize);
+      Font boldFont = new Font(consoleFontName, Font.BOLD, consoleFontSize);
+      Font italicFont = new Font(consoleFontName, Font.ITALIC, consoleFontSize);
+      Font boldItalicFont = new Font(consoleFontName, Font.BOLD | Font.ITALIC, consoleFontSize);
 
       myFontsMap.put(EditorFontType.PLAIN, plainFont);
       myFontsMap.put(EditorFontType.BOLD, boldFont);
@@ -274,29 +309,22 @@
     @NotNull
     @Override
     public FontPreferences getFontPreferences() {
-      return myFontPreferences;
+      return myGlobalScheme.getFontPreferences();
     }
 
     @Override
     public void setFontPreferences(@NotNull FontPreferences preferences) {
-      preferences.copyTo(myFontPreferences);
-      initFonts();
+      throw new IllegalStateException();      
     }
 
     @Override
     public int getEditorFontSize() {
-      if (myFontSize == -1) {
-        return getGlobal().getEditorFontSize();
-      }
-      return myFontSize;
+      return getGlobal().getEditorFontSize();
     }
 
     @Override
     public void setEditorFontSize(int fontSize) {
-      if (fontSize < 8) fontSize = 8;
-      if (fontSize > myMaxFontSize) fontSize = myMaxFontSize;
-      myFontSize = fontSize;
-      initFonts();
+
     }
 
     @Override
@@ -311,16 +339,12 @@
 
     @Override
     public String getEditorFontName() {
-      if (myFaceName == null) {
-        return getGlobal().getEditorFontName();
-      }
-      return myFaceName;
+      return getGlobal().getEditorFontName();
     }
 
     @Override
     public void setEditorFontName(String fontName) {
-      myFaceName = fontName;
-      initFonts();
+      throw new IllegalStateException();
     }
 
     @Override
@@ -366,39 +390,50 @@
 
     public void updateGlobalScheme() {
       myGlobalScheme = myCustomGlobalScheme == null ? EditorColorsManager.getInstance().getGlobalScheme() : myCustomGlobalScheme;
-      int globalFontSize = getGlobal().getEditorFontSize();
-      myMaxFontSize = Math.max(OptionsConstants.MAX_EDITOR_FONT_SIZE, globalFontSize);
     }
 
     @NotNull
     @Override
     public FontPreferences getConsoleFontPreferences() {
-      return getGlobal().getConsoleFontPreferences();
+      return myFontPreferences;
     }
 
     @Override
     public void setConsoleFontPreferences(@NotNull FontPreferences preferences) {
-      getGlobal().setConsoleFontPreferences(preferences);
+      preferences.copyTo(myFontPreferences);
+      initFonts();
     }
 
     @Override
     public String getConsoleFontName() {
-      return getGlobal().getConsoleFontName();
+      if (myFaceName == null) {
+        return getGlobal().getConsoleFontName();
+      }
+      else {
+        return myFaceName;
+      }
     }
 
     @Override
     public void setConsoleFontName(String fontName) {
-      getGlobal().setConsoleFontName(fontName);
+      myFaceName = fontName;
+      initFonts();
     }
 
     @Override
     public int getConsoleFontSize() {
-      return getGlobal().getConsoleFontSize();
+      if (myConsoleFontSize == -1) {
+        return getGlobal().getConsoleFontSize();
+      }
+      else {
+        return myConsoleFontSize;
+      }
     }
 
     @Override
     public void setConsoleFontSize(int fontSize) {
-      getGlobal().setConsoleFontSize(fontSize);
+      myConsoleFontSize = fontSize;
+      initFonts();
     }
 
     @Override
@@ -411,4 +446,18 @@
       getGlobal().setConsoleLineSpacing(lineSpacing);
     }
   }
+
+  public void addListener(TerminalSettingsListener listener) {
+    myListeners.add(listener);
+  }
+
+  public void removeListener(TerminalSettingsListener listener) {
+    myListeners.remove(listener);
+  }
+
+  public void fireFontChanged() {
+    for (TerminalSettingsListener l : myListeners) {
+      l.fontChanged();
+    }
+  }
 }
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java
index 3150cc9..79d8bfe 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java
@@ -1,5 +1,7 @@
 package org.jetbrains.plugins.terminal;
 
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Disposer;
 import com.intellij.ui.components.JBScrollBar;
 import com.jediterm.terminal.TerminalStarter;
 import com.jediterm.terminal.TtyConnector;
@@ -12,19 +14,23 @@
 
 import javax.swing.*;
 
-public class JBTerminalWidget extends JediTermWidget {
+public class JBTerminalWidget extends JediTermWidget implements Disposable{
 
-  public JBTerminalWidget(JBTerminalSystemSettingsProvider settingsProvider) {
+  public JBTerminalWidget(JBTerminalSystemSettingsProvider settingsProvider, Disposable parent) {
     super(settingsProvider);
 
     JBTabbedTerminalWidget.convertActions(this, getActions());
+
+    Disposer.register(parent, this);
   }
 
   @Override
   protected JBTerminalPanel createTerminalPanel(@NotNull SettingsProvider settingsProvider,
                                                 @NotNull StyleState styleState,
                                                 @NotNull BackBuffer backBuffer) {
-    return new JBTerminalPanel((JBTerminalSystemSettingsProvider)settingsProvider, backBuffer, styleState);
+    JBTerminalPanel panel = new JBTerminalPanel((JBTerminalSystemSettingsProvider)settingsProvider, backBuffer, styleState);
+    Disposer.register(this, panel);
+    return panel;
   }
 
   @Override
@@ -36,4 +42,8 @@
   protected JScrollBar createScrollBar() {
     return new JBScrollBar();
   }
+
+  @Override
+  public void dispose() {
+  }
 }
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java
index 3659634..4d93dd9 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java
@@ -3,14 +3,12 @@
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.wm.ToolWindow;
 import com.intellij.openapi.wm.ToolWindowManager;
 import icons.TerminalIcons;
-import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * @author traff
@@ -48,16 +46,8 @@
     }, true);
   }
 
-  @Nullable
+  @NotNull
   public static LocalTerminalDirectRunner createTerminalRunner(Project project) {
-    String[] terminalCommand;
-    if (SystemInfo.isWindows) {
-      terminalCommand = new String[]{"cmd.exe"};
-    }
-    else {
-      terminalCommand = new String[]{"/bin/bash", "--login"};
-    }
-
     return new LocalTerminalDirectRunner(project);
   }
 }
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsListener.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsListener.java
new file mode 100644
index 0000000..7569880
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsListener.java
@@ -0,0 +1,8 @@
+package org.jetbrains.plugins.terminal;
+
+/**
+ * @author traff
+ */
+public interface TerminalSettingsListener {
+  void fontChanged();
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
index c3f49f9..14b992a 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
@@ -4,7 +4,6 @@
 import com.intellij.notification.EventLog;
 import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.*;
-import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.SimpleToolWindowPanel;
@@ -13,8 +12,13 @@
 import com.intellij.openapi.wm.ToolWindowManager;
 import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
 import com.intellij.openapi.wm.ex.ToolWindowManagerListener;
+import com.intellij.ui.awt.RelativePoint;
+import com.intellij.ui.awt.RelativeRectangle;
 import com.intellij.ui.content.Content;
 import com.intellij.ui.content.ContentFactory;
+import com.intellij.ui.docking.DockContainer;
+import com.intellij.ui.docking.DockManager;
+import com.intellij.ui.docking.DockableContent;
 import com.intellij.util.ui.UIUtil;
 import com.jediterm.terminal.ui.JediTermWidget;
 import com.jediterm.terminal.ui.TabbedTerminalWidget;
@@ -22,6 +26,7 @@
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.terminal.vfs.TerminalSessionVirtualFileImpl;
 
 import javax.swing.*;
 import java.awt.*;
@@ -37,6 +42,8 @@
 
   private final Project myProject;
 
+  private TerminalDockContainer myDockContainer;
+
   public TerminalView(Project project) {
     myProject = project;
   }
@@ -52,22 +59,7 @@
     toolWindow.setToHideOnEmptyContent(true);
 
     if (terminalRunner != null) {
-      myTerminalWidget = terminalRunner.createTerminalWidget();
-      myTerminalWidget.addTabListener(new TabbedTerminalWidget.TabListener() {
-        @Override
-        public void tabClosed(JediTermWidget terminal) {
-          UIUtil.invokeLaterIfNeeded(new Runnable() {
-            @Override
-            public void run() {
-              hideIfNoActiveSessions(toolWindow, myTerminalWidget);
-            }
-          });
-        }
-      });
-    }
-
-    if (myTerminalWidget != null) {
-      Content content = createToolWindowContentPanel(terminalRunner, myTerminalWidget, toolWindow);
+      Content content = createTerminalInContentPanel(terminalRunner, toolWindow);
 
       toolWindow.getContentManager().addContent(content);
 
@@ -98,11 +90,17 @@
         }
       });
     }
+
+    if (myDockContainer == null) {
+      myDockContainer = new TerminalDockContainer(toolWindow);
+
+      Disposer.register(myProject, myDockContainer);
+      DockManager.getInstance(myProject).register(myDockContainer);
+    }
   }
 
-  private Content createToolWindowContentPanel(@Nullable LocalTerminalDirectRunner terminalRunner,
-                                               @NotNull JBTabbedTerminalWidget terminalWidget,
-                                               @NotNull ToolWindow toolWindow) {
+  private Content createTerminalInContentPanel(@Nullable LocalTerminalDirectRunner terminalRunner,
+                                               final @NotNull ToolWindow toolWindow) {
     SimpleToolWindowPanel panel = new SimpleToolWindowPanel(false, true) {
       @Override
       public Object getData(@NonNls String dataId) {
@@ -110,18 +108,34 @@
       }
     };
 
-    panel.setContent(terminalWidget.getComponent());
+    final Content content = ContentFactory.SERVICE.getInstance().createContent(panel, "", false);
+    content.setCloseable(true);
+
+    myTerminalWidget = terminalRunner.createTerminalWidget(content);
+    myTerminalWidget.addTabListener(new TabbedTerminalWidget.TabListener() {
+      @Override
+      public void tabClosed(JediTermWidget terminal) {
+        UIUtil.invokeLaterIfNeeded(new Runnable() {
+          @Override
+          public void run() {
+            if (myTerminalWidget != null) {
+              hideIfNoActiveSessions(toolWindow, myTerminalWidget);
+            }
+          }
+        });
+      }
+    });
+
+    panel.setContent(myTerminalWidget.getComponent());
     panel.addFocusListener(createFocusListener());
 
-    ActionToolbar toolbar = createToolbar(terminalRunner, terminalWidget, toolWindow);
+    ActionToolbar toolbar = createToolbar(terminalRunner, myTerminalWidget, toolWindow);
     toolbar.getComponent().addFocusListener(createFocusListener());
     toolbar.setTargetComponent(panel);
     panel.setToolbar(toolbar.getComponent());
 
-    final Content content = ContentFactory.SERVICE.getInstance().createContent(panel, "", false);
-    content.setCloseable(true);
 
-    content.setPreferredFocusableComponent(terminalWidget.getComponent());
+    content.setPreferredFocusableComponent(myTerminalWidget.getComponent());
 
     return content;
   }
@@ -152,11 +166,10 @@
     openSession(terminal, terminalRunner);
   }
 
-  private void openSession(ToolWindow toolWindow, AbstractTerminalRunner terminalRunner) {
+  private void openSession(@NotNull ToolWindow toolWindow, @NotNull AbstractTerminalRunner terminalRunner) {
     if (myTerminalWidget == null) {
-      myTerminalWidget = terminalRunner.createTerminalWidget();
       toolWindow.getContentManager().removeAllContents(true);
-      final Content content = createToolWindowContentPanel(null, myTerminalWidget, toolWindow);
+      final Content content = createTerminalInContentPanel(null, toolWindow);
       toolWindow.getContentManager().addContent(content);
     }
     else {
@@ -194,7 +207,7 @@
     }, true);
   }
 
-  private static void hideIfNoActiveSessions(final ToolWindow toolWindow, JBTabbedTerminalWidget terminal) {
+  private static void hideIfNoActiveSessions(@NotNull final ToolWindow toolWindow, @NotNull JBTabbedTerminalWidget terminal) {
     if (terminal.isNoActiveSessions()) {
       toolWindow.getContentManager().removeAllContents(true);
     }
@@ -234,4 +247,101 @@
       hideIfNoActiveSessions(myToolWindow, myTerminal);
     }
   }
+
+  /**
+   * @author traff
+   */
+  public class TerminalDockContainer implements DockContainer {
+    private ToolWindow myTerminalToolWindow;
+
+    public TerminalDockContainer(ToolWindow toolWindow) {
+      myTerminalToolWindow = toolWindow;
+    }
+
+    @Override
+    public RelativeRectangle getAcceptArea() {
+      return new RelativeRectangle(myTerminalToolWindow.getComponent());
+    }
+
+    @Override
+    public RelativeRectangle getAcceptAreaFallback() {
+      return getAcceptArea();
+    }
+
+    @NotNull
+    @Override
+    public ContentResponse getContentResponse(@NotNull DockableContent content, RelativePoint point) {
+      return isTerminalSessionContent(content) ? ContentResponse.ACCEPT_MOVE : ContentResponse.DENY;
+    }
+
+    @Override
+    public JComponent getContainerComponent() {
+      return myTerminalToolWindow.getComponent();
+    }
+
+    @Override
+    public void add(@NotNull DockableContent content, RelativePoint dropTarget) {
+      if (isTerminalSessionContent(content)) {
+        TerminalSessionVirtualFileImpl terminalFile = (TerminalSessionVirtualFileImpl)content.getKey();
+        myTerminalWidget.addTab(terminalFile.getName(), terminalFile.getTerminal());
+        terminalFile.getTerminal().setNextProvider(myTerminalWidget);
+      }
+    }
+
+    private boolean isTerminalSessionContent(DockableContent content) {
+      return content.getKey() instanceof TerminalSessionVirtualFileImpl;
+    }
+
+    @Override
+    public void closeAll() {
+
+    }
+
+    @Override
+    public void addListener(Listener listener, Disposable parent) {
+
+    }
+
+    @Override
+    public boolean isEmpty() {
+      return false;
+    }
+
+    @Nullable
+    @Override
+    public Image startDropOver(@NotNull DockableContent content, RelativePoint point) {
+      return null;
+    }
+
+    @Nullable
+    @Override
+    public Image processDropOver(@NotNull DockableContent content, RelativePoint point) {
+      return null;
+    }
+
+    @Override
+    public void resetDropOver(@NotNull DockableContent content) {
+
+    }
+
+    @Override
+    public boolean isDisposeWhenEmpty() {
+      return false;
+    }
+
+    @Override
+    public void showNotify() {
+
+    }
+
+    @Override
+    public void hideNotify() {
+
+    }
+
+    @Override
+    public void dispose() {
+
+    }
+  }
 }
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditor.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditor.java
new file mode 100644
index 0000000..5dc7b62
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditor.java
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.terminal.vfs;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Lists;
+import com.intellij.codeHighlighting.BackgroundEditorHighlighter;
+import com.intellij.ide.structureView.StructureViewBuilder;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorLocation;
+import com.intellij.openapi.fileEditor.FileEditorState;
+import com.intellij.openapi.fileEditor.FileEditorStateLevel;
+import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
+import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.UserDataHolderBase;
+import com.jediterm.terminal.TtyConnectorWaitFor;
+import com.jediterm.terminal.ui.TerminalAction;
+import com.jediterm.terminal.ui.TerminalActionProviderBase;
+import com.jediterm.terminal.ui.settings.TabbedSettingsProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.event.KeyEvent;
+import java.beans.PropertyChangeListener;
+import java.util.List;
+import java.util.concurrent.Executors;
+
+/**
+ * @author traff
+ */
+public class TerminalSessionEditor extends UserDataHolderBase implements FileEditor {
+
+  private Project myProject;
+  private final TerminalSessionVirtualFileImpl myFile;
+  private final TtyConnectorWaitFor myWaitFor;
+
+  public TerminalSessionEditor(Project project, @NotNull TerminalSessionVirtualFileImpl terminalFile) {
+    myProject = project;
+    myFile = terminalFile;
+
+    final TabbedSettingsProvider settings = myFile.getSettingsProvider();
+
+    myFile.getTerminal().setNextProvider(new TerminalActionProviderBase() {
+      @Override
+      public List<TerminalAction> getActions() {
+        return Lists.newArrayList(
+          new TerminalAction("Close Session", settings.getCloseSessionKeyStrokes(), new Predicate<KeyEvent>() {
+            @Override
+            public boolean apply(KeyEvent input) {
+              handleCloseSession();
+              return true;
+            }
+          }).withMnemonicKey(KeyEvent.VK_S)
+        );
+      }
+    });
+
+    myWaitFor = new TtyConnectorWaitFor(myFile.getTerminal().getTtyConnector(), Executors.newSingleThreadExecutor());
+
+    myWaitFor
+      .setTerminationCallback(new Predicate<Integer>() {
+        @Override
+        public boolean apply(Integer integer) {
+          ApplicationManager.getApplication().invokeLater(new Runnable() {
+            @Override
+            public void run() {
+              FileEditorManagerEx.getInstanceEx(myProject).closeFile(myFile);
+            }
+          });
+
+          return true;
+        }
+      });
+  }
+
+  private void handleCloseSession() {
+    myFile.getTerminal().close();
+  }
+
+  @NotNull
+  @Override
+  public JComponent getComponent() {
+    return myFile.getTerminal();
+  }
+
+  @Nullable
+  @Override
+  public JComponent getPreferredFocusedComponent() {
+    return myFile.getTerminal();
+  }
+
+  @NotNull
+  @Override
+  public String getName() {
+    return myFile.getName();
+  }
+
+  @NotNull
+  @Override
+  public FileEditorState getState(@NotNull FileEditorStateLevel level) {
+    return FileEditorState.INSTANCE;
+  }
+
+  @Override
+  public void setState(@NotNull FileEditorState state) {
+
+  }
+
+  @Override
+  public boolean isModified() {
+    return false;
+  }
+
+  @Override
+  public boolean isValid() {
+    return true;
+  }
+
+  @Override
+  public void selectNotify() {
+
+  }
+
+  @Override
+  public void deselectNotify() {
+
+  }
+
+  @Override
+  public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {
+
+  }
+
+  @Override
+  public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) {
+
+  }
+
+  @Nullable
+  @Override
+  public BackgroundEditorHighlighter getBackgroundHighlighter() {
+    return null;
+  }
+
+  @Nullable
+  @Override
+  public FileEditorLocation getCurrentLocation() {
+    return null;
+  }
+
+  @Nullable
+  @Override
+  public StructureViewBuilder getStructureViewBuilder() {
+    return null;
+  }
+
+  @Override
+  public void dispose() {
+    Boolean closingToReopen = myFile.getUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN);
+    myWaitFor.detach();
+    if (closingToReopen == null || !closingToReopen) {
+      myFile.getTerminal().close();
+    }
+  }
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditorProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditorProvider.java
new file mode 100644
index 0000000..cf1fd59
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditorProvider.java
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.terminal.vfs;
+
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorPolicy;
+import com.intellij.openapi.fileEditor.FileEditorProvider;
+import com.intellij.openapi.fileEditor.FileEditorState;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author traff
+ */
+public class TerminalSessionEditorProvider implements FileEditorProvider, DumbAware {
+  @Override
+  public boolean accept(@NotNull Project project, @NotNull VirtualFile file) {
+    return file instanceof TerminalSessionVirtualFileImpl;
+  }
+
+  @NotNull
+  @Override
+  public FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) {
+    return new TerminalSessionEditor(project, (TerminalSessionVirtualFileImpl)file);
+  }
+
+  @Override
+  public void disposeEditor(@NotNull FileEditor editor) {
+    Disposer.dispose(editor);
+  }
+
+  @NotNull
+  @Override
+  public FileEditorState readState(@NotNull Element sourceElement, @NotNull Project project, @NotNull VirtualFile file) {
+    return FileEditorState.INSTANCE;
+  }
+
+  @Override
+  public void writeState(@NotNull FileEditorState state, @NotNull Project project, @NotNull Element targetElement) {
+
+  }
+
+  @NotNull
+  @Override
+  public String getEditorTypeId() {
+    return "terminal-session-editor";
+  }
+
+  @NotNull
+  @Override
+  public FileEditorPolicy getPolicy() {
+    return FileEditorPolicy.HIDE_DEFAULT_EDITOR;
+  }
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionFileType.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionFileType.java
new file mode 100644
index 0000000..bb545a1
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionFileType.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.terminal.vfs;
+
+import com.intellij.openapi.fileTypes.ex.FakeFileType;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author traff
+ */
+public class TerminalSessionFileType extends FakeFileType {
+
+  public final static TerminalSessionFileType INSTANCE = new TerminalSessionFileType();
+
+  @NotNull
+  public String getName() {
+    return "Terminal Session";
+  }
+
+  @NotNull
+  public String getDescription() {
+    return getName() + " Fake File Type";
+  }
+
+  public boolean isMyFileType(VirtualFile file) {
+    return file instanceof TerminalSessionVirtualFileImpl;
+  }
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionVirtualFileImpl.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionVirtualFileImpl.java
new file mode 100644
index 0000000..b642f7f
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionVirtualFileImpl.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/**
+ * @author cdr
+ */
+package org.jetbrains.plugins.terminal.vfs;
+
+import com.intellij.testFramework.LightVirtualFile;
+import com.intellij.ui.tabs.TabInfo;
+import com.jediterm.terminal.ui.JediTermWidget;
+import com.jediterm.terminal.ui.settings.TabbedSettingsProvider;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author traff
+ */
+public class TerminalSessionVirtualFileImpl extends LightVirtualFile {
+  private final JediTermWidget myTerminal;
+  private TabbedSettingsProvider mySettingsProvider;
+
+  private final TabInfo myTabInfo;
+
+  public TerminalSessionVirtualFileImpl(@NotNull TabInfo tabInfo,
+                                        @NotNull JediTermWidget terminal,
+                                        @NotNull TabbedSettingsProvider settingsProvider) {
+    myTabInfo = tabInfo;
+    myTerminal = terminal;
+    mySettingsProvider = settingsProvider;
+    setFileType(TerminalSessionFileType.INSTANCE);
+    setWritable(true);
+  }
+
+  public JediTermWidget getTerminal() {
+    return myTerminal;
+  }
+
+  @NotNull
+  public String getName() {
+    return myTabInfo.getText();
+  }
+
+  public TabbedSettingsProvider getSettingsProvider() {
+    return mySettingsProvider;
+  }
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionsVFS.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionsVFS.java
new file mode 100644
index 0000000..b1439cc
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionsVFS.java
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+package org.jetbrains.plugins.terminal.vfs;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.project.ProjectManagerAdapter;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.openapi.vfs.ex.dummy.DummyFileSystem;
+import com.intellij.util.containers.BidirectionalMap;
+import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @author traff
+ */
+public class TerminalSessionsVFS extends DummyFileSystem {
+  @NonNls private static final String PROTOCOL = "terminalDummy";
+  @NonNls private static final String PATH_PREFIX = "terminal";
+  @NonNls private static final String PROTOCOL_SEPARATOR = ":/";
+  
+  private final BidirectionalMap<Project, String> myProject2Id = new BidirectionalMap<Project, String>();
+  private final Map<String, VirtualFile> myCachedFiles = new HashMap<String, VirtualFile>();
+
+  private ProjectManagerAdapter myProjectManagerListener;
+
+  public static TerminalSessionsVFS getTerminalSessionVFS() {
+    return (TerminalSessionsVFS)VirtualFileManager.getInstance().getFileSystem(PROTOCOL);
+  }
+
+  @Override
+  @Nullable
+  public VirtualFile createRoot(String name) {
+    return null;
+  }
+
+  public void initListener() {
+    if (myProjectManagerListener == null || ApplicationManager.getApplication().isUnitTestMode()) {
+      myCachedFiles.clear();
+      myProject2Id.clear();
+      for (Project project : ProjectManager.getInstance().getOpenProjects()) {
+        onProjectOpened(project);
+      }
+    }
+    if (myProjectManagerListener == null) {
+      myProjectManagerListener = new ProjectManagerAdapter() {
+        @Override
+        public void projectOpened(final Project project) {
+          onProjectOpened(project);
+        }
+
+        @Override
+        public void projectClosed(final Project project) {
+          onProjectClosed(project);
+        }
+      };
+      ProjectManager.getInstance().addProjectManagerListener(myProjectManagerListener);
+    }
+  }
+
+  public void onProjectClosed(final Project project) {
+    myCachedFiles.clear();
+    myProject2Id.remove(project);
+  }
+
+  public void onProjectOpened(final Project project) {
+    myProject2Id.put(project, project.getLocationHash());
+    StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() {
+      @Override
+      public void run() {
+//        DatabaseEditorHelper.installEditorFactoryListener(project); TODO:? 
+      }
+    });
+  }
+
+  @Override
+  public VirtualFile findFileByPath(@NotNull String path) {
+    throw new UnsupportedOperationException("not implemented yet"); //TODO: implement TerminalSessionManager and store there terminal sessions by handle ID
+  }
+
+  public static String getPath(Project project, final String dataSourceId, final String tableName, String typeName) {
+    return PATH_PREFIX + typeName + PROTOCOL_SEPARATOR + project.getLocationHash() + "/" + dataSourceId + "/" + tableName;
+  }
+
+  @Override
+  @NotNull
+  public String getProtocol() {
+    return PROTOCOL;
+  }
+
+  @Override
+  public boolean isReadOnly() {
+    return false;
+  }
+
+  @Override
+  public void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException {
+    throw new UnsupportedOperationException("renameFile not supported");
+  }
+
+  @Override
+  @NotNull
+  public String extractPresentableUrl(@NotNull String path) {
+    VirtualFile file = findFileByPath(path);
+    return file != null ? file.getPresentableName() : super.extractPresentableUrl(path);
+  }
+}
diff --git a/plugins/terminal/terminal.iml b/plugins/terminal/terminal.iml
index ce9ede1..f2d64268 100644
--- a/plugins/terminal/terminal.iml
+++ b/plugins/terminal/terminal.iml
@@ -13,7 +13,7 @@
     <orderEntry type="module-library">
       <library name="jediterm-pty">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/lib/jediterm-pty-0.08.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/jediterm-pty-1.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES />
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/DesignerToolWindow.java b/plugins/ui-designer-core/src/com/intellij/designer/DesignerToolWindow.java
index 3c8b155..6cafce8 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/DesignerToolWindow.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/DesignerToolWindow.java
@@ -39,7 +39,7 @@
 /**
  * @author Alexander Lobas
  */
-public final class DesignerToolWindow implements LightToolWindowContent {
+public final class DesignerToolWindow implements DesignerToolWindowContent {
   private final Splitter myToolWindowPanel;
   private ComponentTree myComponentTree;
   private ComponentTreeBuilder myTreeBuilder;
@@ -138,12 +138,14 @@
     return myPropertyTablePanel.getPropertyTable();
   }
 
+  @Override
   public void expandFromState() {
     if (myTreeBuilder != null) {
       myTreeBuilder.expandFromState();
     }
   }
 
+  @Override
   public void refresh(boolean updateProperties) {
     if (myTreeBuilder != null) {
       if (updateProperties) {
@@ -155,6 +157,7 @@
     }
   }
 
+  @Override
   public void updateInspections() {
     if (myComponentTree != null) {
       myComponentTree.updateInspections();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java b/plugins/ui-designer-core/src/com/intellij/designer/DesignerToolWindowContent.java
similarity index 68%
copy from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java
copy to plugins/ui-designer-core/src/com/intellij/designer/DesignerToolWindowContent.java
index bed999e..4ef588d 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyTypeHierarchyProvider.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/DesignerToolWindowContent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -13,12 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jetbrains.plugins.groovy.lang;
+package com.intellij.designer;
 
-import com.intellij.ide.hierarchy.type.JavaTypeHierarchyProvider;
+public interface DesignerToolWindowContent extends LightToolWindowContent {
+  void refresh(boolean updateProperties);
 
-/**
- * @author peter
- */
-public class GroovyTypeHierarchyProvider extends JavaTypeHierarchyProvider{
-}
+  void expandFromState();
+
+  void updateInspections();
+}
\ No newline at end of file
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/PaletteToolWindowContent.java b/plugins/ui-designer-core/src/com/intellij/designer/PaletteToolWindowContent.java
new file mode 100644
index 0000000..5e77e7c
--- /dev/null
+++ b/plugins/ui-designer-core/src/com/intellij/designer/PaletteToolWindowContent.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+package com.intellij.designer;
+
+import com.intellij.designer.designSurface.DesignerEditorPanel;
+import com.intellij.designer.palette.PaletteItem;
+import org.jetbrains.annotations.Nullable;
+
+public interface PaletteToolWindowContent extends LightToolWindowContent {
+  @Nullable
+  PaletteItem getActiveItem();
+
+  void clearActiveItem();
+
+  void refresh();
+
+  boolean isEmpty();
+
+  void loadPalette(@Nullable DesignerEditorPanel designer);
+}
\ No newline at end of file
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/DesignerEditorPanel.java b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/DesignerEditorPanel.java
index 9405e8b..dc12a18 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/DesignerEditorPanel.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/DesignerEditorPanel.java
@@ -164,8 +164,8 @@
       @Override
       public void run() {
         DesignerEditorPanel designer = DesignerEditorPanel.this;
-        DesignerToolWindowManager.getInstance(myProject).bind(designer);
-        PaletteToolWindowManager.getInstance(myProject).bind(designer);
+        getDesignerWindowManager().bind(designer);
+        getPaletteWindowManager().bind(designer);
       }
     });
   }
@@ -376,7 +376,7 @@
     myErrorPanel.revalidate();
     myLayout.show(myPanel, ERROR_CARD);
 
-    DesignerToolWindowManager.getInstance(this).refresh(true);
+    getDesignerToolWindow().refresh(true);
     repaint();
   }
 
@@ -603,7 +603,7 @@
   }
 
   protected void restoreState() {
-    DesignerToolWindow toolManager = DesignerToolWindowManager.getInstance(this);
+    DesignerToolWindowContent toolManager = getDesignerToolWindow();
 
     if (myExpandedState != null) {
       List<RadComponent> expanded = new ArrayList<RadComponent>();
@@ -733,11 +733,27 @@
 
   public void dispose() {
     Disposer.dispose(myProgressIcon);
-    DesignerToolWindowManager.getInstance(myProject).dispose(this);
-    PaletteToolWindowManager.getInstance(myProject).dispose(this);
+    getDesignerWindowManager().dispose(this);
+    getPaletteWindowManager().dispose(this);
     Disposer.dispose(myContentSplitter);
   }
 
+  protected AbstractToolWindowManager getDesignerWindowManager() {
+    return DesignerToolWindowManager.getInstance(myProject);
+  }
+
+  protected AbstractToolWindowManager getPaletteWindowManager() {
+    return PaletteToolWindowManager.getInstance(myProject);
+  }
+
+  public DesignerToolWindowContent getDesignerToolWindow() {
+    return DesignerToolWindowManager.getInstance(this);
+  }
+
+  protected PaletteToolWindowContent getPaletteToolWindow() {
+    return PaletteToolWindowManager.getInstance(this);
+  }
+
   @Nullable
   public WrapInProvider getWrapInProvider() {
     return null;
@@ -1012,7 +1028,7 @@
     @Override
     public void setActiveTool(InputTool tool) {
       if (getActiveTool() instanceof CreationTool && !(tool instanceof CreationTool)) {
-        PaletteToolWindowManager.getInstance(DesignerEditorPanel.this).clearActiveItem();
+        getPaletteToolWindow().clearActiveItem();
       }
       if (!(tool instanceof SelectionTool)) {
         hideInspections();
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/inspection/DesignerHighlightingPass.java b/plugins/ui-designer-core/src/com/intellij/designer/inspection/DesignerHighlightingPass.java
index fc3fe23..0fe7241 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/inspection/DesignerHighlightingPass.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/inspection/DesignerHighlightingPass.java
@@ -16,7 +16,6 @@
 package com.intellij.designer.inspection;
 
 import com.intellij.codeHighlighting.HighlightingPass;
-import com.intellij.designer.DesignerToolWindowManager;
 import com.intellij.designer.designSurface.DesignerEditorPanel;
 import com.intellij.openapi.progress.ProgressIndicator;
 import org.jetbrains.annotations.NotNull;
@@ -38,7 +37,7 @@
 
   @Override
   public void applyInformationToEditor() {
-    DesignerToolWindowManager.getInstance(myDesigner).updateInspections();
+    myDesigner.getDesignerToolWindow().updateInspections();
     myDesigner.updateInspections();
   }
 }
\ No newline at end of file
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/model/MetaManager.java b/plugins/ui-designer-core/src/com/intellij/designer/model/MetaManager.java
index 453751d..0727b48 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/model/MetaManager.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/model/MetaManager.java
@@ -22,6 +22,7 @@
 import com.intellij.openapi.util.text.StringUtil;
 import org.jdom.Attribute;
 import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
@@ -92,8 +93,9 @@
     }
   }
 
+  @NotNull
   @SuppressWarnings("unchecked")
-  private void loadModel(ClassLoader classLoader, Element element, Map<MetaModel, List<String>> modelToMorphing) throws Exception {
+  protected MetaModel loadModel(ClassLoader classLoader, Element element, Map<MetaModel, List<String>> modelToMorphing) throws Exception {
     String modelValue = element.getAttributeValue("model");
     Class<RadComponent> model = modelValue == null ? null : (Class<RadComponent>)classLoader.loadClass(modelValue);
     String target = element.getAttributeValue("class");
@@ -145,16 +147,30 @@
     if (target != null) {
       myTarget2Model.put(target, meta);
     }
+
+    return meta;
   }
 
+  @NotNull
   protected MetaModel createModel(Class<RadComponent> model, String target, String tag) throws Exception {
     return new MetaModel(model, target, tag);
   }
 
+  @NotNull
   protected DefaultPaletteItem createPaletteItem(Element palette) {
     return new DefaultPaletteItem(palette);
   }
 
+  @NotNull
+  protected VariationPaletteItem createVariationPaletteItem(PaletteItem paletteItem, MetaModel model, Element itemElement) {
+    return new VariationPaletteItem(paletteItem, model, itemElement);
+  }
+
+  @NotNull
+  protected PaletteGroup createPaletteGroup(String name) {
+    return new PaletteGroup(name);
+  }
+
   protected void loadProperties(MetaModel meta, Element properties) throws Exception {
     Attribute inplace = properties.getAttribute("inplace");
     if (inplace != null) {
@@ -190,8 +206,9 @@
   protected void loadOther(MetaModel meta, Element element) throws Exception {
   }
 
-  private void loadGroup(Element element) throws Exception {
-    PaletteGroup group = new PaletteGroup(element.getAttributeValue(NAME));
+  @NotNull
+  protected PaletteGroup loadGroup(Element element) throws Exception {
+    PaletteGroup group = createPaletteGroup(element.getAttributeValue(NAME));
 
     for (Object child : element.getChildren(ITEM)) {
       Element itemElement = (Element)child;
@@ -209,12 +226,12 @@
         // this such that the {@link MetaModel} can hold multiple {@link PaletteItem}
         // instances, and perform attribute matching.
         if (itemElement.getAttribute("title") != null) {
-          paletteItem = new VariationPaletteItem(paletteItem, model, itemElement);
+          paletteItem = createVariationPaletteItem(paletteItem, model, itemElement);
         }
         group.addItem(paletteItem);
 
         for (Object grandChild : itemElement.getChildren(ITEM)) {
-          group.addItem(new VariationPaletteItem(paletteItem, model, (Element)grandChild));
+          group.addItem(createVariationPaletteItem(paletteItem, model, (Element)grandChild));
         }
       }
       else {
@@ -223,6 +240,8 @@
     }
 
     myPaletteGroups.add(group);
+
+    return group;
   }
 
   @SuppressWarnings("unchecked")
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/model/MetaModel.java b/plugins/ui-designer-core/src/com/intellij/designer/model/MetaModel.java
index 8f4bbb9..442adf2 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/model/MetaModel.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/model/MetaModel.java
@@ -16,6 +16,7 @@
 package com.intellij.designer.model;
 
 import com.intellij.designer.palette.DefaultPaletteItem;
+import com.intellij.designer.palette.PaletteItem;
 import com.intellij.designer.propertyTable.IPropertyDecorator;
 import com.intellij.openapi.util.IconLoader;
 import com.intellij.util.ArrayUtil;
@@ -33,7 +34,7 @@
   private Class<RadLayout> myLayout;
   private final String myTarget;
   private final String myTag;
-  private DefaultPaletteItem myPaletteItem;
+  private PaletteItem myPaletteItem;
   private String myTitle;
   private String myIconPath;
   private Icon myIcon;
@@ -117,7 +118,7 @@
     myIcon = null;
   }
 
-  public DefaultPaletteItem getPaletteItem() {
+  public PaletteItem getPaletteItem() {
     return myPaletteItem;
   }
 
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/model/VariationPaletteItem.java b/plugins/ui-designer-core/src/com/intellij/designer/model/VariationPaletteItem.java
index 81c761f..782fd85 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/model/VariationPaletteItem.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/model/VariationPaletteItem.java
@@ -12,16 +12,16 @@
  * Implementation of a {@link PaletteItem} which delegates to another {@linkplain PaletteItem}
  * but which possibly overrides the title, icon and or creation properties.
  */
-final class VariationPaletteItem implements PaletteItem {
+public class VariationPaletteItem implements PaletteItem {
   private final PaletteItem myDefaultItem;
-  private final MetaModel myModel;
   private final String myTitle;
   private final String myIconPath;
   private final String myTooltip;
   private final String myCreation;
   private Icon myIcon;
+  private MetaModel myModel;
 
-  VariationPaletteItem(PaletteItem defaultItem, MetaModel model, Element element) {
+  protected VariationPaletteItem(PaletteItem defaultItem, MetaModel model, Element element) {
     myDefaultItem = defaultItem;
     myModel = model;
 
@@ -91,6 +91,11 @@
     return myModel;
   }
 
+  @Override
+  public void setMetaModel(MetaModel metaModel) {
+    myModel = metaModel;
+  }
+
   @Nullable
   @Override
   public String getDeprecatedIn() {
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/palette/DefaultPaletteItem.java b/plugins/ui-designer-core/src/com/intellij/designer/palette/DefaultPaletteItem.java
index 4ae4ae9..0824f5a 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/palette/DefaultPaletteItem.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/palette/DefaultPaletteItem.java
@@ -114,6 +114,7 @@
     return myMetaModel;
   }
 
+  @Override
   public void setMetaModel(MetaModel metaModel) {
     myMetaModel = metaModel;
   }
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/palette/PaletteItem.java b/plugins/ui-designer-core/src/com/intellij/designer/palette/PaletteItem.java
index 8cf9578..54347f5 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/palette/PaletteItem.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/palette/PaletteItem.java
@@ -60,4 +60,9 @@
    * Returns the associated {@link com.intellij.designer.model.MetaModel}, if known
    */
   MetaModel getMetaModel();
+
+  /**
+   * Sets the associated {@link com.intellij.designer.model.MetaModel}, if known
+   */
+  void setMetaModel(MetaModel metaModel);
 }
\ No newline at end of file
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/palette/PalettePanel.java b/plugins/ui-designer-core/src/com/intellij/designer/palette/PalettePanel.java
index 67bfd77..a7dfef3 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/palette/PalettePanel.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/palette/PalettePanel.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.designer.palette;
 
-import com.intellij.designer.LightToolWindowContent;
+import com.intellij.designer.PaletteToolWindowContent;
 import com.intellij.designer.designSurface.DesignerEditorPanel;
 import com.intellij.openapi.actionSystem.*;
 import com.intellij.openapi.application.ApplicationManager;
@@ -42,7 +42,7 @@
 /**
  * @author Alexander Lobas
  */
-public class PalettePanel extends JPanel implements DataProvider, LightToolWindowContent {
+public class PalettePanel extends JPanel implements DataProvider, PaletteToolWindowContent {
   private final JPanel myPaletteContainer = new PaletteContainer();
   private List<PaletteGroupComponent> myGroupComponents = Collections.emptyList();
   private List<PaletteItemsComponent> myItemsComponents = Collections.emptyList();
@@ -116,6 +116,7 @@
     return null;
   }
 
+  @Override
   public void clearActiveItem() {
     if (getActiveItem() != null) {
       for (PaletteItemsComponent itemsComponent : myItemsComponents) {
@@ -125,14 +126,17 @@
     }
   }
 
+  @Override
   public void refresh() {
     repaint();
   }
 
+  @Override
   public boolean isEmpty() {
     return myGroups.isEmpty();
   }
 
+  @Override
   public void loadPalette(@Nullable DesignerEditorPanel designer) {
     if (myDesigner == null && designer == null) {
       return;