Snapshot cd724ea5e27634f1c84f893f10b646937a677d56 from idea/132.425 of git://git.jetbrains.org/idea/community.git

cd724ea: Code cleanup - Idea's warnings fixed - message moved to .properties file
c84855b: for performance use processNames api for java symbol contributor
334c509: IDEA-114064 Create "From Maven" library dialog doesn't handle full coords correctly (as advertised)
4e10a17: IDEA-109943 Download Library from Maven Repository: artifacts from repository with provider != maven2 are suggested, but repository is filtered off
d4bc48d: IDEA-114037 Code completion should prefer variable names to unimported class names
b7e5e6c: refix RUBY-11716: do not play with fire, always save and load in UTF-8 !
bb7ed8a: cleanup
15bd24e: cleanup
e56b270: ProjectId, don't add project level provider if project is not mapped
a0fb6a5: let IsNullCheck mean null->true, the former !null->false meaning was useless
26402542: test data fixed
f800733: new inference: input/output inference variables
56d872d: NPE: find usage for db element
3ffd6a0: IDEA-114003 XDebuger breakpoint properties: strage selection jumps in breakpoint tree
bbdef54: IDEA-114001 XDebuger Breakpoint Properties: enable in tree is not saved IDEA-114002 XDebuger breakpoint properties: don't close the dialog by double click IDEA-114004 XDebugger breakpoint properties: checkboxes synchronization is broken
f6ff871: IDEA-114001 XDebuger Breakpoint Properties: enable in tree is not saved IDEA-114002 XDebuger breakpoint properties: don't close the dialog by double click IDEA-114004 XDebugger breakpoint properties: checkboxes synchronization is broken
8f3d962: IDEABKL-6897 Enter inserts closing brace in wrong place
6a78643: IDEABKL-6897 Enter inserts closing brace in wrong place
06b899c: IDEA-114001 XDebuger Breakpoint Properties: enable in tree is not saved IDEA-114002 XDebuger breakpoint properties: don't close the dialog by double click IDEA-114004 XDebugger breakpoint properties: checkboxes synchronization is broken
aeda985: don't give focus to ant messages view
f525708: new inference: overload resolution for SAM return type for implicit lambda should be ignored
6692602: cleanup current file from highlighting markup
27c6645: compilation fix
1936bb2: IDEA-107453 Compilation error if overriding methods have different access modifiers
0ddcc36: api
a7f05e1: card layout fixed
b007608: IDEA-110203 IDEA ignores space after comma setting for methods declaration/call [CR-IC-2022]
ae02c17: hiding artifacts
90e6ed2: back to AddModuleWizard
4a029e9: Groovy: Pull-up members
6f9e810: NPE
fc48bab: pull-up
cbf7531: prepare pull-up refactoring for Groovy
6762d5f: cleanup
b26ffb2: spaces around inner classes
41e8e70: IDEA-113333 Java formatter breaks source code: Merges statements into line comments [CR-IC-2245]
ea91b55: IDEA-113815 keep "simple methods in one line" does not keep long methods [CR-IC-2486]
ecd65ad: Import Eclipse code style settings from XML profile (a part of IDEA-104068) [CR-IC-2219]
aacf1e4: IDEA-113844 (handling of core component initialization failures when spoiled by plugins)
8dc3ede: IDEA-112387 Reformat code with rearrange entires on = fail on enum [CR-IC-2205]
72ddb9e: Merge remote-tracking branch 'origin/master'
209340b: Add the description for MavenDuplicatePluginInspection.
de367e1: Merge branch 'svn1_8_new'
1a70497: IdeaTestAssistant: fix test data
d6a2510: svn: Fixed "Import" when path/url contains '@' symbol
94c4223: svn: Implemented "Export" action for command line
8913712: parameter popup: escape for annotation methods (IDEA-113971)
fdf7312: svn: Made event handler for checkout/export utilize passed progress indicator (instead of just current thread progress indicator)
f653713: IDEA-105758: Contradiction between error and fix actions (Java EE artifact)
eac456f: Platform: ability to provide native icons for PsiElements (PsiFile/Directory) AppCode: blue icons for folders
4d5c47a: IDEA-77519: Project fails to open when workspace.xml is empty
c40e732: two classes temporary restored to fix backward compatibility
b6b3bc6: added optional dependencies for framework support providers
a9dae78: IDEA-90661: recognize IBM JDK jars
6b44958: cleanup & javadoc
0c0a6a6: IDEA-108785 Allow applying the same context to many selected live templates
247661b: don't search for unknown path macros in the middle of xml unless asked so by PathMacroFilter (IDEA-102674)
90222d5: hopefully fix control flow building stack inconsistency assertions in case when a PCE is thrown
241e44b: EA-50288 - CCE: RefJavaUtilImpl.getTopLevelClass
22d5c2f: ensure to filter already inserted annotations (IDEA-113785)
27b76b4: inplace introducer: another case to restore expression (IDEA-113352)
603e138: add mnemonics (IDEA-113889)
a8c374c: XSuspendPolicyPanel "Make default" (requires for new JavaBreakpointType) remove unused methods
4f19472: CR-IC-2485 (deprecation policy specified; deprecated API usage upgraded)
7231807: JavaBreakpointType isSuspendThreadSupported true
8637e89: register JavaBreakpointType, but hide under system property java.debugger.xBreakpoint
0b2d5f0: cleanup
5cc1f5e: EA-50289 (CCE: TooBroadScopeInspection$TooBroadScopeInspectionFix.getCommentText)
505b86e: new inference: pertinent to applicability
8ac21fd: cleanup
2c5f39e: cleanup
f6efaa9: simplify DebuggerInvocationUtil
bf8865f: overrides
0d49e5b: JavaBreakpointType canPutAt
33ebea3: extract XLineBreakpointTypeBase
de7d963: extract XDebuggerEditorsProviderBase, init JavaBreakpointType (is not registered, so, not in action now)
ed777e6: remove deprecated canPutAt
9163435: overrides
44af67f8: extract XDebuggerUtil.getInstance().getGroupingByFileRuleAsList()
b93b27c: add missing Overrides
0857036: cleanup
ae791a7: new inference: test preparations
48120ab: IdeaTestAssistant: add resolving and completion inside TestDataPath annotation
971544b: remove empty unused class
c5642d9: hippie completion: split complex tokens by spaces
e1383b1: refix and add test for IDEA-90294 Don't use substring match in word completion
fbae94c: EA-49809 Made client factories final in SvnVcs
2b4b70f: Fix OC-8127: Appcode hangs on reformatting (endless right shift) +review CR-OC @Anton.Makeev, @Rustam.Vishnyakov
b7314cf: fix pycharm detection
5f0bb3c: revert error checking
5f99590: svn: Implemented "Import" action for command line
ad04905: svn: Changed import logic to use common commit event handler (instead of checkout event handler)
1a45be0: custom options
8d278a3: MavenArchetypesPanel extracted
32eeb4c: aggregation panel invisible
9388cc4: new project wizard: project type sorting
2c02a07: svn: Add "Skipped" event processing in commit/import output for command line
d365580: svn: Refactored commit output parsing for command line
b1cc312: immutable dfa offset stack
5c494fb: toolbarIcon is nullable
4304880: dfa: traverse only flushable variables, not all
ed08eab: immutable EqClass
03de519: overrides
f8661d9: return empty collection if list of storage files is empty
81a998c: IDEA-111030: Add Framework Support: Ok is disabled for the only selected Web Application
4ce1cc8: unused class removed
84f7401: svn: Added final status bar message for Import ("Committed revision xxx")
aa1d479: library editor: 'attach javadoc' extracted to separate button so the main '+' button won't show popup
1612198: cleanup
e180456: cleanup
546fffe: Merge remote-tracking branch 'origin/master'
c3caf6c: Merge remote-tracking branch 'origin/master'
5cd2b37: assertion for EA-45385 - NPE: XmlTagImpl.getDescriptor
99563ea: EA-49418 - NPE: InjectLanguageAction.invokeImpl
dc82859: cleanup
f70ef96: EA-50139 - assert: TextRange.<init>
990e410: svn: Removed unused code (from "Ignore" functionality)
6604613: svn: Implemented "Ignore" functionality on subversion level
d544d03: cleanup after notnullification
5330d9e: plugin suggester: suggest plugins from repository by unknown facet
1ccf92a: error which should never happen replaced by assertion
889d3ce: improved dialog for choosing root types of added roots
0eb34fa: hide "use out of process build" option from UI
d79e13e: plugin suggester: suggest plugins from repository by unknown facet
00a127b: Use shell options only if applicable.
b4f21b9: Don't fail to create SSH terminal session if we failed to create local terminal session.
8e5cb57: test for "Unnecessary unicode escape sequence" inspection
dc8acce: temp revert
c7c4431: fix SliceBackwardTest
3e16a04: svn: Implemented "Edit Revision Comment" action for command line
c54948a: 'async' added
e4f7950: svn: Correctly create externals that have '@' in url - add '@' at url end
9b66e1c: svn: Fix line separators duplication for "Create External" action for SVNKit
a98dc14: svn: Implemented "Create External" action for command line
32e30d1: EA-50206 - assert: FileManagerImpl.findFile
4a4c0cc: svn: Unify line separator for multiline properties
4b9422b: Reverted: Semantic highlighting level to avoid conflicts with "unused symbol" annotations [CR-IC-2435]
ad970ef: lambda: propagate wildcards elimination
e78ab51: lambda: check formal params for equality, eliminate wildcards during inference according to 15.27.3
fc9a196: new inference: ignore proper types in mutual eq constraints generation
7bc0048: new inference: void compatible according to return values
939fc45: prepare for test new inference
eef6eb2: new inference: exact method reference
172daec: new inference: eliminate delayed constrains according to 0.6.3
ec93384: postpone type evaluation
e689d68: new inference: make use of ex constraint
7838f8e: Merge branch 'safe-sudo-escaping'
1c22df9: Add grails-app/resources as resources folder, not a source folder.
a7f094d: fix NPE
e1fe819: Added ExecUtil.sudoAndGetOutput() with safe escaping and quoting for Mac and Linux
6bf3a02: fixed EA-48905 - SIOOBE: ParameterInfoComponent$OneLineComponent.buildLabelText
c853c69: system dependent paths in groovy shell
db7d97f: Merge remote-tracking branch 'origin/master'
65426f9: mark as DumbAware
0d1a074: Support active links in GotIt panel
c7297a0: debugging blinking test
755c6b2: IDEA-113938 "Submit feedback" should pre-fill project and affected version
ff45141: dfa: don't go into the same instruction twice with the same state
3361944: a bit more parsimonous DfaMemoryStateImpl.createCopy
028d28b: dfa states should not change while in queue => no need to copy them
1709382: dfa: use UnorderedPair instead of two-element set
e8dbc21: immutable DfaVariableState, for faster copying and less memory usage
666ed52: IDEA-70241 (Replace with '{@code}' inspection doesn't replace all occurrences in file.)
71bd9cf: Merge remote-tracking branch 'origin/master'
c923098: EA-47881 - IOE: GroovyPsiElementFactoryImpl.createGroovyFileChecked
8b97940: cleanup logging
6e4b81e: EA-50137 - assert: TestObject.addClassesListToJavaParameters
5381d51: cleanup
dc2d1b2: notnull
f419fab: "todo" moved out of lang-impl
97cd633: attributes cleanup
75b3eaa: notnull
c7fa9af: cleanup
f5b5bf4: cleanup
776b16b: cleanup
bf3cea4: made fields final
87913f7: cleanup
798e94e: cleanup, get rid of buggy duplicate node renderer
50f13e4: removed deprecated methods from ExternalAnnotator
6d9c887: avoid deprecated methods
4852116: minor
9cd549c: now Searchable. fixes test.
302302a: typo
26d8885: - handle strings with more than one quote used for start / end delimiters - proper retrieving syntax highlighter in case of non languge based syntaxhighlighter (quite often it is bound to file type) - Find: String literals only: Throwable at StringSearcher.scan() on XML with a string (IDEA-113885) - fix for backward search not ending when whole word option used
4dfd0c7: Encapsulate field dialog: explicit value for "Use accessors when field is accessible" when "as is" visibility is selected
e1aff45: typo :(((
6237b9b: test fixed
6c0d31b: test fixed
493cfae: update test data
711bca1: update test data
f1bc615: update test data
8dd18de: update test data
e61a901: update test data
0be96e9: update test data
aac178b: dfa: remove queued state duplication
6a25f5d: dfa: don't reschedule already processed states, cleanup
7559dfc: Semantic highlighting level to avoid conflicts with "unused symbol" annotations [CR-IC-2435], for WI-19396, WI-20126 (cherry picked from commit 56d66dc)
7c27aef: extract collectUsedJars() function
12f59ff: update test data
03df890: update test data
1efd604: update test data
2c1726e: update test data
24bf1d1: Merge remote-tracking branch 'origin/master'
8f26a8b: improved duplicates search in python extract method
9bfcbbe: setup resource roots when project is imported from Maven (IDEA-57398)
64594cd: diagnostics for EA-49831
0d76c32: add support for frameworks step: sorting restored
b510334: IDEA-113294 indentation of brace in a lambda expression corrected [CR-IC-2426]
9651be4: IDEA-113910 Gradle: code insight; dependencies DSL resolving
25595c8: new inference: checked exceptions compatibility constraint
6b8f295: dump highlighting test data without markup
636719b: now that we have dfa state hashing, use it instead of linear lookup
3813120: dfa: don't merge states when there's only one
3fd9ba8: IDEA-113910 Gradle: code insight; dependencies DSL resolving
57a6aeb: IDEA-113910 Gradle: code insight; dependencies resolving
da23b6c: Merge remote-tracking branch 'origin/master'
7ca6ea3: Merge remote branch 'origin/master'
cdc6d6a: show deprecated make implementation warning once on first compilation after project opening
090c4e3: dfa state merging: cache copies
e6ee024: Allows getting Gradle home without having a Project.
0391639: Gradle VM Options are now saved in between sessions.
f5412f0: resource root: show 'New Directory' action instead of 'New Package' under resource roots
1637f6b: notnullification
87f394f: IDEA-113904 (Add New Module from Project Structure dialog wants to create new project)
a7c75f6: IDEA-113865 ('Equals should check class of parameter' shouldn't warn on identity equals)
2486e9e: dfa: merge several states to account for variables with several possible values
4d4f4b0: dfa: some minor things and caching
c14961f: UnorderedPair in platform
5ad442d: Merge remote-tracking branch 'origin/master'
946a281: Scroll to bottom on typing in terminal (PY-10344).
e5a0548: Close all connections on dispose.
f61f6a2: changes from tech-writers
b82b0bb: dfa: state merging interruptibility
3893373: VcsDirtyScopeManagerImpl: log who marks everything dirty
41e5381: Merge remote-tracking branch 'origin/master'
da21efb: JediTerm updated.
beb1d1a: Merge remote-tracking branch 'origin/master'
ed3a2b5: skip the whole document if some component has disabled roaming type (details CR-IU-308)
d66309b: Fix antialiasing.
e55fae1: dfa: abstract out eq class into EqClass class
370d44d: dfa: remove trivial state facts that constant != another constant
4ccfcf7: UsagesStatistic must specify roaming disabled
75894ae: cleanup
784b4e3: DimensionService: cleanup, order of stored data should be stable
36443b6: overrides
b70b1dc: overrides
dfe38fb: simplify some constant conditions and greenify
9a08478: IDEA-85961 (Pattern BACKSLASH_PATTERN = Pattern.compile("\\", Pattern.LITERAL) is always marked red.)
d0bdc3b: simplify load from providers – we don't need to filter again (our save do it, in any case it is absurd to store component with global roaming in the project level file, — should be refine later)
bf85e1b: cleanup
9c30823: remove unused methods
f671c09: overrides
3bd62bc: ComponentRoamingManager should not keep defaults (we use RoamingType.PER_USER by default)
a8f1063: CR-IU-300 remove outdated EP ComponentRoamingType
b182751: CR-IU-300 remove outdated RoamingTypePerPlatform
994389c: another java.util.regex.Pattern.compile() parameter annotation
301710d: IDEA-113866 (this. not suggested for fields of anonymous inner classes)
f5d03c4: dfa: don't consider final getters same as immutable fields
272a6d0: Corresponding parents for console colors.
71298ce: Bright console colors for Monokai.
f39c34b: Console colors for WarmNeon scheme.
7548e47: Black is invisible on dark background (in RegExps for example).
ca6b784: Change bloody red to light pink for numbers (pink is specific to Neon color schemes while red is not, also eyes say thanks).
7f627d9: Console colors for Twilight scheme fixed.
a5eb2fc: Console colors for Monokai scheme fixed.
f7da145: DfaPsiType: add @NotNull
b216102: rebomb test
b349547: diagnostics for inconsistencies during control flow building
6823425: dfa: only perform costly state merging when it has chances - after jumps
fea8871: dfa: fighting too complex methods; join complementary memory states after fork to avoid having too many states
0ac2084: DfaMemoryStateImpl: introduce unwrap; compare variable values with their non-initialized counterparts
e919b8b: dfa: only goto catch on non-trivial method calls and throws
e2ea04f: new inference: initial method reference constraint
a9dde36: new inference: check substituted descriptor return type
3e5b164: new inference: expression inside condition should be poly, target type for conditional expression
ff9f2e9: new inference: emulate fresh variable - do not override vars with captured ones
f415702: new inference: default constructor as poly expression argument
ee56497: new inference: symmetric variable bounds
4a46b24: new inference: init inter call inference
06829c5: Merge remote-tracking branch 'origin/master'
e3f213f: Console colors for Darcula.
f748505: IDEA-57940 Cyclic expand word should take into account all open files
460ef47: StreamProvider.isVersioningRequired
8029f47: Bright yellow made more visible on white background.
96006be: Default console colors as in xterm palette,  gray and dark gray from standard vga palette for better readability.
a378414: Bight console colors added to settings.
54e6582: builder-based project types
b0b2cf8: template-based project types?
e741484: CPU hogging fix again
eb22a99: fix todo duplication when several pattern match -> prefer finding match with last pattern (in settings list), thus default TODO pattern is matched last
a4d4371: fix compilation
2f823ba: Difference Groovy Shell & Groovy Console actions
3e876f4: IDEA-113590 annotations as annotation values
732cafd: dead code
a712f87: pull up 'isQualified()' method
4edd102: extract base class from PullUpDialog
10d89d6: remove obsolete test
a0750e4: delete envFile manually
114cbb2: IDEA-113861 Gradle: it could be possible to hide 'Gradle: download' progress to the background
ca416b8: 'More' element for classes, files, action, and settings. Better renderer.
b2a550c: test framework: drop temp directory on light project close
8aaf53b: greenify ActionsTreeUtil a bit
922d41a: layout
2cd7326: adding frameworks support
2bd8fb0: cleanup
4ea6442: ProjectSummaryStep
9fdcdcd: commit project name
bd39918: new project wizard: first test
630fc14: External system: use URLs in compile output paths
85dbe5f: IDEA-65114 "Add Maven projects" cannot be undone
5041ae5: test framework: returning of the data provider
16e2072: @Nullable XBreakpoint.getProperties reverted +review CR-IC-2418
df4da38: dump shell environment to a temporary file to reduce probability of malformed lines occurrence
280d52a: let event log warning color be orange (IDEA-113802)
a30b2ae: IDEA-113836 Console folding: add TestNG related patterns
cbeb0f1: don't change mouse cursor during goto name population (IDEA-113800)
fb5ad5b: IDEA-113638 ChooseByName restart on write action spawns a new thread
89b3767: disable autopopup in groovy shell if selection by chars is enabled (IDEA-112820)
9fa36be: CompletionConfidence: don't force API users to implement unused method
34cf7eb: Console Folding: proper capitalization
5e8aa44: IDEA-113855 Search Everywhere looks scrambled at first start
71723cb: svn: Refactored executable validation - use separate version client
1114cfe: javadoc
0738800: jps model: simplification, source roots always have default properties
b1d5062: jps model: JpsElementType converted to interface to allow reusing common base class
229deb0: test framework: ok, put light project file into ephemeral directory, but keep it for a project's life
6e8b950: ensure  "thread" suspend policy for logging breakpoints
d67c04e: EA-49809 Move client factories creation to SvnVcs constructor (instead of active() method)
935cdba: new inference: initial tests
970a180: encapsulate read access to USE_COMPILE_SERVER option
b9b3fc8: remote agents - extract to remote servers
cfe8e2b: WEB-9335 Bad insert pair brace in CSS
2815c22: WEB-9334 Incremental selection works bad with negative CSS values
d023471: new "Unnecessary unicode escape sequence" inspection
945b069: unicode escape needs at least one 'u'
8e7797b: chrome still crashed, revert to old, not-recursive speed search
1917d86: Merge remote-tracking branch 'origin/master'
c18e6bd: Lense mode "internal" preview
db88427: Merge branch 'svn1_8_new'
7c64e8b: test framework: do not put light project file into ephemeral directory
af09e11: remove @Nullable from key.get as it's too generic
d49df32: svn: Refactored prompting for working copy format - make return not null format
d6086ae: dfa: types with wildcard parameters are not equal
3d28aa5: Optimization: check exiting of griffon-app first
b016c04: correct ephemeral state copy (IDEA-113143 Calling method with contract shouldn't result in nullability suspicion)
189573f: svn: Refactored upgrade working copy format dialog - use list of available formats (instead of separate fields for each format)
60c471b: Rename test
1a42f59: Remove using of unnecessary StringBuilder
a56db90: Use MultiMap
340cf22: Calling method with contract shouldn't result in nullability suspicion (IDEA-113763, IDEA-113699, almost IDEA-113143)
f2a563b: dfa: unify nullability violation processing
709af86: dfa: expand contract test
1cddfb4: dfa cleanup: skipping reports on method calls is now done via unknown variable mechanism
2765dab: dfa: spare some minor cpu cycles
8bc7465: svn: Added "1.8" option to upgrade/checkout dialogs
c266bd2: IDEA-66603 Maven3: provide inspection that checks duplicate declarations of plugins
af32923: SpellChecker: "cyclomatic"
5f4f98f: svn: Refactored working copy format selection dialog to use WorkingCopyFormat instances instead of just strings
e33b58b: MismatchedCollectionQueryUpdateInspection -- added "compute" prefix (from j.u.Map in JDK8)
7d54b2e: new inference: accept nonProper eq bounds
457d95b: new inference: distinguish different captures
5b5f52e: new inference: assertions caused by raw types
3848de4: new inference: open top level captured wildcards
35d59c0: new inference: extend usage of already inferred variables
4f7b572: new inference: inference of calls in arguments during outer call inference
bfa7879: new inference: captured variables from outer calls to be included
ed95269: new inference: eq bound for S<=T constraint reduction
12a0faf: better positioning
13029b7: different position layout algorithms
39e6e21: EA-49923 - Fixed working copy format detection for default project
d521e9d: JDK combobox should show JDK home
17fe05e: Fix typo
7ab769b: IDEA-16077 Maven embedder runs in the 'wrong' JDK add "embedder JDK" option
418ddc0: Inline string constant
6a8f1e2: IDEA-16077 Maven embedder runs in the 'wrong' JDK extract MavenJdkCombobox
46078c4: svn: Refactored detection if command line implementation should be used (use utility method)
24106fc: XDebugger: @Nullable XBreakpoint.getProperties()
3dc6f07: extract util method
476dac4: Reinit checkbox state on create
39cf1fd: Structure viewer for simple editors support fixed
a38a251: Show filters only for table editor + a few model and UI fixes
cbd5630: Initial dynamic filters model + columns header improved
281c008: svn: Support nullable SVNStatusClient in status implementation for SVNKit
1840d42: simplification
fbcba0f: svn: Make command line clients (info, status) use vcs instead of project instances
ae8b41b: Merge remote-tracking branch 'origin/master'
a97397c: Extract method.
3b9eca4: new project wizard: preparing test infrastructure
327ddb0: Lense mode "internal" preview
0ede5e1: new project wizard: AbstractProjectWizard extracted
a94b556: IDEA-111335 Gradle: task tree is incorrectly displayed if tasks are added to sub-projects via 'subprojects' method
bfd366f: Merge remote-tracking branch 'origin/master'
0ef2a82: calls to obsolete method removed from build scripts
2df016f: AntLoggerFactory inner class made static to fix NoSuchMethodException in Logger.setFactory
fe876e2: svn: Clients for update command renamed and moved to corresponding package
a38d90e: Terminal color settings.
bd285b8: svn: Refactored update logic to common ClientFactory model
9cc13da: platform: ignore hidden Windows files
d87664c: test framework: relic property dropped
5f6ef06: svn: Removed unused "common ancestor" behavior from command line update client
3667fe1:  Find in strings with reg exp with start / end match markers doesn't work without string delimiters (IDEA-113788)
94a079f: svn: Refactored "update" command - explicitly create new SVNKit update client for each update/switch operation
0344e91: new project wizard: added option to use framework libraries from an app server
2882ac0: svn: Removed unused methods from "update" client
17ea275: svn: Removed unused SvnProxies class
c926181: WEB-9342 External Tool fails on OSX if an executable file basename specified
a3433f9: svn: Removed unused methods from "info" client
ec3112d: Optimize SassExtensionFunctionsIndex
9f1abf7: nosplash shouldn't prevent from plugin update
4c7154d: dfa: use cached nullability
b81e9c3: dfa: less frequent "too long" check
0b0eba9: DfaValueFactory: use List instead of TIntObjectHashMap for sequential keys
95d5433: introduce DfaPsiType without nullability, to quickly check assignability/convertibility in DfaVariableState
b901d90: IDEA-96713 Incorrect options shown for 'implements'
e02e2c4: IDEA-113780 "Annotate" from history fixed for renamed/moved files
fe00f73: test framework: stability improvements
76d664d: platform: suspicious event logging
b204bdf: Cleanup (de-duplication)
7ba9ff0: spelling
ece939c: make public for Upsource
496db4d: xdebugger: rebuild standalone variables view on EDT
eae27cb: xdebugger: supported rebuilding of standalone variables view
8bf5204: xdebugger api: added convenient method
43dbb6f: Terminal options.
3db1f5c: Blink period and antialiasing settings.
88264bd: IDEA-108147 Use "merge sources" wrapper object instead of just string representation as data model for "Merge Sources" column (to correctly get file revision object and show details panel)
111e6ba: IDEA-108147 While building history for element make check "if element parent or child was changed in given revision" only be performed for non-"merge source" revisions
e07828d: svn: Implemented support for "merged revisions" parsing in history logic for command line
1586c4a: svn: history logic refactored for command line - get and parse history data in xml format
0ac1dd2: IDEA-94942 Refactored "Annotate" implementation for command line - use utility method for parsing
ba1e5e0: IDEA-94942 Implemented merge history support for "Annotate" action
4c3b0a8: IDEA-94942 Implemented "Switch" logic (during update)

Change-Id: I7092ae66ff47d353a5b9770d1d91f77369bb7734
diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLexer.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLexer.java
index c37f576..09ee6a5 100644
--- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLexer.java
+++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLexer.java
@@ -16,6 +16,7 @@
 package org.intellij.lang.regexp;
 
 import com.intellij.lexer.FlexAdapter;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.EnumSet;
 
@@ -29,7 +30,7 @@
         myCapabilities = capabilities;
   }
 
-    public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+    public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
         getFlex().commentMode = (initialState & COMMENT_MODE) != 0 || myCapabilities.contains(RegExpCapability.COMMENT_MODE);
         super.start(buffer, startOffset, endOffset, initialState & ~COMMENT_MODE);
     }
diff --git a/build/scripts/common_tests.gant b/build/scripts/common_tests.gant
index b067618..1af3d7a 100644
--- a/build/scripts/common_tests.gant
+++ b/build/scripts/common_tests.gant
@@ -27,7 +27,6 @@
   }
 
   loadProject()
-  projectBuilder.useInProcessJavac = false
   projectBuilder.targetFolder = out
   projectBuilder.cleanOutput()
   projectBuilder.buildAll()
diff --git a/build/scripts/dist.gant b/build/scripts/dist.gant
index a03f512..58ece9a 100644
--- a/build/scripts/dist.gant
+++ b/build/scripts/dist.gant
@@ -47,7 +47,6 @@
 
 target(compile: "Compile project") {
   loadProject()
-  projectBuilder.arrangeModuleCyclesOutputs = true
 
   projectBuilder.stage("Cleaning up sandbox folder")
   forceDelete(paths.sandbox)
diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant
index 8f0e940..d1e90c1 100644
--- a/build/scripts/utils.gant
+++ b/build/scripts/utils.gant
@@ -775,11 +775,9 @@
   }
 })
 
-binding.setVariable("buildModulesAndCollectUsedJars", { List modules, List approvedJars, List forbiddenJars ->
+binding.setVariable("collectUsedJars", { List modules, List approvedJars, List forbiddenJars, List modulesToBuild ->
   def usedJars = new HashSet();
 
-  projectBuilder.cleanOutput()
-  def modulesToBuild = []
   modules.each {
     def module = findModule(it)
     if (module != null) {
@@ -794,12 +792,22 @@
           }
         }
       }
-      modulesToBuild << module
+      if (modulesToBuild != null) {
+        modulesToBuild << module
+      }
     }
     else {
       projectBuilder.warning("$it is not a module")
     }
   }
+
+  return usedJars
+})
+
+binding.setVariable("buildModulesAndCollectUsedJars", { List modules, List approvedJars, List forbiddenJars ->
+  def modulesToBuild = []
+  def usedJars = collectUsedJars(modules, approvedJars, forbiddenJars, modulesToBuild)
+  projectBuilder.cleanOutput()
   projectBuilder.buildModules(modulesToBuild)
 
   return usedJars
diff --git a/colorSchemes/src/colorSchemes/Darcula.xml b/colorSchemes/src/colorSchemes/Darcula.xml
index f0ad4be..b405024 100644
--- a/colorSchemes/src/colorSchemes/Darcula.xml
+++ b/colorSchemes/src/colorSchemes/Darcula.xml
@@ -157,14 +157,34 @@
         <option name="EFFECT_TYPE" value="-1" />
       </value>
     </option>
+    <option name="CONSOLE_BLACK_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="000000" />
+      </value>
+    </option>
     <option name="CONSOLE_BLUE_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="5394ec" />
+        <option name="FOREGROUND" value="5394EC" />
+      </value>
+    </option>
+    <option name="CONSOLE_BLUE_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="7EAEF1" />
       </value>
     </option>
     <option name="CONSOLE_CYAN_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="6969" />
+        <option name="FOREGROUND" value="33CCCC" />
+      </value>
+    </option>
+    <option name="CONSOLE_CYAN_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="6CDADA" />
+      </value>
+    </option>
+    <option name="CONSOLE_DARKGRAY_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="555555" />
       </value>
     </option>
     <option name="CONSOLE_ERROR_OUTPUT">
@@ -172,9 +192,29 @@
         <option name="FOREGROUND" value="ff6b68" />
       </value>
     </option>
+    <option name="CONSOLE_GRAY_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="999999" />
+      </value>
+    </option>
+    <option name="CONSOLE_GREEN_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="007F00" />
+      </value>
+    </option>
+    <option name="CONSOLE_GREEN_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="70FF70" />
+      </value>
+    </option>
     <option name="CONSOLE_MAGENTA_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="983498" />
+        <option name="FOREGROUND" value="FF70FF"/>
+      </value>
+    </option>
+    <option name="CONSOLE_MAGENTA_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="FF99FF" />
       </value>
     </option>
     <option name="CONSOLE_NORMAL_OUTPUT">
@@ -189,12 +229,32 @@
     </option>
     <option name="CONSOLE_RED_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="ff6b68" />
+        <option name="FOREGROUND" value="FF6B68" />
+      </value>
+    </option>
+    <option name="CONSOLE_RED_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="FF8785" />
       </value>
     </option>
     <option name="CONSOLE_SYSTEM_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="bbbbbb" />
+        <option name="FOREGROUND" value="BBBBBB" />
+      </value>
+    </option>
+    <option name="CONSOLE_WHITE_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="BBBBBB" />
+      </value>
+    </option>
+    <option name="CONSOLE_YELLOW_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="CDCD00" />
+      </value>
+    </option>
+    <option name="CONSOLE_YELLOW_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="FFFF00" />
       </value>
     </option>
     <option name="CSS.COLOR">
diff --git a/colorSchemes/src/colorSchemes/WarmNeon.xml b/colorSchemes/src/colorSchemes/WarmNeon.xml
index 37bb172..25cd484 100644
--- a/colorSchemes/src/colorSchemes/WarmNeon.xml
+++ b/colorSchemes/src/colorSchemes/WarmNeon.xml
@@ -49,7 +49,7 @@
     </option>
     <option name="BAD_CHARACTER">
       <value>
-        <option name="FOREGROUND" value="0" />
+        <option name="FOREGROUND" value="9F0E44" />
         <option name="BACKGROUND" value="ffcccc" />
       </value>
     </option>
@@ -63,10 +63,65 @@
         <option name="FOREGROUND" value="f2f0b5" />
       </value>
     </option>
+    <option name="CONSOLE_BLACK_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="000000" />
+      </value>
+    </option>
+    <option name="CONSOLE_BLUE_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="405EC9" />
+      </value>
+    </option>
+    <option name="CONSOLE_BLUE_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="7A8FD9" />
+      </value>
+    </option>
+    <option name="CONSOLE_CYAN_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="20BAD5" />
+      </value>
+    </option>
+    <option name="CONSOLE_CYAN_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="59D1E6" />
+      </value>
+    </option>
+    <option name="CONSOLE_DARKGRAY_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="555555" />
+      </value>
+    </option>
     <option name="CONSOLE_ERROR_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="e37e7e" />
-        <option name="BACKGROUND" value="404040" />
+        <option name="FOREGROUND" value="E54242" />
+      </value>
+    </option>
+    <option name="CONSOLE_GRAY_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="a7a7a7" />
+      </value>
+    </option>
+    <option name="CONSOLE_GREEN_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="34B434" />
+      </value>
+    </option>
+    <option name="CONSOLE_GREEN_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="9BC28E" />
+      </value>
+    </option>
+    #A3E131
+    <option name="CONSOLE_MAGENTA_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="FF00FF" />
+      </value>
+    </option>
+    <option name="CONSOLE_MAGENTA_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="F971BB" />
       </value>
     </option>
     <option name="CONSOLE_NORMAL_OUTPUT">
@@ -75,6 +130,16 @@
         <option name="BACKGROUND" value="404040" />
       </value>
     </option>
+    <option name="CONSOLE_RED_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="E54242" />
+      </value>
+    </option>
+    <option name="CONSOLE_RED_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="EB6F6F" />
+      </value>
+    </option>
     <option name="CONSOLE_SYSTEM_OUTPUT">
       <value>
         <option name="FOREGROUND" value="9d9d9d" />
@@ -88,9 +153,24 @@
         <option name="FONT_TYPE" value="2" />
       </value>
     </option>
+    <option name="CONSOLE_WHITE_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="ffffff" />
+      </value>
+    </option>
+    <option name="CONSOLE_YELLOW_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="DBE439" />
+      </value>
+    </option>
+    <option name="CONSOLE_YELLOW_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="DEDB74" />
+      </value>
+    </option>
     <option name="CSS.COMMENT">
       <value>
-        <option name="FOREGROUND" value="df8a8a" />
+        <option name="FOREGROUND" value="E2E95D" />
       </value>
     </option>
     <option name="CSS.FUNCTION">
@@ -109,12 +189,6 @@
         <option name="EFFECT_TYPE" value="1" />
       </value>
     </option>
-    <option name="CSS.NUMBER">
-      <value>
-        <option name="FOREGROUND" value="ff0000" />
-        <option name="FONT_TYPE" value="1" />
-      </value>
-    </option>
     <option name="CSS.PROPERTY_NAME">
       <value>
         <option name="FONT_TYPE" value="1" />
@@ -177,12 +251,6 @@
         <option name="FOREGROUND" value="de6666" />
       </value>
     </option>
-    <option name="CUSTOM_NUMBER_ATTRIBUTES">
-      <value>
-        <option name="FOREGROUND" value="ff0000" />
-        <option name="FONT_TYPE" value="1" />
-      </value>
-    </option>
     <option name="CUSTOM_STRING_ATTRIBUTES">
       <value>
         <option name="FOREGROUND" value="1cb01c" />
@@ -240,7 +308,7 @@
     </option>
     <option name="DEFAULT_INVALID_STRING_ESCAPE">
       <value>
-        <option name="FOREGROUND" value="0" />
+        <option name="FOREGROUND" value="9F0E44" />
         <option name="BACKGROUND" value="ffcccc" />
       </value>
     </option>
@@ -263,7 +331,7 @@
     </option>
     <option name="DEFAULT_NUMBER">
       <value>
-        <option name="FOREGROUND" value="ff0000" />
+        <option name="FOREGROUND" value="F971BB" />
       </value>
     </option>
     <option name="DEFAULT_PREDEFINED_SYMBOL">
@@ -339,12 +407,6 @@
         <option name="FOREGROUND" value="ca9e4d" />
       </value>
     </option>
-    <option name="DJANGO_NUMBER">
-      <value>
-        <option name="FOREGROUND" value="ff0000" />
-        <option name="FONT_TYPE" value="1" />
-      </value>
-    </option>
     <option name="DJANGO_STRING_LITERAL">
       <value>
         <option name="FOREGROUND" value="34b434" />
@@ -385,12 +447,6 @@
         <option name="FONT_TYPE" value="1" />
       </value>
     </option>
-    <option name="EL.NUMBER">
-      <value>
-        <option name="FOREGROUND" value="ff0000" />
-        <option name="FONT_TYPE" value="1" />
-      </value>
-    </option>
     <option name="EL.PARENTHS">
       <value>
         <option name="FONT_TYPE" value="1" />
@@ -562,12 +618,6 @@
         <option name="EFFECT_TYPE" value="1" />
       </value>
     </option>
-    <option name="JAVA_INVALID_STRING_ESCAPE">
-      <value>
-        <option name="FOREGROUND" value="0" />
-        <option name="BACKGROUND" value="ffcccc" />
-      </value>
-    </option>
     <option name="JAVA_KEYWORD">
       <value>
         <option name="FOREGROUND" value="ca9e4d" />
@@ -580,12 +630,6 @@
         <option name="FOREGROUND" value="e54242" />
       </value>
     </option>
-    <option name="JAVA_NUMBER">
-      <value>
-        <option name="FOREGROUND" value="ff0000" />
-        <option name="FONT_TYPE" value="1" />
-      </value>
-    </option>
     <option name="JAVA_OPERATION_SIGN">
       <value>
         <option name="FOREGROUND" value="c8c8c8" />
@@ -608,12 +652,6 @@
         <option name="FONT_TYPE" value="1" />
       </value>
     </option>
-    <option name="JS.BADCHARACTER">
-      <value>
-        <option name="FOREGROUND" value="0" />
-        <option name="BACKGROUND" value="ff0000" />
-      </value>
-    </option>
     <option name="JS.BLOCK_COMMENT">
       <value>
         <option name="FOREGROUND" value="e45041" />
@@ -656,12 +694,6 @@
         <option name="EFFECT_TYPE" value="1" />
       </value>
     </option>
-    <option name="JS.INVALID_STRING_ESCAPE">
-      <value>
-        <option name="FOREGROUND" value="8000" />
-        <option name="BACKGROUND" value="ffcccc" />
-      </value>
-    </option>
     <option name="JS.LINE_COMMENT">
       <value>
         <option name="FOREGROUND" value="d14c42" />
@@ -673,12 +705,6 @@
         <option name="EFFECT_TYPE" value="-1" />
       </value>
     </option>
-    <option name="JS.NUMBER">
-      <value>
-        <option name="FOREGROUND" value="e42713" />
-        <option name="FONT_TYPE" value="1" />
-      </value>
-    </option>
     <option name="JS.OPERATION_SIGN">
       <value />
     </option>
@@ -874,12 +900,6 @@
         <option name="EFFECT_TYPE" value="-1" />
       </value>
     </option>
-    <option name="PY.INVALID_STRING_ESCAPE">
-      <value>
-        <option name="FOREGROUND" value="0" />
-        <option name="BACKGROUND" value="ffcccc" />
-      </value>
-    </option>
     <option name="PY.KEYWORD">
       <value>
         <option name="FOREGROUND" value="cc9900" />
@@ -891,12 +911,6 @@
         <option name="FOREGROUND" value="ff6666" />
       </value>
     </option>
-    <option name="PY.NUMBER">
-      <value>
-        <option name="FOREGROUND" value="ff0000" />
-        <option name="FONT_TYPE" value="1" />
-      </value>
-    </option>
     <option name="PY.OPERATION_SIGN">
       <value>
         <option name="FOREGROUND" value="ffffff" />
@@ -1078,12 +1092,6 @@
         <option name="FONT_TYPE" value="1" />
       </value>
     </option>
-    <option name="SASS_NUMBER">
-      <value>
-        <option name="FOREGROUND" value="ff0000" />
-        <option name="FONT_TYPE" value="1" />
-      </value>
-    </option>
     <option name="SASS_RULE">
       <value>
         <option name="FOREGROUND" value="ffffff" />
@@ -1107,12 +1115,6 @@
         <option name="BACKGROUND" value="ffa600" />
       </value>
     </option>
-    <option name="SQL_BAD_CHARACTER">
-      <value>
-        <option name="FOREGROUND" value="0" />
-        <option name="BACKGROUND" value="ffcccc" />
-      </value>
-    </option>
     <option name="SQL_COLUMN">
       <value>
         <option name="FOREGROUND" value="cc9900" />
@@ -1134,12 +1136,6 @@
         <option name="FOREGROUND" value="c0c0c0" />
       </value>
     </option>
-    <option name="SQL_NUMBER">
-      <value>
-        <option name="FOREGROUND" value="ff0000" />
-        <option name="FONT_TYPE" value="1" />
-      </value>
-    </option>
     <option name="SQL_PARAMETER">
       <value>
         <option name="FOREGROUND" value="6699ff" />
diff --git a/colorSchemes/src/colorSchemes/monokai.xml b/colorSchemes/src/colorSchemes/monokai.xml
index 472c99d..f2d6913 100644
--- a/colorSchemes/src/colorSchemes/monokai.xml
+++ b/colorSchemes/src/colorSchemes/monokai.xml
@@ -196,14 +196,34 @@
         <option name="FOREGROUND" value="75715E" />
       </value>
     </option>
+    <option name="CONSOLE_BLACK_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="000000" />
+      </value>
+    </option>
     <option name="CONSOLE_BLUE_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="c7c7ff" />
+        <option name="FOREGROUND" value="0087D5" />
+      </value>
+    </option>
+    <option name="CONSOLE_BLUE_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="0AA5FF" />
       </value>
     </option>
     <option name="CONSOLE_CYAN_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="06b8b8" />
+        <option name="FOREGROUND" value="41E3F6" />
+      </value>
+    </option>
+    <option name="CONSOLE_CYAN_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="63E9F8" />
+      </value>
+    </option>
+    <option name="CONSOLE_DARKGRAY_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="555555" />
       </value>
     </option>
     <option name="CONSOLE_ERROR_OUTPUT">
@@ -218,12 +238,23 @@
     </option>
     <option name="CONSOLE_GREEN_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="68e868" />
+        <option name="FOREGROUND" value="A3E131" />
       </value>
     </option>
+    <option name="CONSOLE_GREEN_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="B8E85E" />
+      </value>
+    </option>
+    #A3E131
     <option name="CONSOLE_MAGENTA_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="ff2eff" />
+        <option name="FOREGROUND" value="8666CA" />
+      </value>
+    </option>
+    <option name="CONSOLE_MAGENTA_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="9376D0" />
       </value>
     </option>
     <option name="CONSOLE_NORMAL_OUTPUT">
@@ -233,7 +264,12 @@
     </option>
     <option name="CONSOLE_RED_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="ff6767" />
+        <option name="FOREGROUND" value="f10000" />
+      </value>
+    </option>
+    <option name="CONSOLE_RED_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="FF1F1F" />
       </value>
     </option>
     <option name="CONSOLE_SYSTEM_OUTPUT">
@@ -247,9 +283,19 @@
         <option name="FONT_TYPE" value="2" />
       </value>
     </option>
+    <option name="CONSOLE_WHITE_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="ffffff" />
+      </value>
+    </option>
     <option name="CONSOLE_YELLOW_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="754200" />
+        <option name="FOREGROUND" value="DEDB74" />
+      </value>
+    </option>
+    <option name="CONSOLE_YELLOW_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="E8E59C" />
       </value>
     </option>
     <option name="CSS.COMMENT">
diff --git a/colorSchemes/src/colorSchemes/twilight.xml b/colorSchemes/src/colorSchemes/twilight.xml
index d30254e..b7f514e 100644
--- a/colorSchemes/src/colorSchemes/twilight.xml
+++ b/colorSchemes/src/colorSchemes/twilight.xml
@@ -208,14 +208,34 @@
         <option name="FONT_TYPE" value="2" />
       </value>
     </option>
+    <option name="CONSOLE_BLACK_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="000000" />
+      </value>
+    </option>
     <option name="CONSOLE_BLUE_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="c7c7ff" />
+        <option name="FOREGROUND" value="5A80B7" />
+      </value>
+    </option>
+    <option name="CONSOLE_BLUE_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="8598B6" />
       </value>
     </option>
     <option name="CONSOLE_CYAN_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="06b8b8" />
+        <option name="FOREGROUND" value="6BA3AD" />
+      </value>
+    </option>
+    <option name="CONSOLE_CYAN_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="98A9AC" />
+      </value>
+    </option>
+    <option name="CONSOLE_DARKGRAY_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="555555" />
       </value>
     </option>
     <option name="CONSOLE_ERROR_OUTPUT">
@@ -230,12 +250,23 @@
     </option>
     <option name="CONSOLE_GREEN_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="68e868" />
+        <option name="FOREGROUND" value="8CB053" />
       </value>
     </option>
+    <option name="CONSOLE_GREEN_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="9AAF7C" />
+      </value>
+    </option>
+    #A3E131
     <option name="CONSOLE_MAGENTA_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="ff2eff" />
+        <option name="FOREGROUND" value="754273" />
+      </value>
+    </option>
+    <option name="CONSOLE_MAGENTA_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="755273" />
       </value>
     </option>
     <option name="CONSOLE_NORMAL_OUTPUT">
@@ -245,7 +276,12 @@
     </option>
     <option name="CONSOLE_RED_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="ff6767" />
+        <option name="FOREGROUND" value="EC4A00" />
+      </value>
+    </option>
+    <option name="CONSOLE_RED_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="E87854" />
       </value>
     </option>
     <option name="CONSOLE_SYSTEM_OUTPUT">
@@ -259,9 +295,19 @@
         <option name="FONT_TYPE" value="2" />
       </value>
     </option>
+    <option name="CONSOLE_WHITE_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="ffffff" />
+      </value>
+    </option>
     <option name="CONSOLE_YELLOW_OUTPUT">
       <value>
-        <option name="FOREGROUND" value="754200" />
+        <option name="FOREGROUND" value="F3CC6D" />
+      </value>
+    </option>
+    <option name="CONSOLE_YELLOW_BRIGHT_OUTPUT">
+      <value>
+        <option name="FOREGROUND" value="F3CC6D" />
       </value>
     </option>
     <option name="CSS.COMMENT">
diff --git a/community-resources/src/idea/IdeaApplicationInfo.xml b/community-resources/src/idea/IdeaApplicationInfo.xml
index 8e36755..42da604 100644
--- a/community-resources/src/idea/IdeaApplicationInfo.xml
+++ b/community-resources/src/idea/IdeaApplicationInfo.xml
@@ -23,7 +23,7 @@
   <help file="ideahelp.jar" root="idea"/>
   <documentation url="http://www.jetbrains.com/idea/documentation"/>
   <support url="http://www.jetbrains.com/support/idea/index.html"/>
-  <feedback eap-url="http://youtrack.jetbrains.com"
+  <feedback eap-url="http://youtrack.jetbrains.com/newissue?project=IDEA&amp;clearDraft=true&amp;c=Affected+versions+$BUILD"
             release-url="http://www.jetbrains.com/feedback/feedback.jsp?product=IDEA&amp;build=$BUILD&amp;timezone=$TIMEZONE&amp;eval=$EVAL"/>
   <plugins url="http://plugins.jetbrains.com"/>
   <whatsnew url="http://www.jetbrains.com/idea/whatsnew/index.html"/>
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
index d03ec5b..167cd7d 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
@@ -787,7 +787,12 @@
     });
   }
 
+  private static final Key<Boolean> OLD_IMPLEMENTATION_WARNING_SHOWN = Key.create("_old_make_implementation_warning_shown_"); 
   private void notifyDeprecatedImplementation() {
+    if (OLD_IMPLEMENTATION_WARNING_SHOWN.get(myProject, Boolean.FALSE).booleanValue()) {
+      return;
+    }
+    OLD_IMPLEMENTATION_WARNING_SHOWN.set(myProject, Boolean.TRUE);
     final NotificationListener hyperlinkHandler = new NotificationListener.Adapter() {
       @Override
       protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) {
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
index 8ba9de9..d36a3b0 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
@@ -1759,7 +1759,7 @@
   }
   
   public boolean isMarkedForCompilation(Project project, VirtualFile file) {
-    if (CompilerWorkspaceConfiguration.getInstance(project).USE_COMPILE_SERVER) {
+    if (CompilerWorkspaceConfiguration.getInstance(project).useOutOfProcessBuild()) {
       final CompilerManager compilerManager = CompilerManager.getInstance(project);
       return !compilerManager.isUpToDate(compilerManager.createFilesCompileScope(new VirtualFile[]{file}));
     }
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form
index 36f3b45..5e6fdda 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form
@@ -38,7 +38,7 @@
           <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.no.warnings"/>
         </properties>
       </component>
-      <grid id="d7ddf" layout-manager="GridLayoutManager" row-count="2" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+      <grid id="d7ddf" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
         <margin top="10" left="8" bottom="0" right="0"/>
         <constraints>
           <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -62,33 +62,6 @@
             </constraints>
             <properties/>
           </component>
-          <component id="327dc" class="javax.swing.JLabel">
-            <constraints>
-              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties>
-              <text resource-bundle="messages/CompilerBundle" key="javac.option.max.heap.size"/>
-            </properties>
-          </component>
-          <component id="15c16" class="javax.swing.JTextField" binding="myJavacMaximumHeapField">
-            <constraints>
-              <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties>
-              <columns value="4"/>
-              <margin top="0" left="2" bottom="0" right="0"/>
-              <text value="128"/>
-            </properties>
-          </component>
-          <component id="6f8c2" class="com.intellij.ui.components.JBLabel">
-            <constraints>
-              <grid row="1" column="2" row-span="1" col-span="2" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties>
-              <enabled value="false"/>
-              <text value="(ineffective when &quot;Use external build&quot; is on)"/>
-            </properties>
-          </component>
         </children>
       </grid>
       <vspacer id="af30">
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.java
index ad9cb1d..5227dfc 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.java
@@ -35,7 +35,6 @@
   private JCheckBox myCbDebuggingInfo;
   private JCheckBox myCbGenerateNoWarnings;
   private RawCommandLineEditor myAdditionalOptionsField;
-  private JTextField myJavacMaximumHeapField;
   private JCheckBox myCbProceedOnErrors;
   private final EclipseCompilerOptions myCompilerSettings;
 
@@ -59,7 +58,7 @@
   }
 
   public boolean isModified() {
-    boolean isModified = ComparingUtils.isModified(myJavacMaximumHeapField, myCompilerSettings.MAXIMUM_HEAP_SIZE);
+    boolean isModified = false;
 
     isModified |= ComparingUtils.isModified(myCbDeprecation, myCompilerSettings.DEPRECATION);
     isModified |= ComparingUtils.isModified(myCbDebuggingInfo, myCompilerSettings.DEBUGGING_INFO);
@@ -70,17 +69,6 @@
   }
 
   public void apply() throws ConfigurationException {
-
-    try {
-      myCompilerSettings.MAXIMUM_HEAP_SIZE = Integer.parseInt(myJavacMaximumHeapField.getText());
-      if(myCompilerSettings.MAXIMUM_HEAP_SIZE < 1) {
-        myCompilerSettings.MAXIMUM_HEAP_SIZE = 128;
-      }
-    }
-    catch(NumberFormatException exception) {
-      myCompilerSettings.MAXIMUM_HEAP_SIZE = 128;
-    }
-
     myCompilerSettings.DEPRECATION =  myCbDeprecation.isSelected();
     myCompilerSettings.DEBUGGING_INFO = myCbDebuggingInfo.isSelected();
     myCompilerSettings.GENERATE_NO_WARNINGS = myCbGenerateNoWarnings.isSelected();
@@ -89,7 +77,6 @@
   }
 
   public void reset() {
-    myJavacMaximumHeapField.setText(Integer.toString(myCompilerSettings.MAXIMUM_HEAP_SIZE));
     myCbDeprecation.setSelected(myCompilerSettings.DEPRECATION);
     myCbDebuggingInfo.setSelected(myCompilerSettings.DEBUGGING_INFO);
     myCbGenerateNoWarnings.setSelected(myCompilerSettings.GENERATE_NO_WARNINGS);
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfigurable.java
index c51f5f30..1c8910a 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfigurable.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfigurable.java
@@ -34,7 +34,6 @@
   private JCheckBox myCbDeprecation;
   private JCheckBox myCbGenerateNoWarnings;
   private RawCommandLineEditor myAdditionalOptionsField;
-  private JTextField myJavacMaximumHeapField;
   private final JpsJavaCompilerOptions myJavacSettings;
 
   public JavacConfigurable(final JpsJavaCompilerOptions javacSettings) {
@@ -56,8 +55,6 @@
 
   public boolean isModified() {
     boolean isModified = false;
-    isModified |= ComparingUtils.isModified(myJavacMaximumHeapField, myJavacSettings.MAXIMUM_HEAP_SIZE);
-
     isModified |= ComparingUtils.isModified(myCbDeprecation, myJavacSettings.DEPRECATION);
     isModified |= ComparingUtils.isModified(myCbDebuggingInfo, myJavacSettings.DEBUGGING_INFO);
     isModified |= ComparingUtils.isModified(myCbGenerateNoWarnings, myJavacSettings.GENERATE_NO_WARNINGS);
@@ -66,17 +63,6 @@
   }
 
   public void apply() throws ConfigurationException {
-
-    try {
-      myJavacSettings.MAXIMUM_HEAP_SIZE = Integer.parseInt(myJavacMaximumHeapField.getText());
-      if(myJavacSettings.MAXIMUM_HEAP_SIZE < 1) {
-        myJavacSettings.MAXIMUM_HEAP_SIZE = 128;
-      }
-    }
-    catch(NumberFormatException exception) {
-      myJavacSettings.MAXIMUM_HEAP_SIZE = 128;
-    }
-
     myJavacSettings.DEPRECATION =  myCbDeprecation.isSelected();
     myJavacSettings.DEBUGGING_INFO = myCbDebuggingInfo.isSelected();
     myJavacSettings.GENERATE_NO_WARNINGS = myCbGenerateNoWarnings.isSelected();
@@ -84,7 +70,6 @@
   }
 
   public void reset() {
-    myJavacMaximumHeapField.setText(Integer.toString(myJavacSettings.MAXIMUM_HEAP_SIZE));
     myCbDeprecation.setSelected(myJavacSettings.DEPRECATION);
     myCbDebuggingInfo.setSelected(myJavacSettings.DEBUGGING_INFO);
     myCbGenerateNoWarnings.setSelected(myJavacSettings.GENERATE_NO_WARNINGS);
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form
index bf4baec..3dc8e99 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form
@@ -3,7 +3,7 @@
   <grid id="280f7" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
     <margin top="0" left="0" bottom="0" right="0"/>
     <constraints>
-      <xy x="79" y="160" width="574" height="210"/>
+      <xy x="79" y="160" width="577" height="210"/>
     </constraints>
     <properties/>
     <clientProperties>
@@ -37,7 +37,7 @@
           <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.no.warnings"/>
         </properties>
       </component>
-      <grid id="d7ddf" layout-manager="GridLayoutManager" row-count="2" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+      <grid id="d7ddf" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
         <margin top="10" left="8" bottom="0" right="0"/>
         <constraints>
           <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -61,33 +61,6 @@
             </constraints>
             <properties/>
           </component>
-          <component id="327dc" class="javax.swing.JLabel">
-            <constraints>
-              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties>
-              <text resource-bundle="messages/CompilerBundle" key="javac.option.max.heap.size"/>
-            </properties>
-          </component>
-          <component id="15c16" class="javax.swing.JTextField" binding="myJavacMaximumHeapField">
-            <constraints>
-              <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties>
-              <columns value="4"/>
-              <margin top="0" left="2" bottom="0" right="0"/>
-              <text value="128"/>
-            </properties>
-          </component>
-          <component id="9ae23" class="com.intellij.ui.components.JBLabel">
-            <constraints>
-              <grid row="1" column="2" row-span="1" col-span="2" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties>
-              <enabled value="false"/>
-              <text value="(ineffective when &quot;Use external build&quot; is on)"/>
-            </properties>
-          </component>
         </children>
       </grid>
       <vspacer id="72a3c">
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsPanel.form b/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsPanel.form
index 179dbe2..c89fdca 100644
--- a/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsPanel.form
+++ b/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsPanel.form
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.options.CompilerUIConfigurable">
-  <grid id="1663f" binding="myPanel" layout-manager="GridLayoutManager" row-count="11" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+  <grid id="1663f" binding="myPanel" layout-manager="GridLayoutManager" row-count="10" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
     <margin top="0" left="0" bottom="0" right="0"/>
     <constraints>
       <xy x="28" y="24" width="883" height="379"/>
@@ -10,7 +10,7 @@
     <children>
       <vspacer id="67edf">
         <constraints>
-          <grid row="10" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+          <grid row="9" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
         </constraints>
       </vspacer>
       <grid id="b341d" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="1">
@@ -76,17 +76,9 @@
           <text resource-bundle="messages/CompilerBundle" key="label.option.autoshow.first.error"/>
         </properties>
       </component>
-      <component id="ce617" class="javax.swing.JCheckBox" binding="myCbUseExternalBuild" default-binding="true">
-        <constraints>
-          <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties>
-          <text value="Use external build"/>
-        </properties>
-      </component>
       <component id="b9b2d" class="javax.swing.JCheckBox" binding="myCbEnableAutomake">
         <constraints>
-          <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+          <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <text value="Make project automatically"/>
@@ -94,7 +86,7 @@
       </component>
       <component id="17126" class="javax.swing.JLabel" binding="myHeapSizeLabel">
         <constraints>
-          <grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+          <grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <text value="Compiler process heap size (Mbytes):"/>
@@ -102,7 +94,7 @@
       </component>
       <component id="a28b8" class="javax.swing.JTextField" binding="myHeapSizeField">
         <constraints>
-          <grid row="8" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false">
+          <grid row="7" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false">
             <preferred-size width="50" height="-1"/>
           </grid>
         </constraints>
@@ -110,7 +102,7 @@
       </component>
       <component id="5b86a" class="javax.swing.JLabel" binding="myVMOptionsLabel">
         <constraints>
-          <grid row="9" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+          <grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <text value="Additional compiler process VM options:"/>
@@ -118,7 +110,7 @@
       </component>
       <component id="b5547" class="javax.swing.JTextField" binding="myVMOptionsField">
         <constraints>
-          <grid row="9" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+          <grid row="8" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
             <preferred-size width="150" height="-1"/>
           </grid>
         </constraints>
@@ -126,7 +118,7 @@
       </component>
       <component id="ba694" class="javax.swing.JCheckBox" binding="myCbParallelCompilation">
         <constraints>
-          <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+          <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <text value="Compile independent modules in parallel"/>
@@ -134,7 +126,7 @@
       </component>
       <component id="91979" class="javax.swing.JLabel" binding="myParallelCompilationLegendLabel">
         <constraints>
-          <grid row="6" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+          <grid row="5" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <text value="(may require larger heap size)"/>
@@ -142,7 +134,7 @@
       </component>
       <component id="732b1" class="javax.swing.JLabel" binding="myEnableAutomakeLegendLabel">
         <constraints>
-          <grid row="5" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+          <grid row="4" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <text value="(only works while not running / debugging)"/>
@@ -150,7 +142,7 @@
       </component>
       <component id="4b44" class="javax.swing.JCheckBox" binding="myCbRebuildOnDependencyChange" default-binding="true">
         <constraints>
-          <grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+          <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <text value="Rebuild module on dependency change"/>
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
index 38769dc..b97a103 100644
--- a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
+++ b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
@@ -36,11 +36,9 @@
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
 import java.util.*;
 
-import static com.intellij.compiler.options.CompilerOptionsFilter.*;
+import static com.intellij.compiler.options.CompilerOptionsFilter.Setting;
 
 public class CompilerUIConfigurable implements SearchableConfigurable, Configurable.NoScroll {
   private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.options.CompilerUIConfigurable");
@@ -77,7 +75,6 @@
   private JCheckBox            myCbAssertNotNull;
   private JBLabel              myPatternLegendLabel;
   private JCheckBox            myCbAutoShowFirstError;
-  private JCheckBox            myCbUseExternalBuild;
   private JCheckBox            myCbEnableAutomake;
   private JCheckBox            myCbParallelCompilation;
   private JTextField           myHeapSizeField;
@@ -93,19 +90,12 @@
     myProject = project;
 
     myPatternLegendLabel.setText("<html><body>" +
-                                 "Use <b>;</b> to separate patterns and <b>!</b> to negate a pattern. " +
-                                 "Accepted wildcards: <b>?</b> &mdash; exactly one symbol; <b>*</b> &mdash; zero or more symbols; " +
-                                 "<b>/</b> &mdash; path separator; <b>/**/</b> &mdash; any number of directories; " +
-                                 "<i>&lt;dir_name&gt;</i>:<i>&lt;pattern&gt;</i> &mdash; restrict to source roots with the specified name" +
-                                 "</body></html>");
+                                   "Use <b>;</b> to separate patterns and <b>!</b> to negate a pattern. " +
+                                   "Accepted wildcards: <b>?</b> &mdash; exactly one symbol; <b>*</b> &mdash; zero or more symbols; " +
+                                   "<b>/</b> &mdash; path separator; <b>/**/</b> &mdash; any number of directories; " +
+                                   "<i>&lt;dir_name&gt;</i>:<i>&lt;pattern&gt;</i> &mdash; restrict to source roots with the specified name" +
+                                   "</body></html>");
     myPatternLegendLabel.setForeground(new JBColor(Gray._50, Gray._130));
-    myCbUseExternalBuild.addItemListener(new ItemListener() {
-      @Override
-      public void itemStateChanged(ItemEvent e) {
-        updateExternalMakeOptionControls(myCbUseExternalBuild.isSelected());
-      }
-    });
-
     tweakControls(project);
   }
 
@@ -141,7 +131,6 @@
     controls.put(Setting.CLEAR_OUTPUT_DIR_ON_REBUILD, Collections.<JComponent>singleton(myCbClearOutputDirectory));
     controls.put(Setting.ADD_NOT_NULL_ASSERTIONS, Collections.<JComponent>singleton(myCbAssertNotNull));
     controls.put(Setting.AUTO_SHOW_FIRST_ERROR_IN_EDITOR, Collections.<JComponent>singleton(myCbAutoShowFirstError));
-    controls.put(Setting.EXTERNAL_BUILD, ContainerUtilRt.<JComponent>newArrayList(myCbUseExternalBuild));
     controls.put(Setting.AUTO_MAKE, ContainerUtilRt.<JComponent>newArrayList(myCbEnableAutomake, myEnableAutomakeLegendLabel));
     controls.put(Setting.PARALLEL_COMPILATION,
                  ContainerUtilRt.<JComponent>newArrayList(myCbParallelCompilation, myParallelCompilationLegendLabel));
@@ -166,14 +155,12 @@
     myCbAutoShowFirstError.setSelected(workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR);
     myCbClearOutputDirectory.setSelected(workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY);
     myCbAssertNotNull.setSelected(configuration.isAddNotNullAssertions());
-    myCbUseExternalBuild.setSelected(workspaceConfiguration.USE_COMPILE_SERVER);
     myCbEnableAutomake.setSelected(workspaceConfiguration.MAKE_PROJECT_ON_SAVE);
     myCbParallelCompilation.setSelected(workspaceConfiguration.PARALLEL_COMPILATION);
     myCbRebuildOnDependencyChange.setSelected(workspaceConfiguration.REBUILD_ON_DEPENDENCY_CHANGE);
     myHeapSizeField.setText(String.valueOf(workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE));
     final String options = workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS;
     myVMOptionsField.setText(options == null ? "" : options.trim());
-    updateExternalMakeOptionControls(myCbUseExternalBuild.isSelected());
 
     configuration.convertPatterns();
 
@@ -201,9 +188,7 @@
     if (!myDisabledSettings.contains(Setting.CLEAR_OUTPUT_DIR_ON_REBUILD)) {
       workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY = myCbClearOutputDirectory.isSelected();
     }
-    boolean wasUsingExternalMake = workspaceConfiguration.USE_COMPILE_SERVER;
     if (!myDisabledSettings.contains(Setting.EXTERNAL_BUILD)) {
-      workspaceConfiguration.USE_COMPILE_SERVER = myCbUseExternalBuild.isSelected();
       if (!myDisabledSettings.contains(Setting.AUTO_MAKE)) {
         workspaceConfiguration.MAKE_PROJECT_ON_SAVE = myCbEnableAutomake.isSelected();
       }
@@ -234,12 +219,8 @@
       String extensionString = myResourcePatternsField.getText().trim();
       applyResourcePatterns(extensionString, (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject));
     }
-    if (wasUsingExternalMake != workspaceConfiguration.USE_COMPILE_SERVER) {
-      myProject.getMessageBus().syncPublisher(ExternalBuildOptionListener.TOPIC).externalBuildOptionChanged(workspaceConfiguration.USE_COMPILE_SERVER);
-    }
-    if (workspaceConfiguration.USE_COMPILE_SERVER) {
-      BuildManager.getInstance().clearState(myProject);
-    }
+    
+    BuildManager.getInstance().clearState(myProject);
   }
 
   private static void applyResourcePatterns(String extensionString, final CompilerConfigurationImpl configuration)
@@ -277,8 +258,6 @@
     final CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(myProject);
     boolean isModified = !myDisabledSettings.contains(Setting.AUTO_SHOW_FIRST_ERROR_IN_EDITOR)
                          && ComparingUtils.isModified(myCbAutoShowFirstError, workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR);
-    isModified |= !myDisabledSettings.contains(Setting.EXTERNAL_BUILD)
-                  && ComparingUtils.isModified(myCbUseExternalBuild, workspaceConfiguration.USE_COMPILE_SERVER);
     isModified |= !myDisabledSettings.contains(Setting.AUTO_MAKE)
                   && ComparingUtils.isModified(myCbEnableAutomake, workspaceConfiguration.MAKE_PROJECT_ON_SAVE);
     isModified |= !myDisabledSettings.contains(Setting.PARALLEL_COMPILATION)
@@ -325,16 +304,6 @@
   public void disposeUIResources() {
   }
 
-  private void updateExternalMakeOptionControls(boolean enabled) {
-    myCbEnableAutomake.setEnabled(enabled);
-    myCbParallelCompilation.setEnabled(enabled);
-    myCbRebuildOnDependencyChange.setEnabled(enabled);
-    myHeapSizeField.setEnabled(enabled);
-    myVMOptionsField.setEnabled(enabled);
-    myHeapSizeLabel.setEnabled(enabled);
-    myVMOptionsLabel.setEnabled(enabled);
-  }
-
   private void createUIComponents() {
     myResourcePatternsField = new RawCommandLineEditor(LINE_PARSER, LINE_JOINER);
     myResourcePatternsField.setDialogCaption("Resource patterns");
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorWrapper.java b/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorWrapper.java
index 88fe95c..cadbc0f 100644
--- a/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorWrapper.java
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorWrapper.java
@@ -58,6 +58,7 @@
   private final InspectionProjectProfileManager myProfileManager;
   private final PsiDocumentManager myPsiDocumentManager;
   private static final ThreadLocal<Boolean> ourCompilationThreads = new ThreadLocal<Boolean>() {
+    @Override
     protected Boolean initialValue() {
       return Boolean.FALSE;
     }
@@ -95,11 +96,13 @@
       myVirtualFile = psiFile.getVirtualFile();
     }
 
+    @Override
     @NotNull
     public VirtualFile getFile() {
       return myVirtualFile;
     }
 
+    @Override
     @Nullable
     public ValidityState getValidityState() {
       if (myValidityState == null) {
@@ -121,6 +124,7 @@
     }
   }
 
+  @Override
   @NotNull
   public ProcessingItem[] getProcessingItems(final CompileContext context) {
     final Project project = context.getProject();
@@ -129,6 +133,7 @@
     }
     final ExcludedEntriesConfiguration excludedEntriesConfiguration = ValidationConfiguration.getExcludedEntriesConfiguration(project);
     final List<ProcessingItem> items = new ReadAction<List<ProcessingItem>>() {
+      @Override
       protected void run(final Result<List<ProcessingItem>> result) {
         final CompileScope compileScope = context.getCompileScope();
         if (!myValidator.isAvailableOnScope(compileScope)) return;
@@ -167,6 +172,7 @@
     return items.toArray(new ProcessingItem[items.size()]);
   }
 
+  @Override
   public ProcessingItem[] process(final CompileContext context, final ProcessingItem[] items) {
     context.getProgressIndicator().setText(myValidator.getProgressIndicatorText());
 
@@ -307,7 +313,13 @@
 
     final List<ExternalAnnotator> annotators = ExternalLanguageAnnotators.allForFile(StdLanguages.XML, xmlFile);
     for (ExternalAnnotator annotator : annotators) {
-      annotator.annotate(xmlFile, holder);
+      Object initial = annotator.collectInformation(xmlFile);
+      if (initial != null) {
+        Object result = annotator.doAnnotate(initial);
+        if (result != null) {
+          annotator.apply(xmlFile, result, holder);
+        }
+      }
     }
 
     if (!holder.hasAnnotations()) return Collections.emptyMap();
@@ -331,15 +343,18 @@
   }
 
 
+  @Override
   @NotNull
   public String getDescription() {
     return myValidator.getDescription();
   }
 
+  @Override
   public boolean validateConfiguration(final CompileScope scope) {
     return true;
   }
 
+  @Override
   public ValidityState createValidityState(final DataInput in) throws IOException {
     return PsiElementsValidityState.load(in);
   }
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElementType.java
index dc0383f..e82f277e 100644
--- a/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElementType.java
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElementType.java
@@ -28,7 +28,6 @@
 import com.intellij.packaging.ui.ArtifactEditorContext;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.util.ArrayList;
@@ -89,11 +88,6 @@
 
   protected abstract String getItemText(F item);
 
-  @Nullable
-  protected Icon getIcon(F item) {
-    return FacetTypeRegistry.getInstance().findFacetType(myFacetType).getIcon();
-  }
-
   private class ChooseFacetsDialog extends ChooseElementsDialog<F> {
     private ChooseFacetsDialog(Project project, List<? extends F> items, String title, String description) {
       super(project, items, title, description, true);
@@ -106,7 +100,7 @@
 
     @Override
     protected Icon getItemIcon(F item) {
-      return FacetBasedPackagingElementType.this.getIcon(item);
+      return FacetTypeRegistry.getInstance().findFacetType(myFacetType).getIcon();
     }
   }
 }
diff --git a/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java b/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java
index 629a488..57ca440 100644
--- a/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java
+++ b/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java
@@ -43,7 +43,7 @@
   public boolean AUTO_SHOW_ERRORS_IN_EDITOR = true;
   @Deprecated public boolean CLOSE_MESSAGE_VIEW_IF_SUCCESS = true;
   public boolean CLEAR_OUTPUT_DIRECTORY = true;
-  public boolean USE_COMPILE_SERVER = true;
+  public boolean USE_OUT_OF_PROCESS_BUILD = true;
   public boolean MAKE_PROJECT_ON_SAVE = false; // until we fix problems with several open projects (IDEA-104064), daemon slowness (IDEA-104666)
   public boolean PARALLEL_COMPILATION = false;
   public int COMPILER_PROCESS_HEAP_SIZE = DEFAULT_COMPILE_PROCESS_HEAP_SIZE;
@@ -63,7 +63,7 @@
   }
 
   public boolean useOutOfProcessBuild() {
-    return USE_COMPILE_SERVER;
+    return USE_OUT_OF_PROCESS_BUILD;
   }
 
   public boolean allowAutoMakeWhileRunningApplication() {
diff --git a/java/debugger/impl/src/com/intellij/debugger/DebuggerInvocationUtil.java b/java/debugger/impl/src/com/intellij/debugger/DebuggerInvocationUtil.java
index c0dfbb9..ebb5bef 100644
--- a/java/debugger/impl/src/com/intellij/debugger/DebuggerInvocationUtil.java
+++ b/java/debugger/impl/src/com/intellij/debugger/DebuggerInvocationUtil.java
@@ -22,76 +22,79 @@
 import com.intellij.openapi.util.Computable;
 import com.intellij.psi.PsiDocumentManager;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 
 public class DebuggerInvocationUtil {
-  public static void swingInvokeLater(final Project project, @NotNull final Runnable runnable) {
+  public static void swingInvokeLater(@Nullable final Project project, @NotNull final Runnable runnable) {
+    if (project == null) {
+      return;
+    }
+
     SwingUtilities.invokeLater(new Runnable() {
+      @Override
       public void run() {
-        if (project != null && !project.isDisposed()) {
-          runnable.run();
-        }
-      }
-    });
-  }
-  public static void invokeLater(final Project project, @NotNull final Runnable runnable) {
-    ApplicationManager.getApplication().invokeLater(new Runnable() {
-      public void run() {
-        if (project != null && !project.isDisposed()) {
+        if (!project.isDisposed()) {
           runnable.run();
         }
       }
     });
   }
 
-  public static void invokeLater(final Project project, @NotNull final Runnable runnable, ModalityState state) {
-    ApplicationManager.getApplication().invokeLater(new Runnable() {
-      public void run() {
-        if(project == null || project.isDisposed()) return;
+  public static void invokeLater(@Nullable Project project, @NotNull Runnable runnable) {
+    if (project != null) {
+      ApplicationManager.getApplication().invokeLater(runnable, project.getDisposed());
+    }
+  }
 
-        runnable.run();
-      }
-    }, state);
+  public static void invokeLater(@Nullable Project project, @NotNull Runnable runnable, ModalityState state) {
+    if (project != null) {
+      ApplicationManager.getApplication().invokeLater(runnable, state, project.getDisposed());
+    }
   }
 
   public static void invokeAndWait(final Project project, @NotNull final Runnable runnable, ModalityState state) {
-    ApplicationManager.getApplication().invokeAndWait(new Runnable() {
-      public void run() {
-        if(project == null || project.isDisposed()) return;
-
-        runnable.run();
-      }
-    }, state);
+    if (project != null) {
+      ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+        @Override
+        public void run() {
+          if (!project.isDisposed()) {
+            runnable.run();
+          }
+        }
+      }, state);
+    }
   }
 
-  public static  <T> T commitAndRunReadAction(Project project, final EvaluatingComputable<T> computable) throws EvaluateException {
-    final Throwable[] ex = new Throwable[] { null };
+  public static <T> T commitAndRunReadAction(Project project, final EvaluatingComputable<T> computable) throws EvaluateException {
+    final Throwable[] ex = new Throwable[]{null};
     T result = PsiDocumentManager.getInstance(project).commitAndRunReadAction(new Computable<T>() {
-          public T compute() {
-            try {
-              return computable.compute();
-            }
-            catch (RuntimeException e) {
-              ex[0] = e;
-            }
-            catch (Exception th) {
-              ex[0] = th;
-            }
+      @Override
+      public T compute() {
+        try {
+          return computable.compute();
+        }
+        catch (RuntimeException e) {
+          ex[0] = e;
+        }
+        catch (Exception th) {
+          ex[0] = th;
+        }
 
-            return null;
-          }
-        });
+        return null;
+      }
+    });
 
-    if(ex[0] != null) {
-      if(ex[0] instanceof RuntimeException) {
+    if (ex[0] != null) {
+      if (ex[0] instanceof RuntimeException) {
         throw (RuntimeException)ex[0];
       }
       else {
-        throw (EvaluateException) ex[0];
+        throw (EvaluateException)ex[0];
       }
     }
 
     return result;
   }
-}
+}
\ No newline at end of file
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java
index deb5752..54cef88 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java
@@ -19,8 +19,8 @@
 import com.intellij.debugger.ui.breakpoints.BreakpointPropertiesPanel;
 import com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter;
 import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.markup.GutterIconRenderer;
@@ -28,7 +28,7 @@
 import com.intellij.openapi.ui.popup.Balloon;
 import com.intellij.openapi.ui.popup.JBPopupListener;
 import com.intellij.openapi.ui.popup.LightweightWindowEvent;
-import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.EmptyRunnable;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.wm.IdeFocusManager;
 import com.intellij.util.ui.UIUtil;
@@ -41,48 +41,31 @@
 import javax.swing.*;
 import java.awt.*;
 
-/**
- * Created with IntelliJ IDEA.
- * User: zajac
- * Date: 04.05.12
- * Time: 4:10
- * To change this template use File | Settings | File Templates.
- */
 public class JavaEditBreakpointActionHandler extends EditBreakpointActionHandler {
   @Override
   protected void doShowPopup(final Project project, final JComponent component, final Point whereToShow, final Object breakpoint) {
-    if (!(breakpoint instanceof BreakpointWithHighlighter)) return;
+    if (!(breakpoint instanceof BreakpointWithHighlighter)) {
+      return;
+    }
 
     final BreakpointWithHighlighter javaBreakpoint = (BreakpointWithHighlighter)breakpoint;
-    Key<? extends BreakpointWithHighlighter> category = javaBreakpoint.getCategory();
-
-    final BreakpointFactory[] allFactories = ApplicationManager.getApplication().getExtensions(BreakpointFactory.EXTENSION_POINT_NAME);
     BreakpointFactory breakpointFactory = null;
-    for (BreakpointFactory factory : allFactories) {
-      if (factory.getBreakpointCategory().equals(category)) {
+    for (BreakpointFactory factory : BreakpointFactory.EXTENSION_POINT_NAME.getExtensions()) {
+      if (factory.getBreakpointCategory().equals(javaBreakpoint.getCategory())) {
         breakpointFactory = factory;
       }
     }
     assert breakpointFactory != null : "can't find factory for breakpoint " + javaBreakpoint;
 
     final BreakpointPropertiesPanel propertiesPanel = breakpointFactory.createBreakpointPropertiesPanel(project, true);
+    assert propertiesPanel != null;
     propertiesPanel.initFrom(javaBreakpoint, false);
 
     final JComponent mainPanel = propertiesPanel.getPanel();
-    final String displayName = javaBreakpoint.getDisplayName();
-
-    final JBPopupListener saveOnClose = new JBPopupListener() {
-      @Override
-      public void beforeShown(LightweightWindowEvent event) {
-      }
-
+    final JBPopupListener saveOnClose = new JBPopupListener.Adapter() {
       @Override
       public void onClosed(LightweightWindowEvent event) {
-        propertiesPanel.saveTo(javaBreakpoint, new Runnable() {
-          @Override
-          public void run() {
-          }
-        });
+        propertiesPanel.saveTo(javaBreakpoint, EmptyRunnable.getInstance());
       }
     };
 
@@ -93,13 +76,12 @@
           @Override
           public void run() {
             BreakpointsDialogFactory.getInstance(project).showDialog(javaBreakpoint);
-
           }
         });
       }
     };
-    final Balloon balloon = DebuggerUIUtil.showBreakpointEditor(project, mainPanel, displayName, whereToShow, component, showMoreOptions,
-                                                                breakpoint);
+
+    final Balloon balloon = DebuggerUIUtil.showBreakpointEditor(project, mainPanel, whereToShow, component, showMoreOptions, breakpoint);
     balloon.addListener(saveOnClose);
 
     propertiesPanel.setDelegate(new BreakpointPropertiesPanel.Delegate() {
@@ -107,9 +89,7 @@
       public void showActionsPanel() {
         propertiesPanel.setActionsPanelVisible(true);
         balloon.hide();
-        final Balloon newBalloon =
-          DebuggerUIUtil.showBreakpointEditor(project, mainPanel, displayName, whereToShow, component, showMoreOptions, breakpoint);
-        newBalloon.addListener(saveOnClose);
+        DebuggerUIUtil.showBreakpointEditor(project, mainPanel, whereToShow, component, showMoreOptions, breakpoint).addListener(saveOnClose);
       }
     });
 
@@ -124,7 +104,7 @@
   @Override
   public boolean isEnabled(@NotNull Project project, AnActionEvent event) {
     DataContext dataContext = event.getDataContext();
-    Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
+    Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
     if (editor == null) {
       return false;
     }
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java
index 0247790..54d1545 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java
@@ -19,9 +19,9 @@
 import com.intellij.debugger.DebuggerManagerEx;
 import com.intellij.debugger.InstanceFilter;
 import com.intellij.debugger.SourcePosition;
+import com.intellij.debugger.engine.DebuggerUtils;
 import com.intellij.debugger.engine.requests.RequestManagerImpl;
 import com.intellij.debugger.impl.DebuggerSession;
-import com.intellij.debugger.impl.DebuggerUtilsEx;
 import com.intellij.debugger.ui.breakpoints.Breakpoint;
 import com.intellij.debugger.ui.breakpoints.BreakpointManager;
 import com.intellij.debugger.ui.breakpoints.FieldBreakpoint;
@@ -33,7 +33,6 @@
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.FileTypeManager;
 import com.intellij.openapi.fileTypes.StdFileTypes;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -50,8 +49,9 @@
  */
 public class ToggleFieldBreakpointAction extends AnAction {
 
+  @Override
   public void actionPerformed(AnActionEvent e) {
-    Project project = e.getData(PlatformDataKeys.PROJECT);
+    Project project = e.getData(CommonDataKeys.PROJECT);
     if (project == null) {
       return;
     }
@@ -83,7 +83,7 @@
 
             RequestManagerImpl.createRequests(fieldBreakpoint);
 
-            manager.editBreakpoint(fieldBreakpoint, PlatformDataKeys.EDITOR.getData(e.getDataContext()));
+            manager.editBreakpoint(fieldBreakpoint, CommonDataKeys.EDITOR.getData(e.getDataContext()));
           }
         }
         else {
@@ -93,6 +93,7 @@
     }
   }
 
+  @Override
   public void update(AnActionEvent event){
     SourcePosition place = getPlace(event);
     boolean toEnable = place != null;
@@ -105,7 +106,7 @@
     }
     else if(DebuggerAction.isContextView(event)) {
       presentation.setText(DebuggerBundle.message("action.add.field.watchpoint.text"));
-      Project project = event.getData(PlatformDataKeys.PROJECT);
+      Project project = event.getData(CommonDataKeys.PROJECT);
       if(project != null && place != null) {
         Document document = PsiDocumentManager.getInstance(project).getDocument(place.getFile());
         if (document != null) {
@@ -125,14 +126,14 @@
   @Nullable
   public static SourcePosition getPlace(AnActionEvent event) {
     final DataContext dataContext = event.getDataContext();
-    Project project = event.getData(PlatformDataKeys.PROJECT);
+    Project project = event.getData(CommonDataKeys.PROJECT);
     if(project == null) {
       return null;
     }
     if (ActionPlaces.PROJECT_VIEW_POPUP.equals(event.getPlace()) ||
         ActionPlaces.STRUCTURE_VIEW_POPUP.equals(event.getPlace()) ||
         ActionPlaces.FAVORITES_VIEW_POPUP.equals(event.getPlace())) {
-      final PsiElement psiElement = event.getData(LangDataKeys.PSI_ELEMENT);
+      final PsiElement psiElement = event.getData(CommonDataKeys.PSI_ELEMENT);
       if(psiElement instanceof PsiField) {
         return SourcePosition.createFromElement(psiElement);
       }
@@ -152,7 +153,7 @@
         if(node != null && node.getDescriptor() instanceof FieldDescriptorImpl) {
           Field field = ((FieldDescriptorImpl)node.getDescriptor()).getField();
           DebuggerSession session = tree.getDebuggerContext().getDebuggerSession();
-          PsiClass psiClass = DebuggerUtilsEx.findClass(field.declaringType().name(), project, (session != null) ? session.getSearchScope(): GlobalSearchScope.allScope(project));
+          PsiClass psiClass = DebuggerUtils.findClass(field.declaringType().name(), project, (session != null) ? session.getSearchScope() : GlobalSearchScope.allScope(project));
           if(psiClass != null) {
             psiClass = (PsiClass) psiClass.getNavigationElement();
             final PsiField psiField = psiClass.findFieldByName(field.name(), true);
@@ -165,7 +166,7 @@
       return null;
     }
 
-    Editor editor = event.getData(PlatformDataKeys.EDITOR);
+    Editor editor = event.getData(CommonDataKeys.EDITOR);
     if(editor == null) {
       editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
     }
@@ -173,7 +174,6 @@
       final Document document = editor.getDocument();
       PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
       if (file != null) {
-        FileTypeManager fileTypeManager = FileTypeManager.getInstance();
         final VirtualFile virtualFile = file.getVirtualFile();
         FileType fileType = virtualFile != null ? virtualFile.getFileType() : null;
         if (StdFileTypes.JAVA == fileType || StdFileTypes.CLASS  == fileType) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java
index 9d10487..63a2ce8 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java
@@ -142,7 +142,7 @@
   }
 
   private void addLocatableRequest(FilteredRequestor requestor, EventRequest request) {
-    if(DebuggerSettings.SUSPEND_ALL.equals(requestor.SUSPEND_POLICY)) {
+    if(DebuggerSettings.SUSPEND_ALL.equals(requestor.getSuspendPolicy())) {
       request.setSuspendPolicy(EventRequest.SUSPEND_ALL);
     }
     else {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java
index 79398de..f595c1d 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java
@@ -15,13 +15,10 @@
  */
 package com.intellij.debugger.ui.breakpoints;
 
-import com.intellij.debugger.ui.breakpoints.actions.BreakpointPanelAction;
 import com.intellij.icons.AllIcons;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.util.Key;
 import org.jdom.Element;
-import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 
@@ -58,19 +55,10 @@
   }
 
   @Override
-  protected BreakpointPanelAction[] createBreakpointPanelActions(Project project, DialogWrapper parentDialog) {
-    return new BreakpointPanelAction[0];  //To change body of implemented methods use File | Settings | File Templates.
-  }
-
-  @Override
   public boolean breakpointCanBeRemoved(Breakpoint breakpoint) {
     return false;
   }
 
-  public @Nullable BreakpointPanel createBreakpointPanel(Project project, DialogWrapper parentDialog) {
-    return null;
-  }
-
   public Key<AnyExceptionBreakpoint> getBreakpointCategory() {
     return AnyExceptionBreakpoint.ANY_EXCEPTION_BREAKPOINT;
   }
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java
index 6389fdd..2077b56 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java
@@ -15,11 +15,9 @@
  */
 package com.intellij.debugger.ui.breakpoints;
 
-import com.intellij.debugger.ui.breakpoints.actions.BreakpointPanelAction;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.extensions.ExtensionPointName;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.util.Key;
 import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem;
 import org.jdom.Element;
@@ -42,14 +40,6 @@
 
   public abstract Key<? extends Breakpoint> getBreakpointCategory();
 
-  public BreakpointPanel createBreakpointPanel(final Project project, final DialogWrapper parentDialog) {
-    BreakpointPanel panel =
-      new BreakpointPanel(project, createBreakpointPropertiesPanel(project, false), createBreakpointPanelActions(project, parentDialog),
-                          getBreakpointCategory(), getDisplayName(), getHelpID());
-    configureBreakpointPanel(panel);
-    return panel;
-  }
-
   public abstract Icon getIcon();
 
   public abstract Icon getDisabledIcon();
@@ -75,8 +65,6 @@
   @Nullable
   public abstract BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact);
 
-  protected abstract BreakpointPanelAction[] createBreakpointPanelActions(Project project, DialogWrapper parentDialog);
-
   @Nullable
   public Breakpoint addBreakpoint(Project project) {
     return null;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
index dd52bcf..686965f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
@@ -25,7 +25,6 @@
 import com.intellij.debugger.DebuggerInvocationUtil;
 import com.intellij.debugger.SourcePosition;
 import com.intellij.debugger.engine.DebugProcessImpl;
-import com.intellij.debugger.engine.DebuggerUtils;
 import com.intellij.debugger.engine.evaluation.CodeFragmentKind;
 import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
 import com.intellij.debugger.engine.requests.RequestManagerImpl;
@@ -47,12 +46,12 @@
 import com.intellij.openapi.fileEditor.FileEditor;
 import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.fileEditor.TextEditor;
-import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.fileTypes.StdFileTypes;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.startup.StartupManager;
 import com.intellij.openapi.ui.MessageType;
 import com.intellij.openapi.util.*;
+import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiDocumentManager;
 import com.intellij.psi.PsiField;
 import com.intellij.psi.PsiFile;
@@ -73,6 +72,7 @@
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.breakpoints.JavaBreakpointType;
 
 import javax.swing.*;
 import java.awt.event.MouseEvent;
@@ -182,14 +182,10 @@
         }
         final Document document = editor.getDocument();
         final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
-        if (psiFile == null) {
+        if (!JavaBreakpointType.doCanPutAt(psiFile)) {
           return null;
         }
-        final FileType fileType = psiFile.getFileType();
-        boolean isInsideCompiledClass = StdFileTypes.CLASS.equals(fileType);
-        if (!isInsideCompiledClass && !(DebuggerUtils.supportsJVMDebugging(fileType) || DebuggerUtils.supportsJVMDebugging(psiFile))) {
-          return null;
-        }
+
         PsiDocumentManager.getInstance(myProject).commitDocument(document);
 
         int offset = editor.getCaretModel().getOffset();
@@ -205,6 +201,7 @@
 
         Breakpoint breakpoint = findBreakpoint(document, offset, null);
         if (breakpoint == null) {
+          boolean isInsideCompiledClass = StdFileTypes.CLASS.equals(psiFile.getFileType());
           if (mostSuitingBreakpoint || isInsideCompiledClass) {
             breakpoint = addFieldBreakpoint(document, offset);
             if (breakpoint == null) {
@@ -298,7 +295,8 @@
                 return;
               }
 
-              if (XDebuggerUtil.getInstance().canPutBreakpointAt(myProject, FileDocumentManager.getInstance().getFile(document), line)) {
+              VirtualFile file = FileDocumentManager.getInstance().getFile(document);
+              if (file != null && XDebuggerUtil.getInstance().canPutBreakpointAt(myProject, file, line)) {
                 return;
               }
               e.consume();
@@ -346,6 +344,7 @@
       @Override
       public void documentChanged(@NotNull final DocumentEvent e) {
         final Document document = e.getDocument();
+        //noinspection SynchronizeOnThis
         synchronized (BreakpointManager.this) {
           List<BreakpointWithHighlighter> breakpoints = myDocumentBreakpoints.get(document);
 
@@ -374,8 +373,7 @@
     DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() {
       @Override
       public void run() {
-        final GutterIconRenderer renderer =
-          (GutterIconRenderer)((BreakpointWithHighlighter)breakpoint).getHighlighter().getGutterIconRenderer();
+        final GutterIconRenderer renderer = ((BreakpointWithHighlighter)breakpoint).getHighlighter().getGutterIconRenderer();
         if (renderer != null) {
           DebuggerSupport.getDebuggerSupport(JavaDebuggerSupport.class).getEditBreakpointAction()
             .editBreakpoint(myProject, editor, breakpoint, renderer);
@@ -539,6 +537,7 @@
     for (final Breakpoint breakpoint : getBreakpoints()) {
       if (breakpoint instanceof BreakpointWithHighlighter && ((BreakpointWithHighlighter)breakpoint).isAt(document, offset)) {
         if (category == null || category.equals(breakpoint.getCategory())) {
+          //noinspection CastConflictsWithInstanceof,unchecked
           return (T)breakpoint;
         }
       }
@@ -662,18 +661,15 @@
   public synchronized void addBreakpoint(Breakpoint breakpoint) {
     myBreakpoints.add(breakpoint);
     myBreakpointsListForIteration = null;
-    if(breakpoint instanceof BreakpointWithHighlighter) {
+    if (breakpoint instanceof BreakpointWithHighlighter) {
       BreakpointWithHighlighter breakpointWithHighlighter = (BreakpointWithHighlighter)breakpoint;
       Document document = breakpointWithHighlighter.getDocument();
-      if(document != null) {
-        List<BreakpointWithHighlighter> breakpoints = myDocumentBreakpoints.get(document);
-
-        if(breakpoints == null) {
-          breakpoints = new ArrayList<BreakpointWithHighlighter>();
-          myDocumentBreakpoints.put(document, breakpoints);
-        }
-        breakpoints.add(breakpointWithHighlighter);
+      List<BreakpointWithHighlighter> breakpoints = myDocumentBreakpoints.get(document);
+      if (breakpoints == null) {
+        breakpoints = new ArrayList<BreakpointWithHighlighter>();
+        myDocumentBreakpoints.put(document, breakpoints);
       }
+      breakpoints.add(breakpointWithHighlighter);
     }
     myDispatcher.getMulticaster().breakpointsChanged();
   }
@@ -812,7 +808,7 @@
 
   /**
    * @return breakpoints of one of the category:
-   *         LINE_BREAKPOINTS, EXCEPTION_BREKPOINTS, FIELD_BREAKPOINTS, METHOD_BREAKPOINTS
+   *         LINE_BREAKPOINTS, EXCEPTION_BREAKPOINTS, FIELD_BREAKPOINTS, METHOD_BREAKPOINTS
    */
   public <T extends Breakpoint> Breakpoint[] getBreakpoints(@NotNull final Key<T> category) {
     ApplicationManager.getApplication().assertIsDispatchThread();
@@ -977,7 +973,6 @@
   public void removeBreakpointManagerListener(@NotNull BreakpointManagerListener listener) {
     myDispatcher.removeListener(listener);
   }
-
   
   private boolean myAllowMulticasting = true;
   private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
index 1217e16..5ed3c10 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
@@ -196,6 +196,7 @@
     public MyTextField() {
     }
 
+    @Override
     public String getToolTipText(MouseEvent event) {
       reloadClassFilters();
       updateClassFilterEditor(false);
@@ -205,6 +206,7 @@
       return getToolTipText().length() == 0 ? null : toolTipText;
     }
 
+    @Override
     public JToolTip createToolTip() {
       JToolTip toolTip = new JToolTip(){{
         setUI(new MultiLineTooltipUI());
@@ -230,6 +232,7 @@
 
     updateSuspendPolicyRbFont();
     final ItemListener suspendPolicyChangeListener = new ItemListener() {
+      @Override
       public void itemStateChanged(final ItemEvent e) {
         final BreakpointDefaults defaults = getBreakpointManager(myProject).getBreakpointDefaults(breakpointCategory);
         myMakeDefaultButton.setEnabled(!defaults.getSuspendPolicy().equals(getSelectedSuspendPolicy()) || defaults.isConditionEnabled() != myConditionCheckbox.isSelected());
@@ -251,6 +254,7 @@
     myConditionCheckbox.addItemListener(suspendPolicyChangeListener);
 
     myMakeDefaultButton.addActionListener(new ActionListener() {
+      @Override
       public void actionPerformed(final ActionEvent e) {
         final BreakpointManager breakpointManager = getBreakpointManager(myProject);
         final String suspendPolicy = getSelectedSuspendPolicy();
@@ -306,6 +310,7 @@
 
     myInstanceFiltersField = new FieldPanel(new MyTextField(), "", null,
      new ActionListener() {
+      @Override
       public void actionPerformed(ActionEvent e) {
         reloadInstanceFilters();
         EditInstanceFiltersDialog _dialog = new EditInstanceFiltersDialog(myProject);
@@ -322,6 +327,7 @@
 
     myClassFiltersField = new FieldPanel(new MyTextField(), "", null,
      new ActionListener() {
+      @Override
       public void actionPerformed(ActionEvent e) {
         reloadClassFilters();
 
@@ -365,6 +371,7 @@
 
     DebuggerUIUtil.enableEditorOnCheck(myLogExpressionCheckBox, myLogExpressionCombo);
     ActionListener updateListener = new ActionListener() {
+      @Override
       public void actionPerformed(ActionEvent e) {
         updateCheckboxes();
       }
@@ -458,6 +465,7 @@
     ClassFilter classFilter;
     if(myBreakpointPsiClass != null) {
       classFilter = new ClassFilter() {
+        @Override
         public boolean isAccepted(PsiClass aClass) {
           return myBreakpointPsiClass == aClass || aClass.isInheritor(myBreakpointPsiClass, true);
         }
@@ -641,7 +649,7 @@
     }
   }
 
-  private TextWithImportsImpl emptyText() {
+  private static TextWithImportsImpl emptyText() {
     return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "");
   }
 
@@ -653,14 +661,14 @@
     saveMasterBreakpoint();
     try {
       String text = myPassCountField.getText().trim();
-      int count = !"".equals(text)? Integer.parseInt(text) : 0;
-      breakpoint.COUNT_FILTER = count;
+      breakpoint.COUNT_FILTER = !text.isEmpty() ? Integer.parseInt(text) : 0;
       if (breakpoint.COUNT_FILTER < 0) {
         breakpoint.COUNT_FILTER = 0;
       }
     }
-    catch (Exception e) {
+    catch (Exception ignored) {
     }
+
     breakpoint.COUNT_FILTER_ENABLED = breakpoint.COUNT_FILTER > 0 && myPassCountCheckbox.isSelected();
     breakpoint.setCondition(myConditionCombo.getText());
     breakpoint.CONDITION_ENABLED = myConditionCheckbox.isSelected();
@@ -867,8 +875,10 @@
       myDialogTitle = dialogTitle;
     }
 
+    @Override
     public void actionPerformed(final ActionEvent e) {
       new DialogWrapper(myTargetEditor, true){
+        @Override
         public void show() {
           setTitle(myDialogTitle);
           setModal(true);
@@ -876,10 +886,12 @@
           super.show();
         }
 
+        @Override
         public JComponent getPreferredFocusedComponent() {
           return myEditor;
         }
 
+        @Override
         @Nullable
         protected JComponent createCenterPanel() {
           final JPanel panel = new JPanel(new BorderLayout());
@@ -890,6 +902,7 @@
           return panel;
         }
 
+        @Override
         protected void doOKAction() {
           myTargetEditor.setText(myEditor.getText());
           super.doOKAction();
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java
index f1742f0..465a968 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java
@@ -19,12 +19,10 @@
 import com.intellij.debugger.DebuggerManagerEx;
 import com.intellij.debugger.HelpID;
 import com.intellij.debugger.engine.JVMNameUtil;
-import com.intellij.debugger.ui.breakpoints.actions.*;
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.util.Key;
 import com.intellij.psi.JavaPsiFacade;
 import com.intellij.psi.PsiClass;
@@ -72,51 +70,6 @@
     return new ExceptionBreakpointPropertiesPanel(project, compact);
   }
 
-  @Override
-  protected BreakpointPanelAction[] createBreakpointPanelActions(final Project project, DialogWrapper parentDialog) {
-    return new BreakpointPanelAction[]{
-      new SwitchViewAction(),
-      new AddAction(this, project),
-      new RemoveAction(project) {
-      public void update() {
-        super.update();
-        if (getButton().isEnabled()) {
-          Breakpoint[] selectedBreakpoints = getPanel().getSelectedBreakpoints();
-          for (Breakpoint bp : selectedBreakpoints) {
-            if (bp instanceof AnyExceptionBreakpoint) {
-              getButton().setEnabled(false);
-            }
-          }
-        }
-      }
-    }, new ToggleGroupByClassesAction(), new ToggleFlattenPackagesAction(),};
-  }
-
-  public BreakpointPanel createBreakpointPanel(final Project project, final DialogWrapper parentDialog) {
-    BreakpointPanel panel =
-      new BreakpointPanel(project, createBreakpointPropertiesPanel(project, false), createBreakpointPanelActions(project, parentDialog),
-                          getBreakpointCategory(), getDisplayName(), getHelpID()) {
-        public void resetBreakpoints() {
-          super.resetBreakpoints();
-          Breakpoint[] breakpoints = getBreakpointManager().getBreakpoints(getBreakpointCategory());
-          final AnyExceptionBreakpoint anyExceptionBreakpoint =
-            DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().getAnyExceptionBreakpoint();
-          boolean found = false;
-          for (Breakpoint breakpoint : breakpoints) {
-            if (breakpoint.equals(anyExceptionBreakpoint)) {
-              found = true;
-              break;
-            }
-          }
-          if (!found) {
-            insertBreakpointAt(anyExceptionBreakpoint, 0);
-          }
-        }
-      };
-    configureBreakpointPanel(panel);
-    return panel;
-  }
-
   public Key<ExceptionBreakpoint> getBreakpointCategory() {
     return ExceptionBreakpoint.CATEGORY;
   }
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java
index 496e013..18d30f7 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java
@@ -19,11 +19,9 @@
 import com.intellij.debugger.DebuggerBundle;
 import com.intellij.debugger.DebuggerManagerEx;
 import com.intellij.debugger.HelpID;
-import com.intellij.debugger.ui.breakpoints.actions.*;
 import com.intellij.icons.AllIcons;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.Ref;
@@ -32,7 +30,6 @@
 import org.jdom.Element;
 
 import javax.swing.*;
-import java.awt.event.ActionEvent;
 
 /**
  * @author Eugene Zhuravlev
@@ -71,24 +68,6 @@
     return new FieldBreakpointPropertiesPanel(project, compact);
   }
 
-  @Override
-  protected BreakpointPanelAction[] createBreakpointPanelActions(final Project project, final DialogWrapper parentDialog) {
-    return new BreakpointPanelAction[] {
-      new SwitchViewAction(),
-      new AddAction(this, project),
-      new GotoSourceAction(project) {
-        public void actionPerformed(ActionEvent e) {
-          super.actionPerformed(e);
-          parentDialog.close(DialogWrapper.OK_EXIT_CODE);
-        }
-      },
-      new ViewSourceAction(project),
-      new RemoveAction(project),
-      new ToggleGroupByClassesAction(),
-      new ToggleFlattenPackagesAction(),
-    };
-  }
-
   public Key<FieldBreakpoint> getBreakpointCategory() {
     return FieldBreakpoint.CATEGORY;
   }
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
index 052cfd7..65cbf2d 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
@@ -18,6 +18,7 @@
 import com.intellij.debugger.DebuggerManagerEx;
 import com.intellij.debugger.SourcePosition;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.EmptyRunnable;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.ui.SimpleColoredComponent;
@@ -31,6 +32,7 @@
 class JavaBreakpointItem extends BreakpointItem {
   private final Breakpoint myBreakpoint;
   private BreakpointFactory myBreakpointFactory;
+  private BreakpointPropertiesPanel myBreakpointPropertiesPanel;
 
   public JavaBreakpointItem(@Nullable BreakpointFactory breakpointFactory, Breakpoint breakpoint) {
     myBreakpointFactory = breakpointFactory;
@@ -68,17 +70,19 @@
 
   @Override
   protected void doUpdateDetailView(DetailView panel, boolean editorOnly) {
-    BreakpointPropertiesPanel breakpointPropertiesPanel = null;
+    saveState();
+    myBreakpointPropertiesPanel = null;
+
     if (!editorOnly) {
-      breakpointPropertiesPanel = myBreakpointFactory != null ? myBreakpointFactory
+      myBreakpointPropertiesPanel = myBreakpointFactory != null ? myBreakpointFactory
         .createBreakpointPropertiesPanel(myBreakpoint.getProject(), false) : null;
 
-      if (breakpointPropertiesPanel != null) {
-        breakpointPropertiesPanel.initFrom(myBreakpoint, true);
+      if (myBreakpointPropertiesPanel != null) {
+        myBreakpointPropertiesPanel.initFrom(myBreakpoint, true);
 
-        breakpointPropertiesPanel.setSaveOnRemove(true);
+        myBreakpointPropertiesPanel.setSaveOnRemove(true);
 
-        final JPanel mainPanel = breakpointPropertiesPanel.getPanel();
+        final JPanel mainPanel = myBreakpointPropertiesPanel.getPanel();
         panel.setPropertiesPanel(mainPanel);
       }
       else {
@@ -93,8 +97,8 @@
     } else {
       panel.clearEditor();
     }
-    if (breakpointPropertiesPanel != null) {
-      breakpointPropertiesPanel.setDetailView(panel);
+    if (myBreakpointPropertiesPanel != null) {
+      myBreakpointPropertiesPanel.setDetailView(panel);
     }
   }
 
@@ -127,6 +131,11 @@
   }
 
   @Override
+  public void saveState() {
+    myBreakpointPropertiesPanel.saveTo(myBreakpoint, EmptyRunnable.INSTANCE);
+  }
+
+  @Override
   public Object getBreakpoint() {
     return myBreakpoint;
   }
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
index ae21b11..beacd19 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
@@ -24,11 +24,11 @@
 import com.intellij.debugger.DebuggerManagerEx;
 import com.intellij.debugger.SourcePosition;
 import com.intellij.debugger.actions.ThreadDumpAction;
+import com.intellij.debugger.engine.ContextUtil;
 import com.intellij.debugger.engine.DebugProcessImpl;
 import com.intellij.debugger.engine.evaluation.EvaluateException;
 import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
 import com.intellij.debugger.impl.DebuggerUtilsEx;
-import com.intellij.debugger.impl.PositionUtil;
 import com.intellij.debugger.jdi.StackFrameProxyImpl;
 import com.intellij.icons.AllIcons;
 import com.intellij.openapi.application.ApplicationManager;
@@ -82,6 +82,7 @@
     super(project, highlighter);
   }
 
+  @Override
   protected Icon getDisabledIcon(boolean isMuted) {
     final Breakpoint master = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().findMasterBreakpoint(this);
     if (isMuted) {
@@ -92,6 +93,7 @@
     }
   }
 
+  @Override
   protected Icon getSetIcon(boolean isMuted) {
     if (REMOVE_AFTER_HIT) {
       return isMuted ? AllIcons.Debugger.Db_muted_temporary_breakpoint : AllIcons.Debugger.Db_temporary_breakpoint;
@@ -99,10 +101,12 @@
     return isMuted? AllIcons.Debugger.Db_muted_breakpoint : AllIcons.Debugger.Db_set_breakpoint;
   }
 
+  @Override
   protected Icon getInvalidIcon(boolean isMuted) {
     return isMuted? AllIcons.Debugger.Db_muted_invalid_breakpoint : AllIcons.Debugger.Db_invalid_breakpoint;
   }
 
+  @Override
   protected Icon getVerifiedIcon(boolean isMuted) {
     if (REMOVE_AFTER_HIT) {
       return isMuted ? AllIcons.Debugger.Db_muted_temporary_breakpoint : AllIcons.Debugger.Db_temporary_breakpoint;
@@ -110,25 +114,30 @@
     return isMuted? AllIcons.Debugger.Db_muted_verified_breakpoint : AllIcons.Debugger.Db_verified_breakpoint;
   }
 
+  @Override
   protected Icon getVerifiedWarningsIcon(boolean isMuted) {
     return isMuted? AllIcons.Debugger.Db_muted_verified_warning_breakpoint : AllIcons.Debugger.Db_verified_warning_breakpoint;
   }
 
+  @Override
   public Key<LineBreakpoint> getCategory() {
     return CATEGORY;
   }
 
+  @Override
   protected void reload(PsiFile file) {
     super.reload(file);
     myMethodName = findMethodName(file, getHighlighter().getStartOffset());
   }
 
+  @Override
   protected void createOrWaitPrepare(DebugProcessImpl debugProcess, String classToBeLoaded) {
     if (isInScopeOf(debugProcess, classToBeLoaded)) {
       super.createOrWaitPrepare(debugProcess, classToBeLoaded);
     }
   }
 
+  @Override
   protected void createRequestForPreparedClass(final DebugProcessImpl debugProcess, final ReferenceType classType) {
     if (!isInScopeOf(debugProcess, classType.name())) {
       if (LOG.isDebugEnabled()) {
@@ -137,13 +146,13 @@
       return;
     }
     try {
-      List<Location> locs = debugProcess.getPositionManager().locationsOfLine(classType, getSourcePosition());
-      if (!locs.isEmpty()) {
-        for (Location loc : locs) {
+      List<Location> locations = debugProcess.getPositionManager().locationsOfLine(classType, getSourcePosition());
+      if (!locations.isEmpty()) {
+        for (Location loc : locations) {
           if (LOG.isDebugEnabled()) {
             LOG.debug("Found location [codeIndex=" + loc.codeIndex() +"] for reference type " + classType.name() + " at line " + getLineIndex() + "; isObsolete: " + (debugProcess.getVirtualMachineProxy().versionHigher("1.4") && loc.method().isObsolete()));
           }
-          BreakpointRequest request = debugProcess.getRequestsManager().createBreakpointRequest(LineBreakpoint.this, loc);
+          BreakpointRequest request = debugProcess.getRequestsManager().createBreakpointRequest(this, loc);
           debugProcess.getRequestsManager().enableRequest(request);
           if (LOG.isDebugEnabled()) {
             LOG.debug("Created breakpoint request for reference type " + classType.name() + " at line " + getLineIndex() + "; codeIndex=" + loc.codeIndex());
@@ -152,7 +161,7 @@
       }
       else {
         // there's no executable code in this class
-        debugProcess.getRequestsManager().setInvalid(LineBreakpoint.this, DebuggerBundle.message(
+        debugProcess.getRequestsManager().setInvalid(this, DebuggerBundle.message(
           "error.invalid.breakpoint.no.executable.code", (getLineIndex() + 1), classType.name())
         );
         if (LOG.isDebugEnabled()) {
@@ -176,7 +185,7 @@
       if (LOG.isDebugEnabled()) {
         LOG.debug("InvalidLineNumberException: " + ex.getMessage());
       }
-      debugProcess.getRequestsManager().setInvalid(LineBreakpoint.this, DebuggerBundle.message("error.invalid.breakpoint.bad.line.number"));
+      debugProcess.getRequestsManager().setInvalid(this, DebuggerBundle.message("error.invalid.breakpoint.bad.line.number"));
     }
     catch (InternalException ex) {
       LOG.info(ex);
@@ -251,6 +260,7 @@
     final int dollarIndex = className.indexOf("$");
     final String topLevelClassName = dollarIndex >= 0? className.substring(0, dollarIndex) : className;
     return ApplicationManager.getApplication().runReadAction(new Computable<Collection<VirtualFile>>() {
+      @Override
       @Nullable
       public Collection<VirtualFile> compute() {
         final PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(topLevelClassName, scope);
@@ -292,6 +302,7 @@
     });
   }
 
+  @Override
   public boolean evaluateCondition(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException {
     if(CLASS_FILTERS_ENABLED){
       String className = null;
@@ -335,6 +346,7 @@
     return getDisplayInfoInternal(false, 30);
   }
 
+  @Override
   public String getDisplayName() {
     return getDisplayInfoInternal(true, -1);
   }
@@ -399,6 +411,7 @@
     }
     if (file instanceof PsiClassOwner) {
       return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+        @Override
         public String compute() {
           final PsiMethod method = DebuggerUtilsEx.findPsiMethod(file, offset);
           return method != null? method.getName() + "()" : null;
@@ -408,9 +421,10 @@
     return null;
   }
 
+  @Override
   public String getEventMessage(LocatableEvent event) {
     final Location location = event.location();
-    String sourceName = "Unknown Source";
+    String sourceName;
     try {
       sourceName = location.sourceName();
     }
@@ -452,8 +466,9 @@
     }
   }
 
+  @Override
   public PsiElement getEvaluationElement() {
-    return PositionUtil.getContextElement(getSourcePosition());
+    return ContextUtil.getContextElement(getSourcePosition());
   }
 
   protected static LineBreakpoint create(Project project, Document document, int lineIndex) {
@@ -471,6 +486,7 @@
     return (LineBreakpoint)breakpoint.init();
   }
 
+  @Override
   public boolean canMoveTo(SourcePosition position) {
     if (!super.canMoveTo(position)) {
       return false;
@@ -493,6 +509,7 @@
 
     final boolean[] canAdd = new boolean[]{false};
     XDebuggerUtil.getInstance().iterateLine(project, document, lineIndex, new Processor<PsiElement>() {
+      @Override
       public boolean process(PsiElement element) {
         if ((element instanceof PsiWhiteSpace) || (PsiTreeUtil.getParentOfType(element, PsiComment.class, false) != null)) {
           return true;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java
index dede7de..0042074 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java
@@ -17,29 +17,29 @@
 
 import com.intellij.debugger.DebuggerBundle;
 import com.intellij.debugger.HelpID;
-import com.intellij.debugger.ui.breakpoints.actions.*;
 import com.intellij.icons.AllIcons;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.util.Key;
 import org.jdom.Element;
 
 import javax.swing.*;
-import java.awt.event.ActionEvent;
 
 /**
  * @author Eugene Zhuravlev
  *         Date: Apr 26, 2005
  */
 public class LineBreakpointFactory extends BreakpointFactory {
+  @Override
   public Breakpoint createBreakpoint(Project project, final Element element) {
     return new LineBreakpoint(project);
   }
 
+  @Override
   public Icon getIcon() {
     return AllIcons.Debugger.Db_set_breakpoint;
   }
 
+  @Override
   public Icon getDisabledIcon() {
     return AllIcons.Debugger.Db_disabled_breakpoint;
   }
@@ -60,22 +60,6 @@
   }
 
   @Override
-  protected BreakpointPanelAction[] createBreakpointPanelActions(Project project, final DialogWrapper parentDialog) {
-    return new BreakpointPanelAction[]{new SwitchViewAction(),
-      new GotoSourceAction(project) {
-        public void actionPerformed(ActionEvent e) {
-          super.actionPerformed(e);
-          parentDialog.close(DialogWrapper.OK_EXIT_CODE);
-        }
-      },
-      new ViewSourceAction(project),
-      new RemoveAction(project),
-      new ToggleGroupByMethodsAction(),
-      new ToggleGroupByClassesAction(),
-      new ToggleFlattenPackagesAction(),
-    };
-  }
-
   public Key<LineBreakpoint> getBreakpointCategory() {
     return LineBreakpoint.CATEGORY;
   }
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java
index c2ad3dc..2574e22 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java
@@ -18,29 +18,29 @@
 import com.intellij.debugger.DebuggerBundle;
 import com.intellij.debugger.DebuggerManagerEx;
 import com.intellij.debugger.HelpID;
-import com.intellij.debugger.ui.breakpoints.actions.*;
 import com.intellij.icons.AllIcons;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.util.Key;
 import org.jdom.Element;
 
 import javax.swing.*;
-import java.awt.event.ActionEvent;
 
 /**
  * @author Eugene Zhuravlev
  *         Date: Apr 26, 2005
  */
 public class MethodBreakpointFactory extends BreakpointFactory{
+  @Override
   public Breakpoint createBreakpoint(Project project, final Element element) {
     return element.getAttributeValue(WildcardMethodBreakpoint.JDOM_LABEL) != null? new WildcardMethodBreakpoint(project) : new MethodBreakpoint(project);
   }
 
+  @Override
   public Icon getIcon() {
     return AllIcons.Debugger.Db_method_breakpoint;
   }
 
+  @Override
   public Icon getDisabledIcon() {
     return AllIcons.Debugger.Db_disabled_method_breakpoint;
   }
@@ -61,29 +61,12 @@
   }
 
   @Override
-  protected BreakpointPanelAction[] createBreakpointPanelActions(Project project, final DialogWrapper parentDialog) {
-    return new BreakpointPanelAction[]{
-      new SwitchViewAction(),
-      new AddAction(this, project),
-      new GotoSourceAction(project) {
-        public void actionPerformed(ActionEvent e) {
-          super.actionPerformed(e);
-          parentDialog.close(DialogWrapper.OK_EXIT_CODE);
-        }
-      },
-      new ViewSourceAction(project),
-      new RemoveAction(project),
-      new ToggleGroupByClassesAction(),
-      new ToggleFlattenPackagesAction(),
-    };
-  }
-
-  @Override
   protected void configureBreakpointPanel(BreakpointPanel panel) {
     super.configureBreakpointPanel(panel);
     panel.getTree().setGroupByMethods(false);
   }
 
+  @Override
   public Key<MethodBreakpoint> getBreakpointCategory() {
     return MethodBreakpoint.CATEGORY;
   }
@@ -93,6 +76,7 @@
     return true;
   }
 
+  @Override
   public WildcardMethodBreakpoint addBreakpoint(Project project) {
     AddWildcardBreakpointDialog dialog = new AddWildcardBreakpointDialog(project);
     dialog.show();
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java b/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java
new file mode 100644
index 0000000..21cdb36
--- /dev/null
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java
@@ -0,0 +1,24 @@
+package org.jetbrains.java.debugger;
+
+import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.JavaCodeFragmentFactory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProviderBase;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase {
+  @NotNull
+  @Override
+  public FileType getFileType() {
+    return JavaFileType.INSTANCE;
+  }
+
+  @Override
+  protected PsiFile createExpressionCodeFragment(@NotNull Project project, @NotNull String text, @Nullable PsiElement context, boolean isPhysical) {
+    return JavaCodeFragmentFactory.getInstance(project).createExpressionCodeFragment(text, context, null, isPhysical);
+  }
+}
\ No newline at end of file
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java
new file mode 100644
index 0000000..d3e6545
--- /dev/null
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java
@@ -0,0 +1,67 @@
+package org.jetbrains.java.debugger.breakpoints;
+
+import com.intellij.debugger.DebuggerBundle;
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.facet.FacetManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.util.SystemProperties;
+import com.intellij.xdebugger.XDebuggerUtil;
+import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
+import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
+import com.intellij.xdebugger.breakpoints.XLineBreakpointTypeBase;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.JavaDebuggerEditorsProvider;
+
+import java.util.List;
+
+public class JavaBreakpointType extends XLineBreakpointTypeBase {
+  public JavaBreakpointType() {
+    super("java", DebuggerBundle.message("java.breakpoint.title"), new JavaDebuggerEditorsProvider());
+  }
+
+  @Override
+  public boolean canPutAt(@NotNull final VirtualFile file, final int line, @NotNull Project project) {
+    if (SystemProperties.getBooleanProperty("java.debugger.xBreakpoint", false)) {
+      boolean result = doCanPutAt(PsiManager.getInstance(project).findFile(file));
+
+      // todo now applicable only if modules has facets, remove this check when java xbreakpoint will work
+      if (result && SystemProperties.getBooleanProperty("java.debugger.xBreakpoint.onlyIfHasFacets", false)) {
+        Module module = ModuleUtilCore.findModuleForFile(file, project);
+        return module != null && FacetManager.getInstance(module).getAllFacets().length > 0;
+      }
+
+      return result;
+    }
+    return false;
+  }
+
+  @Override
+  public boolean isSuspendThreadSupported() {
+    return true;
+  }
+
+  @Override
+  public List<XBreakpointGroupingRule<XLineBreakpoint<XBreakpointProperties>, ?>> getGroupingRules() {
+    return XDebuggerUtil.getInstance().getGroupingByFileRuleAsList();
+  }
+
+  @Contract("null -> false")
+  public static boolean doCanPutAt(@Nullable PsiFile psiFile) {
+    if (psiFile == null) {
+      return false;
+    }
+
+    FileType fileType = psiFile.getFileType();
+    return StdFileTypes.CLASS.equals(fileType) || DebuggerUtils.supportsJVMDebugging(fileType) || DebuggerUtils.supportsJVMDebugging(psiFile);
+  }
+}
\ No newline at end of file
diff --git a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
index ae4ea88..74524ca 100644
--- a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
+++ b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
@@ -99,6 +99,7 @@
   }
 
   public static boolean isTestClass(@NotNull PsiClass psiClass, boolean checkAbstract, boolean checkForTestCaseInheritance) {
+    if (psiClass.getQualifiedName() == null) return false;
     if (!PsiClassUtil.isRunnableClass(psiClass, true, checkAbstract)) return false;
     if (checkForTestCaseInheritance && isTestCaseInheritor(psiClass)) return true;
     final PsiModifierList modifierList = psiClass.getModifierList();
diff --git a/java/execution/impl/src/com/intellij/execution/stacktrace/StackTraceLine.java b/java/execution/impl/src/com/intellij/execution/stacktrace/StackTraceLine.java
index de8cd68..1137273 100644
--- a/java/execution/impl/src/com/intellij/execution/stacktrace/StackTraceLine.java
+++ b/java/execution/impl/src/com/intellij/execution/stacktrace/StackTraceLine.java
@@ -114,10 +114,9 @@
     }
   }
 
-  private PsiClass findClass(final Project project, final String className, final int lineNumber) {
+  private static PsiClass findClass(final Project project, final String className, final int lineNumber) {
     if (project == null) return null;
     final PsiManager psiManager = PsiManager.getInstance(project);
-    if (psiManager == null) return null;
     PsiClass psiClass = JavaPsiFacade.getInstance(psiManager.getProject()).findClass(className, GlobalSearchScope.allScope(project));
     if (psiClass == null || (psiClass.getNavigationElement() instanceof PsiCompiledElement)) return null;
     psiClass = (PsiClass)psiClass.getNavigationElement();
@@ -132,8 +131,7 @@
     if (methods.length == 0) return null;
     final PsiFile psiFile = methods[0].getContainingFile();
     final int offset = offsetOfLine(psiFile, lineNumber);
-    for (int i = 0; i < methods.length; i++) {
-      final PsiMethod method = methods[i];
+    for (final PsiMethod method : methods) {
       if (method.getTextRange().contains(offset)) return method;
     }
     //if (!methods.hasNext() || location == null) return null;
@@ -152,7 +150,6 @@
   private static int offsetOfLine(final PsiFile psiFile, final int lineNumber) {
     final LineTokenizer lineTokenizer = new LineTokenizer(psiFile.getViewProvider().getContents());
     for (int i = 0; i < lineNumber; i++) lineTokenizer.advance();
-    final int offset = lineTokenizer.getOffset();
-    return offset;
+    return lineTokenizer.getOffset();
   }
 }
diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FrameworkLibraryProvider.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FrameworkLibraryProvider.java
new file mode 100644
index 0000000..fe01427
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FrameworkLibraryProvider.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.intellij.facet.impl.ui.libraries;
+
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryKind;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public abstract class FrameworkLibraryProvider {
+  @NotNull
+  public abstract String getPresentableName();
+
+  public abstract Set<LibraryKind> getAvailableLibraryKinds();
+
+  @NotNull
+  public abstract Library createLibrary(@NotNull Set<? extends LibraryKind> suitableLibraryKinds);
+}
diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryCompositionSettings.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryCompositionSettings.java
index b9dd0cb..52d5358 100644
--- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryCompositionSettings.java
+++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryCompositionSettings.java
@@ -53,6 +53,7 @@
   private LibraryDownloadSettings myDownloadSettings;
   private Map<Library, ExistingLibraryEditor> myExistingLibraryEditors =
     ContainerUtil.newIdentityTroveMap();
+  private FrameworkLibraryProvider myLibraryProvider;
 
   public LibraryCompositionSettings(final @NotNull CustomLibraryDescription libraryDescription,
                                     final @NotNull String baseDirectoryPath,
@@ -182,16 +183,16 @@
   @Nullable
   public Library addLibraries(final @NotNull ModifiableRootModel rootModel, final @NotNull List<Library> addedLibraries,
                               final @Nullable LibrariesContainer librariesContainer) {
-    Library library = createLibrary(rootModel, librariesContainer);
+    Library newLibrary = createLibrary(rootModel, librariesContainer);
 
-    if (library != null) {
-      addedLibraries.add(library);
-      DependencyScope scope = LibraryDependencyScopeSuggester.getDefaultScope(library);
+    if (newLibrary != null) {
+      addedLibraries.add(newLibrary);
+      DependencyScope scope = LibraryDependencyScopeSuggester.getDefaultScope(newLibrary);
       if (getLibraryLevel() != LibrariesContainer.LibraryLevel.MODULE) {
-        rootModel.addLibraryEntry(library).setScope(scope);
+        rootModel.addLibraryEntry(newLibrary).setScope(scope);
       }
       else {
-        LibraryOrderEntry orderEntry = rootModel.findLibraryOrderEntry(library);
+        LibraryOrderEntry orderEntry = rootModel.findLibraryOrderEntry(newLibrary);
         assert orderEntry != null;
         orderEntry.setScope(scope);
       }
@@ -200,13 +201,22 @@
       addedLibraries.add(mySelectedLibrary);
       rootModel.addLibraryEntry(mySelectedLibrary).setScope(LibraryDependencyScopeSuggester.getDefaultScope(mySelectedLibrary));
     }
-    return library;
+    if (myLibraryProvider != null) {
+      Library library = myLibraryProvider.createLibrary(myLibraryDescription.getSuitableLibraryKinds());
+      addedLibraries.add(library);
+      rootModel.addLibraryEntry(library).setScope(LibraryDependencyScopeSuggester.getDefaultScope(library));
+    }
+    return newLibrary;
   }
 
   public void setNewLibraryEditor(@Nullable NewLibraryEditor libraryEditor) {
     myNewLibraryEditor = libraryEditor;
   }
 
+  public void setLibraryProvider(FrameworkLibraryProvider libraryProvider) {
+    myLibraryProvider = libraryProvider;
+  }
+
   @Override
   public void dispose() {
   }
diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryDownloadSettings.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryDownloadSettings.java
index b358416..e9e86d6 100644
--- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryDownloadSettings.java
+++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryDownloadSettings.java
@@ -42,7 +42,7 @@
  * @author nik
  */
 public class LibraryDownloadSettings {
-  private FrameworkLibraryVersion myVersion;
+  private final FrameworkLibraryVersion myVersion;
   private final DownloadableLibraryType myLibraryType;
   private String myDirectoryForDownloadedLibrariesPath;
   private final String myLibraryName;
@@ -116,10 +116,6 @@
     return myLibraryType;
   }
 
-  public void setVersion(FrameworkLibraryVersion version) {
-    myVersion = version;
-  }
-
   public void setDirectoryForDownloadedLibrariesPath(String directoryForDownloadedLibrariesPath) {
     myDirectoryForDownloadedLibrariesPath = directoryForDownloadedLibrariesPath;
   }
diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.form b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.form
index afaac4e..d4a8a2b 100644
--- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.form
+++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.form
@@ -15,7 +15,7 @@
         <properties/>
         <border type="none"/>
         <children>
-          <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+          <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
             <margin top="0" left="0" bottom="0" right="0"/>
             <constraints>
               <card name="editing"/>
@@ -27,7 +27,7 @@
             <children>
               <component id="a5b73" class="javax.swing.JRadioButton" binding="myDownloadRadioButton">
                 <constraints>
-                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false">
+                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false">
                     <preferred-size width="207" height="22"/>
                   </grid>
                 </constraints>
@@ -38,7 +38,7 @@
               </component>
               <component id="f63e3" class="javax.swing.JRadioButton" binding="myDoNotCreateRadioButton">
                 <constraints>
-                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
                 </constraints>
                 <properties>
                   <text value="Set up library &amp;later"/>
@@ -46,7 +46,7 @@
               </component>
               <vspacer id="79970">
                 <constraints>
-                  <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+                  <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
                 </constraints>
               </vspacer>
               <grid id="71da4" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -98,7 +98,7 @@
               </grid>
               <grid id="7ea1" binding="myConfigurationPanel" layout-manager="CardLayout" hgap="0" vgap="0">
                 <constraints>
-                  <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                  <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                 </constraints>
                 <properties/>
                 <border type="none"/>
@@ -165,6 +165,14 @@
                   </grid>
                 </children>
               </grid>
+              <component id="9e8d3" class="javax.swing.JRadioButton" binding="myUseFromProviderRadioButton">
+                <constraints>
+                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <text value="Use from provider"/>
+                </properties>
+              </component>
             </children>
           </grid>
           <grid id="b8ccc" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -199,6 +207,7 @@
       <member id="4dbad"/>
       <member id="a5b73"/>
       <member id="f63e3"/>
+      <member id="9e8d3"/>
     </group>
   </buttonGroups>
 </form>
diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java
index e966873..f11e89d 100644
--- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java
+++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java
@@ -39,6 +39,7 @@
 import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor;
 import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor;
 import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
+import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
@@ -49,6 +50,7 @@
 import com.intellij.ui.components.JBLabel;
 import com.intellij.util.PathUtil;
 import com.intellij.util.PlatformIcons;
+import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.download.DownloadableFileSetVersions;
 import com.intellij.util.ui.RadioButtonEnumModel;
 import com.intellij.xml.util.XmlStringUtil;
@@ -84,17 +86,21 @@
   private JLabel myUseLibraryLabel;
   private JLabel myHiddenLabel;
   private JPanel myRootPanel;
+  private JRadioButton myUseFromProviderRadioButton;
   private ButtonGroup myButtonGroup;
 
   private LibraryCompositionSettings mySettings;
+  private final CustomLibraryDescription myLibraryDescription;
   private final LibrariesContainer myLibrariesContainer;
   private SortedComboBoxModel<LibraryEditor> myLibraryComboBoxModel;
+  private FrameworkLibraryProvider myLibraryProvider;
   private boolean myDisposed;
 
   private enum Choice {
     USE_LIBRARY,
     DOWNLOAD,
-    SETUP_LIBRARY_LATER
+    SETUP_LIBRARY_LATER,
+    USE_FROM_PROVIDER
   }
 
   private RadioButtonEnumModel<Choice> myButtonEnumModel;
@@ -104,6 +110,7 @@
                              @NotNull final FrameworkLibraryVersionFilter versionFilter,
                              @NotNull final LibrariesContainer librariesContainer,
                              final boolean showDoNotCreateOption) {
+    myLibraryDescription = libraryDescription;
     myLibrariesContainer = librariesContainer;
     final DownloadableLibraryDescription description = getDownloadableDescription(libraryDescription);
     if (description != null) {
@@ -211,10 +218,22 @@
     });
 
     boolean canDownload = mySettings.getDownloadSettings() != null;
+    boolean canUseFromProvider = myLibraryProvider != null;
     myDownloadRadioButton.setVisible(canDownload);
-    myButtonEnumModel.setSelected(libraries.isEmpty() && canDownload ? Choice.DOWNLOAD : Choice.USE_LIBRARY);
+    myUseFromProviderRadioButton.setVisible(canUseFromProvider);
+    Choice selectedOption;
+    if (canUseFromProvider) {
+      selectedOption = Choice.USE_FROM_PROVIDER;
+    }
+    else if (libraries.isEmpty() && canDownload) {
+      selectedOption = Choice.DOWNLOAD;
+    }
+    else {
+      selectedOption = Choice.USE_LIBRARY;
+    }
+    myButtonEnumModel.setSelected(selectedOption);
 
-    if (!canDownload && !showDoNotCreateOption) {
+    if (!canDownload && !canUseFromProvider && !showDoNotCreateOption) {
       myUseLibraryRadioButton.setVisible(false);
       myUseLibraryLabel.setVisible(true);
     }
@@ -272,12 +291,31 @@
         }
         break;
 
+      case USE_FROM_PROVIDER:
       case SETUP_LIBRARY_LATER:
         break;
     }
     updateState();
   }
 
+  public void setLibraryProvider(@Nullable FrameworkLibraryProvider provider) {
+    if (provider != null && !ContainerUtil.intersects(provider.getAvailableLibraryKinds(), myLibraryDescription.getSuitableLibraryKinds())) {
+      provider = null;
+    }
+
+    if (!Comparing.equal(myLibraryProvider, provider)) {
+      myLibraryProvider = provider;
+
+      if (mySettings != null) {
+        if (provider != null && !myUseFromProviderRadioButton.isVisible()) {
+          myUseFromProviderRadioButton.setSelected(true);
+        }
+        myUseFromProviderRadioButton.setVisible(provider != null);
+        updateState();
+      }
+    }
+  }
+
   public void changeBaseDirectoryPath(@NotNull String directoryForLibrariesPath) {
     if (mySettings != null) {
       mySettings.changeBaseDirectoryPath(directoryForLibrariesPath);
@@ -293,7 +331,7 @@
   }
 
   private void doCreate() {
-    final NewLibraryConfiguration libraryConfiguration = mySettings.getLibraryDescription().createNewLibrary(myPanel, getBaseDirectory());
+    final NewLibraryConfiguration libraryConfiguration = myLibraryDescription.createNewLibrary(myPanel, getBaseDirectory());
     if (libraryConfiguration != null) {
       final NewLibraryEditor libraryEditor = new NewLibraryEditor(libraryConfiguration.getLibraryType(), libraryConfiguration.getProperties());
       libraryEditor.setName(myLibrariesContainer.suggestUniqueLibraryName(libraryConfiguration.getDefaultLibraryName()));
@@ -308,12 +346,11 @@
   }
 
   private List<Library> calculateSuitableLibraries() {
-    final CustomLibraryDescription description = mySettings.getLibraryDescription();
     List<Library> suitableLibraries = new ArrayList<Library>();
     for (Library library : myLibrariesContainer.getAllLibraries()) {
-      if (description instanceof OldCustomLibraryDescription &&
-          ((OldCustomLibraryDescription)description).isSuitableLibrary(library, myLibrariesContainer)
-          || LibraryPresentationManager.getInstance().isLibraryOfKind(library, myLibrariesContainer, description.getSuitableLibraryKinds())) {
+      if (myLibraryDescription instanceof OldCustomLibraryDescription &&
+          ((OldCustomLibraryDescription)myLibraryDescription).isSuitableLibrary(library, myLibrariesContainer)
+          || LibraryPresentationManager.getInstance().isLibraryOfKind(library, myLibrariesContainer, myLibraryDescription.getSuitableLibraryKinds())) {
         suitableLibraries.add(library);
       }
     }
@@ -335,9 +372,17 @@
     myMessageLabel.setIcon(null);
     myConfigureButton.setVisible(true);
     final LibraryDownloadSettings settings = mySettings.getDownloadSettings();
-    myDownloadRadioButton.setEnabled(settings != null);
     myDownloadRadioButton.setVisible(settings != null);
-    if (!myDownloadRadioButton.isEnabled() && myDownloadRadioButton.isSelected() && myUseLibraryRadioButton.isVisible()) {
+    myUseFromProviderRadioButton.setVisible(myLibraryProvider != null);
+    if (!myUseFromProviderRadioButton.isVisible() && myUseFromProviderRadioButton.isSelected()) {
+      if (myDownloadRadioButton.isVisible()) {
+        myDownloadRadioButton.setSelected(true);
+      }
+      else {
+        myUseLibraryRadioButton.setSelected(true);
+      }
+    }
+    if (!myDownloadRadioButton.isVisible() && myDownloadRadioButton.isSelected() && myUseLibraryRadioButton.isVisible()) {
       myUseLibraryRadioButton.setSelected(true);
     }
     String message = "";
@@ -346,6 +391,12 @@
       case DOWNLOAD:
         message = getDownloadFilesMessage();
         break;
+      case USE_FROM_PROVIDER:
+        if (myLibraryProvider != null) {
+          message = "Library from " + myLibraryProvider.getPresentableName() + " will be used";
+        }
+        myConfigureButton.setVisible(false);
+        break;
       case USE_LIBRARY:
         final Object item = myExistingLibraryComboBox.getSelectedItem();
         if (item == null) {
@@ -366,6 +417,10 @@
         showConfigurePanel = false;
     }
 
+    if (myLibraryProvider != null) {
+      myUseFromProviderRadioButton.setText("Use library from " + myLibraryProvider.getPresentableName());
+    }
+
     //show the longest message on the hidden card to ensure that dialog won't jump if user selects another option
     if (mySettings.getDownloadSettings() != null) {
       myHiddenLabel.setText(getDownloadFilesMessage());
@@ -424,6 +479,8 @@
     else {
       mySettings.setNewLibraryEditor(null);
     }
+
+    mySettings.setLibraryProvider(option == Choice.USE_FROM_PROVIDER ? myLibraryProvider : null);
     return mySettings;
   }
 
diff --git a/java/idea-ui/src/com/intellij/framework/addSupport/FrameworkSupportInModuleProvider.java b/java/idea-ui/src/com/intellij/framework/addSupport/FrameworkSupportInModuleProvider.java
index 2dafb46..744922c 100644
--- a/java/idea-ui/src/com/intellij/framework/addSupport/FrameworkSupportInModuleProvider.java
+++ b/java/idea-ui/src/com/intellij/framework/addSupport/FrameworkSupportInModuleProvider.java
@@ -23,6 +23,9 @@
 import com.intellij.openapi.roots.ui.configuration.FacetsProvider;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.Collections;
+import java.util.List;
+
 /**
  * @author nik
  */
@@ -60,6 +63,10 @@
     return "Version:";
   }
 
+  public List<String> getOptionalDependenciesFrameworkIds() {
+    return Collections.emptyList();
+  }
+
   @Override
   public String toString() {
     return getPresentableName();
diff --git a/java/idea-ui/src/com/intellij/framework/library/DownloadableLibraryTypeBase.java b/java/idea-ui/src/com/intellij/framework/library/DownloadableLibraryTypeBase.java
new file mode 100644
index 0000000..5764efa
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/framework/library/DownloadableLibraryTypeBase.java
@@ -0,0 +1,34 @@
+/*
+ * 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.framework.library;
+
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.net.URL;
+
+/**
+ * @deprecated use {@link DownloadableLibraryType} instead
+ */
+public abstract class DownloadableLibraryTypeBase extends DownloadableLibraryType {
+  protected DownloadableLibraryTypeBase(@NotNull String libraryCategoryName,
+                                        @NotNull String libraryTypeId,
+                                        @NotNull String groupId,
+                                        @NotNull Icon icon,
+                                        @NotNull URL... localUrls) {
+    super(libraryCategoryName, libraryTypeId, groupId, icon, localUrls);
+  }
+}
diff --git a/java/idea-ui/src/com/intellij/framework/library/LibraryBasedFrameworkType.java b/java/idea-ui/src/com/intellij/framework/library/LibraryBasedFrameworkType.java
index 56d5c13..ca6c47b 100644
--- a/java/idea-ui/src/com/intellij/framework/library/LibraryBasedFrameworkType.java
+++ b/java/idea-ui/src/com/intellij/framework/library/LibraryBasedFrameworkType.java
@@ -48,8 +48,14 @@
   @NotNull
   @Override
   public Icon getIcon() {
+    DownloadableLibraryType libraryType = getLibraryType();
+    return libraryType.getIcon();
+  }
+
+  @NotNull
+  public DownloadableLibraryType getLibraryType() {
     DownloadableLibraryType libraryType = LibraryType.EP_NAME.findExtension(myLibraryTypeClass);
     LOG.assertTrue(libraryType != null, myLibraryTypeClass);
-    return libraryType.getIcon();
+    return libraryType;
   }
 }
diff --git a/java/idea-ui/src/com/intellij/framework/library/UnderlyingFrameworkSupportProviderBase.java b/java/idea-ui/src/com/intellij/framework/library/UnderlyingFrameworkSupportProviderBase.java
new file mode 100644
index 0000000..70748d6
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/framework/library/UnderlyingFrameworkSupportProviderBase.java
@@ -0,0 +1,30 @@
+/*
+ * 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.framework.library;
+
+import com.intellij.framework.FrameworkTypeEx;
+
+/**
+ * @author nik
+ *
+ * @deprecated use {@link #LibraryBasedFrameworkSupportProvider} instead
+ */
+public class UnderlyingFrameworkSupportProviderBase extends LibraryBasedFrameworkSupportProvider {
+  public UnderlyingFrameworkSupportProviderBase(FrameworkTypeEx frameworkType,
+                                                Class<? extends DownloadableLibraryType> libraryTypeClass) {
+    super(frameworkType, libraryTypeClass);
+  }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java b/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java
index e7ec1b0..2faa20b 100644
--- a/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java
+++ b/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java
@@ -17,6 +17,7 @@
 
 import com.intellij.ide.impl.NewProjectUtil;
 import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
 import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
 import com.intellij.ide.util.projectWizard.ProjectBuilder;
 import com.intellij.openapi.actionSystem.AnAction;
@@ -68,9 +69,9 @@
     return createFromWizard(project, wizard);
   }
 
-  public static List<Module> createFromWizard(Project project, AddModuleWizard wizard) {
+  public static List<Module> createFromWizard(Project project, AbstractProjectWizard wizard) {
     if (project == null && wizard.getStepCount() > 0) {
-      Project newProject = NewProjectUtil.createFromWizard(wizard, project);
+      Project newProject = NewProjectUtil.createFromWizard(wizard, null);
       return newProject == null ? Collections.<Module>emptyList() : Arrays.asList(ModuleManager.getInstance(newProject).getModules());
     }
 
diff --git a/java/idea-ui/src/com/intellij/ide/actions/NewProjectAction.java b/java/idea-ui/src/com/intellij/ide/actions/NewProjectAction.java
index 7deeece..048bda9 100644
--- a/java/idea-ui/src/com/intellij/ide/actions/NewProjectAction.java
+++ b/java/idea-ui/src/com/intellij/ide/actions/NewProjectAction.java
@@ -16,13 +16,19 @@
 package com.intellij.ide.actions;
 
 import com.intellij.ide.impl.NewProjectUtil;
+import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
+import com.intellij.ide.util.newProjectWizard.AddModuleWizardPro;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.util.registry.Registry;
 
 public class NewProjectAction extends AnAction implements DumbAware {
   public void actionPerformed(AnActionEvent e) {
-    NewProjectUtil.createNewProject(PlatformDataKeys.PROJECT.getData(e.getDataContext()), null);
+    NewProjectUtil.createNewProject(CommonDataKeys.PROJECT.getData(e.getDataContext()), Registry.is("new.project.wizard")
+                                   ? new AddModuleWizardPro(null, ModulesProvider.EMPTY_MODULES_PROVIDER, null)
+                                   : new AddModuleWizard(null, ModulesProvider.EMPTY_MODULES_PROVIDER, null));
   }
 }
diff --git a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java
index f5ef7af..4cf1663 100644
--- a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java
+++ b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java
@@ -20,8 +20,7 @@
 package com.intellij.ide.impl;
 
 import com.intellij.ide.GeneralSettings;
-import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
-import com.intellij.ide.util.newProjectWizard.AddModuleWizardPro;
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
 import com.intellij.ide.util.projectWizard.ProjectBuilder;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.ModalityState;
@@ -44,7 +43,6 @@
 import com.intellij.openapi.startup.StartupManager;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.util.registry.Registry;
 import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.wm.*;
 import com.intellij.openapi.wm.ex.IdeFrameEx;
@@ -62,25 +60,22 @@
   private NewProjectUtil() {
   }
 
-  public static void createNewProject(Project projectToClose, @Nullable final String defaultPath) {
+  public static void createNewProject(Project projectToClose, AbstractProjectWizard wizard) {
     final boolean proceed = ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
       public void run() {
         ProjectManager.getInstance().getDefaultProject(); //warm up components
       }
     }, ProjectBundle.message("project.new.wizard.progress.title"), true, null);
     if (!proceed) return;
-    final AddModuleWizard dialog = Registry.is("new.project.wizard")
-                                   ? new AddModuleWizardPro(null, ModulesProvider.EMPTY_MODULES_PROVIDER, defaultPath)
-                                   : new AddModuleWizard(null, ModulesProvider.EMPTY_MODULES_PROVIDER, defaultPath);
-    dialog.show();
-    if (!dialog.isOK()) {
+    wizard.show();
+    if (!wizard.isOK()) {
       return;
     }
 
-    createFromWizard(dialog, projectToClose);
+    createFromWizard(wizard, projectToClose);
   }
 
-  public static Project createFromWizard(AddModuleWizard dialog, Project projectToClose) {
+  public static Project createFromWizard(AbstractProjectWizard dialog, Project projectToClose) {
     try {
       return doCreate(dialog, projectToClose);
     }
@@ -95,7 +90,7 @@
     }
   }
 
-  private static Project doCreate(final AddModuleWizard dialog, @Nullable Project projectToClose) throws IOException {
+  private static Project doCreate(final AbstractProjectWizard dialog, @Nullable Project projectToClose) throws IOException {
     final ProjectManagerEx projectManager = ProjectManagerEx.getInstanceEx();
     final String projectFilePath = dialog.getNewProjectFilePath();
     final ProjectBuilder projectBuilder = dialog.getProjectBuilder();
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/BuilderBasedProjectType.java b/java/idea-ui/src/com/intellij/ide/projectWizard/BuilderBasedProjectType.java
new file mode 100644
index 0000000..23379f6
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/BuilderBasedProjectType.java
@@ -0,0 +1,35 @@
+package com.intellij.ide.projectWizard;
+
+import com.intellij.ide.util.projectWizard.ModuleBuilder;
+import com.intellij.openapi.module.JavaModuleType;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Dmitry Avdeev
+ *         Date: 20.09.13
+ */
+public class BuilderBasedProjectType extends ProjectCategory {
+
+  private final ModuleBuilder myBuilder;
+
+  public BuilderBasedProjectType(ModuleBuilder builder) {
+    myBuilder = builder;
+  }
+
+  @NotNull
+  @Override
+  public ModuleBuilder createModuleBuilder() {
+    return myBuilder;
+  }
+
+  /**
+   * @author Dmitry Avdeev
+   *         Date: 04.09.13
+   */
+  public static class Java extends BuilderBasedProjectType {
+
+    public Java() {
+      super(JavaModuleType.getModuleType().createModuleBuilder());
+    }
+  }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/CommonJavaProjectCategory.java b/java/idea-ui/src/com/intellij/ide/projectWizard/CommonJavaProjectCategory.java
deleted file mode 100644
index bac30cb..0000000
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/CommonJavaProjectCategory.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.ide.projectWizard;
-
-import com.intellij.ide.util.projectWizard.ModuleBuilder;
-import com.intellij.openapi.module.JavaModuleType;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author Dmitry Avdeev
- *         Date: 04.09.13
- */
-public class CommonJavaProjectCategory extends ProjectCategory {
-
-  @NotNull
-  @Override
-  public ModuleBuilder createModuleBuilder() {
-    return JavaModuleType.getModuleType().createModuleBuilder();
-  }
-
-  @Override
-  public String getId() {
-    return "Java";
-  }
-
-  @Override
-  public String getDisplayName() {
-    return "Common Java";
-  }
-
-  @Override
-  public String getDescription() {
-    return "Common Java Project";
-  }
-}
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java b/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java
index f76462b..5ecda30 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java
@@ -15,36 +15,43 @@
  */
 package com.intellij.ide.projectWizard;
 
-import com.intellij.ide.util.projectWizard.WizardContext;
-import com.intellij.ide.wizard.AbstractWizard;
-import com.intellij.ide.wizard.Step;
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
+import com.intellij.ide.util.newProjectWizard.StepSequence;
+import com.intellij.ide.util.projectWizard.ModuleWizardStep;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 /**
  * @author Dmitry Avdeev
  *         Date: 04.09.13
  */
-public class NewProjectWizard extends AbstractWizard<Step> {
+public class NewProjectWizard extends AbstractProjectWizard {
 
-  private final WizardContext myContext;
+  private final StepSequence mySequence;
 
-  public NewProjectWizard(String title, @Nullable Project project) {
-    super(title, project);
-    myContext = new WizardContext(project);
-    addStep(new ProjectTypeStep(project, getDisposable()));
+  public NewProjectWizard(@Nullable Project project, @NotNull ModulesProvider modulesProvider, @Nullable String defaultPath) {
+    super("New Project", project, defaultPath);
+//    addStep();
+//    addStep(new ProjectSummaryStep(myWizardContext));
+    mySequence = new StepSequence();
+    mySequence.addCommonStep(new ProjectTypeStep(myWizardContext, this, modulesProvider));
+    mySequence.addCommonFinishingStep(new ProjectSettingsStep(myWizardContext), null);
+    for (ModuleWizardStep step : mySequence.getAllSteps()) {
+      addStep(step);
+    }
     init();
   }
 
   @Nullable
   @Override
-  protected String getHelpID() {
-    return null;
-  }
-
-  @Nullable
-  @Override
   protected String getDimensionServiceKey() {
     return "new project wizard";
   }
+
+  @Override
+  public StepSequence getSequence() {
+    return mySequence;
+  }
 }
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizardAction.java b/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizardAction.java
index 676c8b1..29226b6 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizardAction.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizardAction.java
@@ -15,8 +15,10 @@
  */
 package com.intellij.ide.projectWizard;
 
+import com.intellij.ide.impl.NewProjectUtil;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
 
 /**
  * @author Dmitry Avdeev
@@ -25,6 +27,7 @@
 public class NewProjectWizardAction extends AnAction {
   @Override
   public void actionPerformed(AnActionEvent e) {
-    new NewProjectWizard("New Project", getEventProject(e)).show();
+    NewProjectWizard wizard = new NewProjectWizard(null, ModulesProvider.EMPTY_MODULES_PROVIDER, null);
+    NewProjectUtil.createNewProject(getEventProject(e), wizard);
   }
 }
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectCategory.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectCategory.java
index 0553895..2d7f32b 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectCategory.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectCategory.java
@@ -24,6 +24,7 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import javax.swing.*;
 import java.util.Arrays;
 import java.util.Map;
 
@@ -46,10 +47,18 @@
     return createModuleBuilder().getPresentableName();
   }
 
+  public Icon getIcon() {
+    return createModuleBuilder().getNodeIcon();
+  }
+
   public String getDescription() {
     return createModuleBuilder().getDescription();
   }
 
+  public String getGroupName() {
+    return createModuleBuilder().getGroupName();
+  }
+
   @Nullable
   public String getParentId() {
     return null;
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSettingsStep.form b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSettingsStep.form
new file mode 100644
index 0000000..625a1ea
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSettingsStep.form
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.projectWizard.ProjectSettingsStep">
+  <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="20" y="20" width="608" height="215"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <grid id="e5cc3" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <grid id="5d4a2" binding="myExpertPlaceholder" layout-manager="BorderLayout" hgap="0" vgap="0">
+            <constraints>
+              <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+            <border type="none"/>
+            <children>
+              <grid id="a59bf" binding="myExpertPanel" layout-manager="GridBagLayout">
+                <constraints border-constraint="Center"/>
+                <properties/>
+                <border type="none"/>
+                <children/>
+              </grid>
+            </children>
+          </grid>
+          <grid id="fb50c" binding="myModulePanel" layout-manager="GridBagLayout">
+            <constraints>
+              <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+            <border type="none"/>
+            <children>
+              <component id="40abf" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <gridbag weightx="0.0" weighty="1.0"/>
+                </constraints>
+                <properties>
+                  <labelFor value="edb8a"/>
+                  <text resource-bundle="messages/ProjectBundle" key="project.new.wizard.module.name.title"/>
+                </properties>
+              </component>
+              <component id="edb8a" class="javax.swing.JTextField" binding="myModuleName">
+                <constraints>
+                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                    <preferred-size width="150" height="-1"/>
+                  </grid>
+                  <gridbag top="0" left="0" bottom="5" right="0" weightx="1.0" weighty="1.0"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="7afef" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <gridbag weightx="0.0" weighty="1.0"/>
+                </constraints>
+                <properties>
+                  <labelFor value="d2d6b"/>
+                  <text resource-bundle="messages/ProjectBundle" key="project.new.wizard.module.root.title"/>
+                </properties>
+              </component>
+              <component id="d2d6b" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myModuleContentRoot">
+                <constraints>
+                  <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                  <gridbag top="0" left="0" bottom="5" right="0" weightx="1.0" weighty="1.0"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="2ac4e" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <gridbag weightx="0.0" weighty="1.0"/>
+                </constraints>
+                <properties>
+                  <labelFor value="9e1b8"/>
+                  <text resource-bundle="messages/ProjectBundle" key="project.new.wizard.module.file.title"/>
+                </properties>
+              </component>
+              <component id="9e1b8" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myModuleFileLocation">
+                <constraints>
+                  <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                  <gridbag top="0" left="0" bottom="5" right="0" weightx="1.0" weighty="1.0"/>
+                </constraints>
+                <properties/>
+              </component>
+            </children>
+          </grid>
+          <grid id="caf4" binding="mySettingsPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+            <border type="empty">
+              <size top="0" left="0" bottom="10" right="0"/>
+            </border>
+            <children/>
+          </grid>
+          <vspacer id="44e0b">
+            <constraints>
+              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+            </constraints>
+          </vspacer>
+        </children>
+      </grid>
+    </children>
+  </grid>
+</form>
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSettingsStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSettingsStep.java
new file mode 100644
index 0000000..3db63ca
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSettingsStep.java
@@ -0,0 +1,463 @@
+/*
+ * 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.ide.projectWizard;
+
+import com.intellij.ide.IdeBundle;
+import com.intellij.ide.highlighter.ModuleFileType;
+import com.intellij.ide.util.BrowseFilesListener;
+import com.intellij.ide.util.newProjectWizard.SelectTemplateSettings;
+import com.intellij.ide.util.projectWizard.*;
+import com.intellij.openapi.components.StorageScheme;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectBundle;
+import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.platform.templates.TemplateModuleBuilder;
+import com.intellij.projectImport.ProjectFormatPanel;
+import com.intellij.ui.DocumentAdapter;
+import com.intellij.ui.HideableDecorator;
+import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.components.JBLabel;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import java.awt.*;
+import java.io.File;
+
+/**
+ * @author Dmitry Avdeev
+ *         Date: 9/26/12
+ */
+public class ProjectSettingsStep extends ModuleWizardStep implements SettingsStep {
+
+  private JPanel mySettingsPanel;
+
+  private JPanel myExpertPlaceholder;
+  private JPanel myExpertPanel;
+  private final HideableDecorator myExpertDecorator;
+
+  private final NamePathComponent myNamePathComponent;
+  private final ProjectFormatPanel myFormatPanel;
+
+  private JTextField myModuleName;
+  private TextFieldWithBrowseButton myModuleContentRoot;
+  private TextFieldWithBrowseButton myModuleFileLocation;
+  private JPanel myModulePanel;
+
+  private JPanel myPanel;
+
+  private boolean myModuleNameChangedByUser = false;
+  private boolean myModuleNameDocListenerEnabled = true;
+
+  private boolean myContentRootChangedByUser = false;
+  private boolean myContentRootDocListenerEnabled = true;
+
+  private boolean myImlLocationChangedByUser = false;
+  private boolean myImlLocationDocListenerEnabled = true;
+
+  private final WizardContext myWizardContext;
+  @Nullable
+  private ModuleWizardStep mySettingsStep;
+
+  public ProjectSettingsStep(WizardContext context) {
+
+    myWizardContext = context;
+
+    myFormatPanel = new ProjectFormatPanel();
+    myNamePathComponent = NamePathComponent.initNamePathComponent(context);
+    if (context.isCreatingNewProject()) {
+      mySettingsPanel.add(myNamePathComponent, BorderLayout.NORTH);
+      addExpertPanel(myModulePanel);
+    }
+    else {
+      mySettingsPanel.add(myModulePanel, BorderLayout.NORTH);
+    }
+    bindModuleSettings();
+
+    myExpertDecorator = new HideableDecorator(myExpertPlaceholder, "Mor&e Settings", false);
+    myExpertPanel.setBorder(IdeBorderFactory.createEmptyBorder(0, IdeBorderFactory.TITLED_BORDER_INDENT, 5, 0));
+    myExpertDecorator.setContentComponent(myExpertPanel);
+
+    if (myWizardContext.isCreatingNewProject()) {
+      addProjectFormat(myModulePanel);
+    }
+  }
+
+  private JTextField getNameComponent() {
+    return myWizardContext.isCreatingNewProject() ? myNamePathComponent.getNameComponent() : myModuleName;
+  }
+
+  private void addProjectFormat(JPanel panel) {
+    addField("Project \u001bformat:", myFormatPanel.getStorageFormatComboBox(), panel);
+  }
+
+  @Override
+  public String getHelpId() {
+    return myWizardContext.isCreatingNewProject() ? "New_Project_Main_Settings" : "Add_Module_Main_Settings";
+  }
+
+  private void setupPanels() {
+
+    ModuleBuilder moduleBuilder = (ModuleBuilder)myWizardContext.getProjectBuilder();
+    restorePanel(myNamePathComponent, 4);
+    restorePanel(myModulePanel, myWizardContext.isCreatingNewProject() ? 8 : 6);
+    restorePanel(myExpertPanel, myWizardContext.isCreatingNewProject() ? 1 : 0);
+    mySettingsStep = moduleBuilder == null ? null : moduleBuilder.modifySettingsStep(this);
+
+    myExpertPlaceholder.setVisible(!(moduleBuilder instanceof TemplateModuleBuilder) && myExpertPanel.getComponentCount() > 0);
+    for (int i = 0; i < 6; i++) {
+      myModulePanel.getComponent(i).setVisible(!(moduleBuilder instanceof EmptyModuleBuilder));
+    }
+    mySettingsPanel.revalidate();
+    mySettingsPanel.repaint();
+  }
+
+  private static int restorePanel(JPanel component, int i) {
+    int removed = 0;
+    while (component.getComponentCount() > i) {
+      component.remove(component.getComponentCount() - 1);
+      removed++;
+    }
+    return removed;
+  }
+
+  @Override
+  public void updateStep() {
+    myExpertDecorator.setOn(SelectTemplateSettings.getInstance().EXPERT_MODE);
+    setupPanels();
+  }
+
+  @Override
+  public void onStepLeaving() {
+    SelectTemplateSettings settings = SelectTemplateSettings.getInstance();
+    settings.EXPERT_MODE = myExpertDecorator.isExpanded();
+  }
+
+  @Override
+  public boolean validate() throws ConfigurationException {
+
+    if (myWizardContext.isCreatingNewProject()) {
+      if (!myNamePathComponent.validateNameAndPath(myWizardContext, myFormatPanel.isDefault())) return false;
+    }
+
+    if (!validateModulePaths()) return false;
+    if (!myWizardContext.isCreatingNewProject()) {
+      validateExistingModuleName();
+    }
+
+    if (mySettingsStep != null) {
+      return mySettingsStep.validate();
+    }
+    return true;
+  }
+
+  @Override
+  public JComponent getComponent() {
+    return myPanel;
+  }
+
+  @Override
+  public JComponent getPreferredFocusedComponent() {
+    return getNameComponent();
+  }
+
+  @Override
+  public void updateDataModel() {
+
+    myWizardContext.setProjectName(myNamePathComponent.getNameValue());
+    myWizardContext.setProjectFileDirectory(myNamePathComponent.getPath());
+    myFormatPanel.updateData(myWizardContext);
+
+    ModuleBuilder moduleBuilder = (ModuleBuilder)myWizardContext.getProjectBuilder();
+    if (moduleBuilder != null) {
+      final String moduleName = getModuleName();
+      moduleBuilder.setName(moduleName);
+      moduleBuilder.setModuleFilePath(
+        FileUtil.toSystemIndependentName(myModuleFileLocation.getText()) + "/" + moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION);
+      moduleBuilder.setContentEntryPath(FileUtil.toSystemIndependentName(getModuleContentRoot()));
+      if (moduleBuilder instanceof TemplateModuleBuilder) {
+        myWizardContext.setProjectStorageFormat(StorageScheme.DIRECTORY_BASED);
+      }
+    }
+
+    if (mySettingsStep != null) {
+      mySettingsStep.updateDataModel();
+    }
+  }
+
+  @Override
+  public String getName() {
+    return "Project Settings";
+  }
+
+  @Override
+  public WizardContext getContext() {
+    return myWizardContext;
+  }
+
+  @Override
+  public void addSettingsField(@NotNull String label, @NotNull JComponent field) {
+    JPanel panel = myWizardContext.isCreatingNewProject() ? myNamePathComponent : myModulePanel;
+    addField(label, field, panel);
+  }
+
+  private static void addField(String label, JComponent field, JPanel panel) {
+    JLabel jLabel = new JBLabel(label);
+    jLabel.setLabelFor(field);
+    panel.add(jLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.WEST,
+                                                 GridBagConstraints.NONE, new Insets(0, 0, 5, 0), 0, 0));
+    panel.add(field, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0, GridBagConstraints.NORTHWEST,
+                                                GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0));
+  }
+
+  @Override
+  public void addSettingsComponent(@NotNull JComponent component) {
+    JPanel panel = myWizardContext.isCreatingNewProject() ? myNamePathComponent : myModulePanel;
+    panel.add(component, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0, GridBagConstraints.NORTHWEST,
+                                                   GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+  }
+
+  @Override
+  public void addExpertPanel(@NotNull JComponent panel) {
+    myExpertPanel.add(panel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0, GridBagConstraints.NORTHWEST,
+                                                    GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+  }
+
+  @Override
+  public void addExpertField(@NotNull String label, @NotNull JComponent field) {
+    JPanel panel = myWizardContext.isCreatingNewProject() ? myModulePanel : myExpertPanel;
+    addField(label, field, panel);
+  }
+
+  public void bindModuleSettings() {
+
+    myNamePathComponent.getNameComponent().getDocument().addDocumentListener(new DocumentAdapter() {
+      protected void textChanged(final DocumentEvent e) {
+        if (!myModuleNameChangedByUser) {
+          setModuleName(myNamePathComponent.getNameValue());
+        }
+      }
+    });
+
+    myModuleContentRoot.addBrowseFolderListener(ProjectBundle.message("project.new.wizard.module.content.root.chooser.title"), ProjectBundle.message("project.new.wizard.module.content.root.chooser.description"),
+                                                myWizardContext.getProject(), BrowseFilesListener.SINGLE_DIRECTORY_DESCRIPTOR);
+
+    myNamePathComponent.getPathComponent().getDocument().addDocumentListener(new DocumentAdapter() {
+      protected void textChanged(final DocumentEvent e) {
+        if (!myContentRootChangedByUser) {
+          setModuleContentRoot(myNamePathComponent.getPath());
+        }
+      }
+    });
+    myModuleName.getDocument().addDocumentListener(new DocumentAdapter() {
+      protected void textChanged(final DocumentEvent e) {
+        if (myModuleNameDocListenerEnabled) {
+          myModuleNameChangedByUser = true;
+        }
+        String path = getDefaultBaseDir(myWizardContext);
+        final String moduleName = getModuleName();
+        if (path.length() > 0 && !Comparing.strEqual(moduleName, myNamePathComponent.getNameValue())) {
+          path += "/" + moduleName;
+        }
+        if (!myContentRootChangedByUser) {
+          final boolean f = myModuleNameChangedByUser;
+          myModuleNameChangedByUser = true;
+          setModuleContentRoot(path);
+          myModuleNameChangedByUser = f;
+        }
+        if (!myImlLocationChangedByUser) {
+          setImlFileLocation(path);
+        }
+      }
+    });
+    myModuleContentRoot.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
+      protected void textChanged(final DocumentEvent e) {
+        if (myContentRootDocListenerEnabled) {
+          myContentRootChangedByUser = true;
+        }
+        if (!myImlLocationChangedByUser) {
+          setImlFileLocation(getModuleContentRoot());
+        }
+        if (!myModuleNameChangedByUser) {
+          final String path = FileUtil.toSystemIndependentName(getModuleContentRoot());
+          final int idx = path.lastIndexOf("/");
+
+          boolean f = myContentRootChangedByUser;
+          myContentRootChangedByUser = true;
+
+          boolean i = myImlLocationChangedByUser;
+          myImlLocationChangedByUser = true;
+
+          setModuleName(idx >= 0 ? path.substring(idx + 1) : "");
+
+          myContentRootChangedByUser = f;
+          myImlLocationChangedByUser = i;
+        }
+      }
+    });
+
+    myModuleFileLocation.addBrowseFolderListener(ProjectBundle.message("project.new.wizard.module.file.chooser.title"), ProjectBundle.message("project.new.wizard.module.file.description"),
+                                                 myWizardContext.getProject(), BrowseFilesListener.SINGLE_DIRECTORY_DESCRIPTOR);
+    myModuleFileLocation.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
+      protected void textChanged(final DocumentEvent e) {
+        if (myImlLocationDocListenerEnabled) {
+          myImlLocationChangedByUser = true;
+        }
+      }
+    });
+    myNamePathComponent.getPathComponent().getDocument().addDocumentListener(new DocumentAdapter() {
+      protected void textChanged(final DocumentEvent e) {
+        if (!myImlLocationChangedByUser) {
+          setImlFileLocation(myNamePathComponent.getPath());
+        }
+      }
+    });
+    if (myWizardContext.isCreatingNewProject()) {
+      setModuleName(myNamePathComponent.getNameValue());
+      setModuleContentRoot(myNamePathComponent.getPath());
+      setImlFileLocation(myNamePathComponent.getPath());
+    } else {
+      final Project project = myWizardContext.getProject();
+      assert project != null;
+      VirtualFile baseDir = project.getBaseDir();
+      if (baseDir != null) { //e.g. was deleted
+        final String baseDirPath = baseDir.getPath();
+        String moduleName = ProjectWizardUtil.findNonExistingFileName(baseDirPath, "untitled", "");
+        String contentRoot = baseDirPath + "/" + moduleName;
+        if (!Comparing.strEqual(project.getName(), myWizardContext.getProjectName()) && !myWizardContext.isCreatingNewProject() && myWizardContext.getProjectName() != null) {
+          moduleName = ProjectWizardUtil.findNonExistingFileName(myWizardContext.getProjectFileDirectory(), myWizardContext.getProjectName(), "");
+          contentRoot = myWizardContext.getProjectFileDirectory();
+        }
+        setModuleName(moduleName);
+        setModuleContentRoot(contentRoot);
+        setImlFileLocation(contentRoot);
+        myModuleName.select(0, moduleName.length());
+      }
+    }
+  }
+
+  private void validateExistingModuleName() throws ConfigurationException {
+    final String moduleName = getModuleName();
+    final Module module;
+    final ProjectStructureConfigurable fromConfigurable = ProjectStructureConfigurable.getInstance(myWizardContext.getProject());
+    if (fromConfigurable != null) {
+      module = fromConfigurable.getModulesConfig().getModule(moduleName);
+    }
+    else {
+      module = ModuleManager.getInstance(myWizardContext.getProject()).findModuleByName(moduleName);
+    }
+    if (module != null) {
+      throw new ConfigurationException("Module \'" + moduleName + "\' already exist in project. Please, specify another name.");
+    }
+  }
+
+  private boolean validateModulePaths() throws ConfigurationException {
+    final String moduleName = getModuleName();
+    final String moduleFileDirectory = myModuleFileLocation.getText();
+    if (moduleFileDirectory.length() == 0) {
+      throw new ConfigurationException("Enter module file location");
+    }
+    if (moduleName.length() == 0) {
+      throw new ConfigurationException("Enter a module name");
+    }
+
+    if (!ProjectWizardUtil.createDirectoryIfNotExists(IdeBundle.message("directory.module.file"), moduleFileDirectory,
+                                                      myImlLocationChangedByUser)) {
+      return false;
+    }
+    if (!ProjectWizardUtil.createDirectoryIfNotExists(IdeBundle.message("directory.module.content.root"), myModuleContentRoot.getText(),
+                                                      myContentRootChangedByUser)) {
+      return false;
+    }
+
+    File moduleFile = new File(moduleFileDirectory, moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION);
+    if (moduleFile.exists()) {
+      int answer = Messages.showYesNoDialog(IdeBundle.message("prompt.overwrite.project.file", moduleFile.getAbsolutePath(),
+                                                              IdeBundle.message("project.new.wizard.module.identification")),
+                                            IdeBundle.message("title.file.already.exists"), Messages.getQuestionIcon());
+      if (answer != 0) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  protected String getModuleContentRoot() {
+    return myModuleContentRoot.getText();
+  }
+
+  private String getDefaultBaseDir(WizardContext wizardContext) {
+    if (wizardContext.isCreatingNewProject()) {
+      return myNamePathComponent.getPath();
+    } else {
+      final Project project = wizardContext.getProject();
+      assert project != null;
+      final VirtualFile baseDir = project.getBaseDir();
+      if (baseDir != null) {
+        return baseDir.getPath();
+      }
+      return "";
+    }
+  }
+
+  private void setImlFileLocation(final String path) {
+    myImlLocationDocListenerEnabled = false;
+    myModuleFileLocation.setText(FileUtil.toSystemDependentName(path));
+    myImlLocationDocListenerEnabled = true;
+  }
+
+  private void setModuleContentRoot(final String path) {
+    myContentRootDocListenerEnabled = false;
+    myModuleContentRoot.setText(FileUtil.toSystemDependentName(path));
+    myContentRootDocListenerEnabled = true;
+  }
+
+  public void setModuleName(String moduleName) {
+    myModuleNameDocListenerEnabled = false;
+    myModuleName.setText(moduleName);
+    myModuleNameDocListenerEnabled = true;
+  }
+
+  @NotNull
+  public JTextField getModuleNameField() {
+    return myModuleName;
+  }
+
+  protected String getModuleName() {
+    return myModuleName.getText().trim();
+  }
+
+  @TestOnly
+  @Nullable
+  public ModuleWizardStep getSettingsStep() {
+    return mySettingsStep;
+  }
+
+  @Override
+  public Icon getIcon() {
+    return null;
+  }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSummaryStep.form b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSummaryStep.form
new file mode 100644
index 0000000..a0f1f25
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSummaryStep.form
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.projectWizard.ProjectSummaryStep">
+  <grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="20" y="20" width="500" height="400"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <grid id="15993" binding="myNameAndLocationPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children/>
+      </grid>
+      <vspacer id="c6894">
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+    </children>
+  </grid>
+</form>
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSummaryStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSummaryStep.java
new file mode 100644
index 0000000..28e9cec
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSummaryStep.java
@@ -0,0 +1,58 @@
+/*
+ * 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.ide.projectWizard;
+
+import com.intellij.ide.util.projectWizard.NamePathComponent;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.ide.wizard.CommitStepException;
+import com.intellij.ide.wizard.StepAdapter;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author Dmitry Avdeev
+ *         Date: 20.09.13
+ */
+public class ProjectSummaryStep extends StepAdapter {
+
+  private final WizardContext myWizardContext;
+  private JPanel myRootPanel;
+  private JPanel myNameAndLocationPanel;
+  private final NamePathComponent myNamePathComponent;
+
+  public ProjectSummaryStep(WizardContext context) {
+    myWizardContext = context;
+    myNamePathComponent = NamePathComponent.initNamePathComponent(myWizardContext);
+    myNameAndLocationPanel.add(myNamePathComponent, BorderLayout.CENTER);
+  }
+
+  @Override
+  public void _commit(boolean finishChosen) throws CommitStepException {
+    myWizardContext.setProjectName(myNamePathComponent.getNameValue());
+    myWizardContext.setProjectFileDirectory(myNamePathComponent.getPath());
+  }
+
+  @Override
+  public JComponent getComponent() {
+    return myRootPanel;
+  }
+
+  @Override
+  public JComponent getPreferredFocusedComponent() {
+    return myNamePathComponent.getNameComponent();
+  }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form
index 85e5a75..513c11a 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form
@@ -39,7 +39,7 @@
           </scrollpane>
         </children>
       </grid>
-      <grid id="ad16" binding="myOptionsPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
+      <grid id="ad16" binding="myOptionsPanel" layout-manager="CardLayout" hgap="0" vgap="0">
         <constraints>
           <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
         </constraints>
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
index 07a1e2c..fc9b0f9 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
@@ -18,72 +18,171 @@
 import com.intellij.framework.FrameworkGroup;
 import com.intellij.framework.FrameworkTypeEx;
 import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
-import com.intellij.ide.util.frameworkSupport.FrameworkSupportModelImpl;
 import com.intellij.ide.util.frameworkSupport.FrameworkSupportUtil;
 import com.intellij.ide.util.newProjectWizard.AddSupportForFrameworksPanel;
 import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase;
-import com.intellij.ide.wizard.StepAdapter;
-import com.intellij.openapi.Disposable;
+import com.intellij.ide.util.projectWizard.ModuleBuilder;
+import com.intellij.ide.util.projectWizard.ModuleWizardStep;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
 import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
 import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory;
 import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.CheckedTreeNode;
 import com.intellij.ui.CollectionListModel;
+import com.intellij.ui.ColoredListCellRenderer;
 import com.intellij.ui.components.JBList;
 import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.FactoryMap;
+import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
 import java.awt.*;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
+import java.util.*;
 import java.util.List;
 
 /**
  * @author Dmitry Avdeev
  *         Date: 04.09.13
  */
-public class ProjectTypeStep extends StepAdapter {
+public class ProjectTypeStep extends ModuleWizardStep {
 
+  private static final String FRAMEWORKS_CARD = "frameworks card";
+  private final WizardContext myContext;
+  private final NewProjectWizard myWizard;
+  private final ModulesProvider myModulesProvider;
   private JPanel myPanel;
   private JBList myProjectTypeList;
   private JPanel myOptionsPanel;
 
+  @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
+  private final FactoryMap<ProjectCategory, ModuleBuilder> myBuilders = new FactoryMap<ProjectCategory, ModuleBuilder>() {
+    @Nullable
+    @Override
+    protected ModuleBuilder create(ProjectCategory key) {
+      return key.createModuleBuilder();
+    }
+  };
+  private final Set<String> myCards = new HashSet<String>();
+
   private final AddSupportForFrameworksPanel myFrameworksPanel;
-  private final FrameworkSupportModelBase myModel;
+  private final ModuleBuilder.ModuleConfigurationUpdater myConfigurationUpdater;
 
-  public ProjectTypeStep(Project project, Disposable disposable) {
-
+  public ProjectTypeStep(WizardContext context, NewProjectWizard wizard, ModulesProvider modulesProvider) {
+    myContext = context;
+    myWizard = wizard;
+    myModulesProvider = modulesProvider;
+    Project project = context.getProject();
     final LibrariesContainer container = LibrariesContainerFactory.createContainer(project);
-    myModel = new FrameworkSupportModelImpl(project, "", container);
-    ProjectCategory[] projectCategories = ProjectCategory.EXTENSION_POINT_NAME.getExtensions();
-    myProjectTypeList.setModel(new CollectionListModel<ProjectCategory>(Arrays.asList(projectCategories)));
-    myProjectTypeList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+    FrameworkSupportModelBase model = new FrameworkSupportModelBase(project, null, container) {
+      @NotNull
       @Override
-      public void valueChanged(ListSelectionEvent e) {
-        updateFrameworks((ProjectCategory)myProjectTypeList.getSelectedValue());
+      public String getBaseDirectoryForLibrariesPath() {
+        return StringUtil.notNullize(getSelectedBuilder().getContentEntryPath());
+      }
+    };
+    myConfigurationUpdater = new ModuleBuilder.ModuleConfigurationUpdater() {
+      @Override
+      public void update(@NotNull Module module, @NotNull ModifiableRootModel rootModel) {
+        myFrameworksPanel.addSupport(module, rootModel);
+      }
+    };
+
+    myProjectTypeList.setCellRenderer(new ColoredListCellRenderer() {
+      @Override
+      protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
+        ProjectCategory category = (ProjectCategory)value;
+        append(category.getDisplayName());
+        setIcon(category.getIcon());
       }
     });
 
-    myFrameworksPanel = new AddSupportForFrameworksPanel(Collections.<FrameworkSupportInModuleProvider>emptyList(), myModel, true);
-    Disposer.register(disposable, myFrameworksPanel);
+    List<ProjectCategory> categories = new ArrayList<ProjectCategory>();
+    categories.addAll(ContainerUtil.map(ModuleBuilder.getAllBuilders(), new Function<ModuleBuilder, ProjectCategory>() {
+      @Override
+      public ProjectCategory fun(ModuleBuilder builder) {
+        return new BuilderBasedProjectType(builder);
+      }
+    }));
+    categories.addAll(Arrays.asList(ProjectCategory.EXTENSION_POINT_NAME.getExtensions()));
 
-    myOptionsPanel.add(myFrameworksPanel.getMainPanel(), BorderLayout.CENTER);
+    final MultiMap<String, ProjectCategory> map = new MultiMap<String, ProjectCategory>();
+    for (ProjectCategory category : categories) {
+      map.putValue(category.getGroupName(), category);
+    }
+    Collections.sort(categories, new Comparator<ProjectCategory>() {
+      @Override
+      public int compare(ProjectCategory o1, ProjectCategory o2) {
+        return map.get(o2.getGroupName()).size() - map.get(o1.getGroupName()).size();
+      }
+    });
+
+    myProjectTypeList.setModel(new CollectionListModel<ProjectCategory>(categories));
+    myProjectTypeList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+      @Override
+      public void valueChanged(ListSelectionEvent e) {
+        ModuleBuilder builder = getSelectedBuilder();
+        myContext.setProjectBuilder(builder);
+        myWizard.getSequence().setType(builder.getBuilderId());
+        builder.addModuleConfigurationUpdater(myConfigurationUpdater);
+        updateOptionsPanel((ProjectCategory)myProjectTypeList.getSelectedValue());
+      }
+    });
+
+    for (ProjectCategory category : categories) {
+      myWizard.getSequence().addStepsForBuilder(myBuilders.get(category), context, modulesProvider, true);
+    }
+
+    myFrameworksPanel = new AddSupportForFrameworksPanel(Collections.<FrameworkSupportInModuleProvider>emptyList(), model, true);
+    Disposer.register(wizard.getDisposable(), myFrameworksPanel);
+
+    myOptionsPanel.add(myFrameworksPanel.getMainPanel(), FRAMEWORKS_CARD);
     myProjectTypeList.setSelectedIndex(0);
   }
 
-  private void updateFrameworks(ProjectCategory projectCategory) {
-    List<FrameworkSupportInModuleProvider> providers = new ArrayList<FrameworkSupportInModuleProvider>();
-    if (projectCategory != null) {
+  private ModuleBuilder getSelectedBuilder() {
+    ProjectCategory projectCategory = (ProjectCategory)myProjectTypeList.getSelectedValue();
+    return myBuilders.get(projectCategory);
+  }
+
+  private void updateOptionsPanel(ProjectCategory projectCategory) {
+    if (projectCategory == null) return;
+    ModuleBuilder builder = myBuilders.get(projectCategory);
+    JComponent panel = builder.getCustomOptionsPanel(this);
+    String card;
+    if (panel != null) {
+      card = builder.getBuilderId();
+      if (myCards.add(card)) {
+         myOptionsPanel.add(panel, card);
+      }
+    }
+    else {
+      card = FRAMEWORKS_CARD;
+      List<FrameworkSupportInModuleProvider> providers = new ArrayList<FrameworkSupportInModuleProvider>();
       for (FrameworkSupportInModuleProvider framework : FrameworkSupportUtil.getAllProviders()) {
         if (matchFramework(projectCategory, framework)) {
           providers.add(framework);
         }
       }
+      myFrameworksPanel.setProviders(providers);
+      for (FrameworkSupportInModuleProvider provider : providers) {
+        if (ArrayUtil.contains(provider.getFrameworkType().getId(), projectCategory.getAssociatedFrameworkIds())) {
+          CheckedTreeNode treeNode = myFrameworksPanel.findNodeFor(provider);
+          treeNode.setChecked(true);
+        }
+      }
     }
-    myFrameworksPanel.setProviders(providers);
+    ((CardLayout)myOptionsPanel.getLayout()).show(myOptionsPanel, card);
   }
 
   private static boolean matchFramework(ProjectCategory projectCategory, FrameworkSupportInModuleProvider framework) {
@@ -120,6 +219,11 @@
   }
 
   @Override
+  public void updateDataModel() {
+    myWizard.getSequence().addStepsForBuilder(getSelectedBuilder(), myContext, myModulesProvider, true);
+  }
+
+  @Override
   public JComponent getPreferredFocusedComponent() {
     return myProjectTypeList;
   }
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/TemplateBasedProjectType.java b/java/idea-ui/src/com/intellij/ide/projectWizard/TemplateBasedProjectType.java
new file mode 100644
index 0000000..b6d8cf7
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/TemplateBasedProjectType.java
@@ -0,0 +1,68 @@
+/*
+ * 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.ide.projectWizard;
+
+import com.intellij.ide.util.projectWizard.ModuleBuilder;
+import com.intellij.platform.templates.ArchivedTemplatesFactory;
+import com.intellij.platform.templates.LocalArchivedTemplate;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.io.File;
+import java.net.URL;
+
+/**
+ * @author Dmitry Avdeev
+ *         Date: 20.09.13
+ */
+public abstract class TemplateBasedProjectType extends ProjectCategory {
+
+  private final LocalArchivedTemplate myTemplate;
+
+  public TemplateBasedProjectType(String templatePath) {
+    ClassLoader loader = getClass().getClassLoader();
+    URL resource = loader.getResource(templatePath);
+    assert resource != null : templatePath;
+    String name = ArchivedTemplatesFactory.getTemplateName(new File(templatePath).getName());
+    myTemplate = new LocalArchivedTemplate(name, resource, loader);
+  }
+
+  @NotNull
+  @Override
+  public ModuleBuilder createModuleBuilder() {
+    return myTemplate.createModuleBuilder();
+  }
+
+  @Override
+  public String getId() {
+    return getDisplayName();
+  }
+
+  @Override
+  public String getDisplayName() {
+    return myTemplate.getName();
+  }
+
+  @Override
+  public String getDescription() {
+    return myTemplate.getDescription();
+  }
+
+  @Override
+  public Icon getIcon() {
+    return myTemplate.getIcon();
+  }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/FrameworkSupportUtil.java b/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/FrameworkSupportUtil.java
index 78c9c68..b2b81ee 100644
--- a/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/FrameworkSupportUtil.java
+++ b/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/FrameworkSupportUtil.java
@@ -123,6 +123,12 @@
           dependencies.add(underlyingProvider);
         }
       }
+      for (String frameworkId : provider.getOptionalDependenciesFrameworkIds()) {
+        FrameworkSupportInModuleProvider dep = findProvider(frameworkId, myFrameworkSupportProviders);
+        if (dep != null) {
+          dependencies.add(dep);
+        }
+      }
       if (provider instanceof OldFrameworkSupportProviderWrapper) {
         String[] ids = ((OldFrameworkSupportProviderWrapper)provider).getProvider().getPrecedingFrameworkProviderIds();
         for (String id : ids) {
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AbstractProjectWizard.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AbstractProjectWizard.java
new file mode 100644
index 0000000..deca300
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AbstractProjectWizard.java
@@ -0,0 +1,263 @@
+/*
+ * 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.ide.util.newProjectWizard;
+
+import com.intellij.ide.highlighter.ModuleFileType;
+import com.intellij.ide.highlighter.ProjectFileType;
+import com.intellij.ide.util.projectWizard.ModuleWizardStep;
+import com.intellij.ide.util.projectWizard.ProjectBuilder;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.ide.wizard.AbstractWizard;
+import com.intellij.ide.wizard.CommitStepException;
+import com.intellij.openapi.components.StorageScheme;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+import java.awt.*;
+import java.io.File;
+
+/**
+ * @author Dmitry Avdeev
+ *         Date: 19.09.13
+ */
+public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardStep> {
+  protected final WizardContext myWizardContext;
+
+  public AbstractProjectWizard(String title, Project project, String defaultPath) {
+    super(title, project);
+    myWizardContext = initContext(project, defaultPath);
+  }
+
+  public AbstractProjectWizard(String title, Project project, Component dialogParent) {
+    super(title, dialogParent);
+    myWizardContext = initContext(project, null);
+  }
+
+  public abstract StepSequence getSequence();
+
+  private static WizardContext initContext(@Nullable Project project, @Nullable String defaultPath) {
+    WizardContext context = new WizardContext(project);
+    if (defaultPath != null) {
+      context.setProjectFileDirectory(defaultPath);
+      context.setProjectName(defaultPath.substring(FileUtil.toSystemIndependentName(defaultPath).lastIndexOf("/") + 1));
+    }
+   return context;
+  }
+
+  @Nullable
+  public static Sdk getNewProjectJdk(WizardContext context) {
+    if (context.getProjectJdk() != null) {
+      return context.getProjectJdk();
+    }
+    return getProjectSdkByDefault(context);
+  }
+
+  public static Sdk getProjectSdkByDefault(WizardContext context) {
+    final Project project = context.getProject() == null ? ProjectManager.getInstance().getDefaultProject() : context.getProject();
+    final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectSdk();
+    if (projectJdk != null) {
+      return projectJdk;
+    }
+    return null;
+  }
+
+  @NotNull
+  public String getNewProjectFilePath() {
+    if (myWizardContext.getProjectStorageFormat() == StorageScheme.DEFAULT) {
+      return myWizardContext.getProjectFileDirectory() + File.separator + myWizardContext.getProjectName() + ProjectFileType.DOT_DEFAULT_EXTENSION;
+    }
+    else {
+      return myWizardContext.getProjectFileDirectory();
+    }
+  }
+
+  @NotNull
+  public StorageScheme getStorageScheme() {
+    return myWizardContext.getProjectStorageFormat();
+  }
+
+  public ProjectBuilder getProjectBuilder() {
+    return myWizardContext.getProjectBuilder();
+  }
+
+  public String getProjectName() {
+    return myWizardContext.getProjectName();
+  }
+
+  @Nullable
+  public Sdk getNewProjectJdk() {
+    return getNewProjectJdk(myWizardContext);
+  }
+
+  @NotNull
+  public String getNewCompileOutput() {
+    final String projectFilePath = myWizardContext.getProjectFileDirectory();
+    @NonNls String path = myWizardContext.getCompilerOutputDirectory();
+    if (path == null) {
+      path = StringUtil.endsWithChar(projectFilePath, '/') ? projectFilePath + "out" : projectFilePath + "/out";
+    }
+    return path;
+  }
+
+  protected void updateStep() {
+    if (!mySteps.isEmpty()) {
+      getCurrentStepObject().updateStep();
+    }
+    super.updateStep();
+    myIcon.setIcon(null);
+  }
+
+  protected void dispose() {
+    for (ModuleWizardStep step : mySteps) {
+      step.disposeUIResources();
+    }
+    super.dispose();
+  }
+
+  protected final void doOKAction() {
+    int idx = getCurrentStep();
+    try {
+      do {
+        final ModuleWizardStep step = mySteps.get(idx);
+        if (step != getCurrentStepObject()) {
+          step.updateStep();
+        }
+        if (!commitStepData(step)) {
+          return;
+        }
+        step.onStepLeaving();
+        try {
+          step._commit(true);
+        }
+        catch (CommitStepException e) {
+          String message = e.getMessage();
+          if (message != null) {
+            Messages.showErrorDialog(getCurrentStepComponent(), message);
+          }
+          return;
+        }
+        if (!isLastStep(idx)) {
+          idx = getNextStep(idx);
+        } else {
+          break;
+        }
+      } while (true);
+    }
+    finally {
+      myCurrentStep = idx;
+      updateStep();
+    }
+    super.doOKAction();
+  }
+
+  protected boolean commitStepData(final ModuleWizardStep step) {
+    try {
+      if (!step.validate()) {
+        return false;
+      }
+    }
+    catch (ConfigurationException e) {
+      Messages.showErrorDialog(myContentPanel, e.getMessage(), e.getTitle());
+      return false;
+    }
+    step.updateDataModel();
+    return true;
+  }
+
+  public void doNextAction() {
+    final ModuleWizardStep step = getCurrentStepObject();
+    if (!commitStepData(step)) {
+      return;
+    }
+    step.onStepLeaving();
+    super.doNextAction();
+  }
+
+
+  protected String getHelpID() {
+    ModuleWizardStep step = getCurrentStepObject();
+    if (step != null) {
+      return step.getHelpId();
+    }
+    return null;
+  }
+
+  @TestOnly
+  public void doOk() {
+    doOKAction();
+  }
+
+  @TestOnly
+  public boolean isLast() {
+    return isLastStep();
+  }
+
+  @NonNls
+  public String getModuleFilePath() {
+    return myWizardContext.getProjectFileDirectory() + File.separator + myWizardContext.getProjectName() + ModuleFileType.DOT_DEFAULT_EXTENSION;
+  }
+
+  protected void doPreviousAction() {
+    final ModuleWizardStep step = getCurrentStepObject();
+    step.onStepLeaving();
+    super.doPreviousAction();
+  }
+
+  public void doCancelAction() {
+    final ModuleWizardStep step = getCurrentStepObject();
+    step.onStepLeaving();
+    super.doCancelAction();
+  }
+
+  private boolean isLastStep(int step) {
+    return getNextStep(step) == step;
+  }
+
+  protected final int getNextStep(final int step) {
+    ModuleWizardStep nextStep = null;
+    final StepSequence stepSequence = getSequence();
+    if (stepSequence != null) {
+      ModuleWizardStep current = mySteps.get(step);
+      nextStep = stepSequence.getNextStep(current);
+      while (nextStep != null && !nextStep.isStepVisible()) {
+        nextStep = stepSequence.getNextStep(nextStep);
+      }
+    }
+    return nextStep == null ? step : mySteps.indexOf(nextStep);
+  }
+
+  protected final int getPreviousStep(final int step) {
+      ModuleWizardStep previousStep = null;
+      final StepSequence stepSequence = getSequence();
+      if (stepSequence != null) {
+        previousStep = stepSequence.getPreviousStep(mySteps.get(step));
+        while (previousStep != null && !previousStep.isStepVisible()) {
+          previousStep = stepSequence.getPreviousStep(previousStep);
+        }
+      }
+      return previousStep == null ? 0 : mySteps.indexOf(previousStep);
+  }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddModuleWizard.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddModuleWizard.java
index 2cb74deb..31af15d 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddModuleWizard.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddModuleWizard.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.
@@ -21,77 +21,58 @@
 package com.intellij.ide.util.newProjectWizard;
 
 import com.intellij.ide.IdeBundle;
-import com.intellij.ide.highlighter.ModuleFileType;
-import com.intellij.ide.highlighter.ProjectFileType;
 import com.intellij.ide.util.newProjectWizard.modes.CreateFromTemplateMode;
 import com.intellij.ide.util.newProjectWizard.modes.ImportMode;
 import com.intellij.ide.util.newProjectWizard.modes.WizardMode;
 import com.intellij.ide.util.projectWizard.ModuleWizardStep;
 import com.intellij.ide.util.projectWizard.ProjectBuilder;
 import com.intellij.ide.util.projectWizard.WizardContext;
-import com.intellij.ide.wizard.AbstractWizard;
-import com.intellij.ide.wizard.CommitStepException;
 import com.intellij.ide.wizard.Step;
-import com.intellij.openapi.components.StorageScheme;
-import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
 import com.intellij.openapi.projectRoots.ProjectJdkTable;
 import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
 import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
-import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.projectImport.ProjectImportBuilder;
 import com.intellij.projectImport.ProjectImportProvider;
 import com.intellij.ui.IdeBorderFactory;
 import com.intellij.util.Function;
-import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.TestOnly;
 
 import javax.swing.*;
 import java.awt.*;
-import java.io.File;
 
-public class AddModuleWizard extends AbstractWizard<ModuleWizardStep>
-{
+public class AddModuleWizard extends AbstractProjectWizard {
   private static final String ADD_MODULE_TITLE = IdeBundle.message("title.add.module");
   private static final String NEW_PROJECT_TITLE = IdeBundle.message("title.new.project");
-  private final Project myCurrentProject;
   private ProjectImportProvider[] myImportProviders;
   private final ModulesProvider myModulesProvider;
-  private WizardContext myWizardContext;
   private WizardMode myWizardMode;
 
   /**
    * @param project if null, the wizard will start creating new project, otherwise will add a new module to the existing project.
    */
   public AddModuleWizard(@Nullable final Project project, final @NotNull ModulesProvider modulesProvider, @Nullable String defaultPath) {
-    super(project == null ? NEW_PROJECT_TITLE : ADD_MODULE_TITLE, project);
-    myCurrentProject = project;
+    super(project == null ? NEW_PROJECT_TITLE : ADD_MODULE_TITLE, project, defaultPath);
     myModulesProvider = modulesProvider;
     initModuleWizard(project, defaultPath);
   }
 
   /**
-   * @param project if null, the wizard will start creating new project, otherwise will add a new module to the existing proj.
+   * @param project if null, the wizard will start creating new project, otherwise will add a new module to the existing project.
    */
   public AddModuleWizard(Component parent, final Project project, @NotNull ModulesProvider modulesProvider) {
-    super(project == null ? NEW_PROJECT_TITLE : ADD_MODULE_TITLE, parent);
-    myCurrentProject = project;
+    super(project == null ? NEW_PROJECT_TITLE : ADD_MODULE_TITLE, project, parent);
     myModulesProvider = modulesProvider;
     initModuleWizard(project, null);
   }
 
   /** Import mode */
   public AddModuleWizard(@Nullable Project project, String filePath, ProjectImportProvider... importProviders) {
-    super(getImportWizardTitle(project, importProviders), project);
-    myCurrentProject = project;
+    super(getImportWizardTitle(project, importProviders), project, filePath);
     myImportProviders = importProviders;
     myModulesProvider = DefaultModulesProvider.createForProject(project);
     initModuleWizard(project, filePath);
@@ -99,8 +80,7 @@
 
   /** Import mode */
   public AddModuleWizard(Project project, Component dialogParent, String filePath, ProjectImportProvider... importProviders) {
-    super(getImportWizardTitle(project, importProviders), dialogParent);
-    myCurrentProject = project;
+    super(getImportWizardTitle(project, importProviders), project, dialogParent);
     myImportProviders = importProviders;
     myModulesProvider = DefaultModulesProvider.createForProject(project);
     initModuleWizard(project, filePath);
@@ -116,11 +96,6 @@
   }
 
   private void initModuleWizard(@Nullable final Project project, @Nullable final String defaultPath) {
-    myWizardContext = new WizardContext(project);
-    if (defaultPath != null) {
-      myWizardContext.setProjectFileDirectory(defaultPath);
-      myWizardContext.setProjectName(defaultPath.substring(FileUtil.toSystemIndependentName(defaultPath).lastIndexOf("/") + 1));
-    }
     myWizardContext.addContextListener(new WizardContext.Listener() {
       public void buttonsUpdateRequested() {
         updateButtons();
@@ -167,168 +142,9 @@
     return super.addStepComponent(component);
   }
 
-  protected void updateStep() {
-    if (!mySteps.isEmpty()) {
-      getCurrentStepObject().updateStep();
-    }
-    super.updateStep();
-    myIcon.setIcon(null);
-  }
-
-  protected void dispose() {
-    for (ModuleWizardStep step : mySteps) {
-      step.disposeUIResources();
-    }
-    super.dispose();
-  }
-
-  protected final void doOKAction() {
-    int idx = getCurrentStep();
-    try {
-      do {
-        final ModuleWizardStep step = mySteps.get(idx);
-        if (step != getCurrentStepObject()) {
-          step.updateStep();
-        }
-        if (!commitStepData(step)) {
-          return;
-        }
-        step.onStepLeaving();
-        try {
-          step._commit(true);
-        }
-        catch (CommitStepException e) {
-          String message = e.getMessage();
-          if (message != null) {
-            Messages.showErrorDialog(getCurrentStepComponent(), message);
-          }
-          return;
-        }
-        if (!isLastStep(idx)) {
-          idx = getNextStep(idx);
-        } else {
-          break;
-        }
-      } while (true);
-    }
-    finally {
-      myCurrentStep = idx;
-      updateStep();
-    }
-    super.doOKAction();
-  }
-
-  protected boolean commitStepData(final ModuleWizardStep step) {
-    try {
-      if (!step.validate()) {
-        return false;
-      }
-    }
-    catch (ConfigurationException e) {
-      Messages.showErrorDialog(myCurrentProject, e.getMessage(), e.getTitle());
-      return false;
-    }
-    step.updateDataModel();
-    return true;
-  }
-
-  public void doNextAction() {
-    final ModuleWizardStep step = getCurrentStepObject();
-    if (!commitStepData(step)) {
-      return;
-    }
-    step.onStepLeaving();
-    super.doNextAction();
-  }
-
-  protected void doPreviousAction() {
-    final ModuleWizardStep step = getCurrentStepObject();
-    step.onStepLeaving();
-    super.doPreviousAction();
-  }
-
-  public void doCancelAction() {
-    final ModuleWizardStep step = getCurrentStepObject();
-    step.onStepLeaving();
-    super.doCancelAction();
-  }
-
-  private boolean isLastStep(int step) {
-    return getNextStep(step) == step;
-  }
-
-
-  protected String getHelpID() {
-    ModuleWizardStep step = getCurrentStepObject();
-    if (step != null) {
-      return step.getHelpId();
-    }
-    return null;
-  }
-
-  protected final int getNextStep(final int step) {
-    ModuleWizardStep nextStep = null;
-    final StepSequence stepSequence = getSequence();
-    if (stepSequence != null) {
-      ModuleWizardStep current = mySteps.get(step);
-      nextStep = stepSequence.getNextStep(current);
-      while (nextStep != null && !nextStep.isStepVisible()) {
-        nextStep = stepSequence.getNextStep(nextStep);
-      }
-    }
-    return nextStep == null ? step : mySteps.indexOf(nextStep);
-  }
-
+  @Override
   public StepSequence getSequence() {
-    return getMode().getSteps(myWizardContext, myModulesProvider);
-  }
-
-  protected final int getPreviousStep(final int step) {
-      ModuleWizardStep previousStep = null;
-      final StepSequence stepSequence = getSequence();
-      if (stepSequence != null) {
-        previousStep = stepSequence.getPreviousStep(mySteps.get(step));
-        while (previousStep != null && !previousStep.isStepVisible()) {
-          previousStep = stepSequence.getPreviousStep(previousStep);
-        }
-      }
-      return previousStep == null ? 0 : mySteps.indexOf(previousStep);
-  }
-
-  private WizardMode getMode() {
-    return myWizardMode;
-  }
-
-  @NotNull
-  public String getNewProjectFilePath() {
-    if (myWizardContext.getProjectStorageFormat() == StorageScheme.DEFAULT) {
-      return myWizardContext.getProjectFileDirectory() + File.separator + myWizardContext.getProjectName() + ProjectFileType.DOT_DEFAULT_EXTENSION;
-    }
-    else {
-      return myWizardContext.getProjectFileDirectory();
-    }
-  }
-
-  @NotNull
-  public StorageScheme getStorageScheme() {
-    return myWizardContext.getProjectStorageFormat();
-  }
-
-  @Nullable
-  public static Sdk getNewProjectJdk(WizardContext context) {
-    if (context.getProjectJdk() != null) {
-      return context.getProjectJdk();
-    }
-    return getProjectSdkByDefault(context);
-  }
-
-  public static Sdk getProjectSdkByDefault(WizardContext context) {
-    final Project project = context.getProject() == null ? ProjectManager.getInstance().getDefaultProject() : context.getProject();
-    final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectSdk();
-    if (projectJdk != null) {
-      return projectJdk;
-    }
-    return null;
+    return myWizardMode.getSteps(myWizardContext, myModulesProvider);
   }
 
   @Nullable
@@ -349,34 +165,6 @@
     return myWizardContext;
   }
 
-  @Nullable
-  public Sdk getNewProjectJdk() {
-    return getNewProjectJdk(myWizardContext);
-  }
-
-  @NotNull
-  public String getNewCompileOutput() {
-    final String projectFilePath = myWizardContext.getProjectFileDirectory();
-    @NonNls String path = myWizardContext.getCompilerOutputDirectory();
-    if (path == null) {
-      path = StringUtil.endsWithChar(projectFilePath, '/') ? projectFilePath + "out" : projectFilePath + "/out";
-    }
-    return path;
-  }
-
-  @NonNls
-  public String getModuleFilePath() {
-    return myWizardContext.getProjectFileDirectory() + File.separator + myWizardContext.getProjectName() + ModuleFileType.DOT_DEFAULT_EXTENSION;
-  }
-
-  public ProjectBuilder getProjectBuilder() {
-    return myWizardContext.getProjectBuilder();
-  }
-
-  public String getProjectName() {
-    return myWizardContext.getProjectName();
-  }
-
   @Override
   protected String getDimensionServiceKey() {
     return "NewModule_or_Project.wizard";
@@ -404,20 +192,6 @@
     return false;
   }
 
-  public ProjectImportProvider[] getImportProviders() {
-    return myImportProviders;
-  }
-
-  @TestOnly
-  public void doOk() {
-    doOKAction();
-  }
-
-  @TestOnly
-  public boolean isLast() {
-    return isLastStep();
-  }
-
   @TestOnly
   public void commit() {
     commitStepData(getCurrentStepObject());
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java
index 6a8fef81..7e324c2 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java
@@ -40,6 +40,7 @@
 import com.intellij.ui.ScrollPaneFactory;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.ui.UIUtil;
+import com.intellij.util.ui.tree.TreeUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -47,6 +48,7 @@
 import javax.swing.*;
 import javax.swing.event.TreeSelectionEvent;
 import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
 import java.awt.*;
 import java.util.*;
 import java.util.List;
@@ -78,7 +80,7 @@
     myLibrariesContainer = model.getLibrariesContainer();
 
     myLabel.setVisible(!vertical);
-    Splitter splitter = vertical ? new Splitter(true, 0.6f, 0.3f, 0.9f) : new Splitter(false, 0.3f, 0.1f, 0.7f);
+    Splitter splitter = vertical ? new Splitter(true, 0.6f) : new Splitter(false, 0.3f, 0.1f, 0.7f);
     myFrameworksTree = new FrameworksTree() {
       @Override
       protected void onNodeStateChanged(CheckedTreeNode node) {
@@ -109,13 +111,13 @@
     splitter.setSecondComponent(myOptionsPanel);
     myFrameworksPanel.add(splitter, BorderLayout.CENTER);
 
-    myFrameworksTree.setSelectionRow(0);    
   }
 
   public void setProviders(List<FrameworkSupportInModuleProvider> providers) {
     myProviders = providers;
     createNodes();
     myFrameworksTree.setRoots(myRoots);
+    myFrameworksTree.setSelectionRow(0);
   }
 
   protected void onFrameworkStateChanged() {}
@@ -299,7 +301,7 @@
   private static void addChildFrameworks(final List<FrameworkSupportNodeBase> list, final List<FrameworkSupportNode> result,
                                          final boolean selectedOnly) {
     for (FrameworkSupportNodeBase node : list) {
-      if (!selectedOnly || node.isChecked()) {
+      if (!selectedOnly || node.isChecked() || node instanceof FrameworkGroupNode) {
         if (node instanceof FrameworkSupportNode) {
           result.add((FrameworkSupportNode)node);
         }
@@ -351,4 +353,8 @@
       }
     });
   }
+
+  public CheckedTreeNode findNodeFor(FrameworkSupportInModuleProvider provider) {
+    return (CheckedTreeNode)TreeUtil.findNodeWithObject((DefaultMutableTreeNode)myFrameworksTree.getModel().getRoot(), provider);
+  }
 }
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java
index 9239c96..6dabfa4 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java
@@ -96,6 +96,7 @@
     if (description != null) {
       myLibraryOptionsPanel = new LibraryOptionsPanel(description, myModel.getBaseDirectoryForLibrariesPath(), createLibraryVersionFilter(),
                                                       container, !myConfigurable.isOnlyLibraryAdded());
+      myLibraryOptionsPanel.setLibraryProvider(myModel.getLibraryProvider());
       Disposer.register(myConfigurable, myLibraryOptionsPanel);
       if (addSeparator) {
         JComponent separator1 = SeparatorFactory.createSeparator("Libraries", null);
@@ -111,6 +112,7 @@
     if (myLibraryOptionsPanel != null) {
       myLibraryOptionsPanel.changeBaseDirectoryPath(myModel.getBaseDirectoryForLibrariesPath());
       myLibraryOptionsPanel.setVersionFilter(createLibraryVersionFilter());
+      myLibraryOptionsPanel.setLibraryProvider(myModel.getLibraryProvider());
       myLibraryOptionsPanelWrapper.setVisible(myConfigurable.isVisible());
     }
   }
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java
index 13b4fcda..40ec96e 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java
@@ -106,7 +106,7 @@
     Messages.installHyperlinkSupport(myDescriptionPane);
 
     myFormatPanel = new ProjectFormatPanel();
-    myNamePathComponent = initNamePathComponent(context);
+    myNamePathComponent = NamePathComponent.initNamePathComponent(context);
     if (context.isCreatingNewProject()) {
       mySettingsPanel.add(myNamePathComponent, BorderLayout.NORTH);
       addExpertPanel(myModulePanel);
@@ -168,24 +168,6 @@
     return helpId;
   }
 
-  private static NamePathComponent initNamePathComponent(WizardContext context) {
-    NamePathComponent component = new NamePathComponent(
-      IdeBundle.message("label.project.name"),
-      IdeBundle.message("label.project.files.location"),
-      IdeBundle.message("title.select.project.file.directory", IdeBundle.message("project.new.wizard.project.identification")),
-      IdeBundle.message("description.select.project.file.directory", StringUtil
-        .capitalize(IdeBundle.message("project.new.wizard.project.identification"))),
-      true, false
-    );
-    final String baseDir = context.getProjectFileDirectory();
-    final String projectName = context.getProjectName();
-    final String initialProjectName = projectName != null ? projectName : ProjectWizardUtil.findNonExistingFileName(baseDir, "untitled", "");
-    component.setPath(projectName == null ? (baseDir + File.separator + initialProjectName) : baseDir);
-    component.setNameValue(initialProjectName);
-    component.getNameComponent().select(0, initialProjectName.length());
-    return component;
-  }
-
   private void setupPanels(@Nullable ProjectTemplate template) {
 
     restorePanel(myNamePathComponent, 4);
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/StepSequence.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/StepSequence.java
index 3b3acf0..bbc9b21 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/StepSequence.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/StepSequence.java
@@ -49,14 +49,17 @@
     myCommonSteps.add(step);
   }
 
-  public void addCommonFinishingStep(@NotNull ModuleWizardStep step, @NotNull Set<String> suitableTypes) {
+  public void addCommonFinishingStep(@NotNull ModuleWizardStep step, @Nullable Set<String> suitableTypes) {
     myCommonFinishingSteps.add(Pair.create(step, suitableTypes));
   }
 
-  public void addStepsForBuilder(@NotNull AbstractModuleBuilder builder, @NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) {
+  public void addStepsForBuilder(@NotNull AbstractModuleBuilder builder,
+                                 @NotNull WizardContext wizardContext,
+                                 @NotNull ModulesProvider modulesProvider,
+                                 boolean forNewWizard) {
     String id = builder.getBuilderId();
     if (!mySpecificSteps.containsKey(id)) {
-      mySpecificSteps.put(id, Arrays.asList(builder.createWizardSteps(wizardContext, modulesProvider)));
+      mySpecificSteps.put(id, Arrays.asList(builder.createWizardSteps(wizardContext, modulesProvider, forNewWizard)));
     }
   }
 
@@ -73,7 +76,8 @@
         mySelectedSteps.addAll(steps);
       }
       for (Pair<ModuleWizardStep, Set<String>> pair : myCommonFinishingSteps) {
-        if (ContainerUtil.intersects(myTypes, pair.getSecond())) {
+        Set<String> types = pair.getSecond();
+        if (types == null || ContainerUtil.intersects(myTypes, types)) {
           mySelectedSteps.add(pair.getFirst());
         }
       }
@@ -121,8 +125,4 @@
     ContainerUtil.removeDuplicates(result);
     return result;
   }
-
-  public ModuleWizardStep getFirstStep() {
-    return myCommonSteps.get(0);
-  }
 }
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SupportForFrameworksStep.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SupportForFrameworksStep.java
index 78f9bb2..08f56ea 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SupportForFrameworksStep.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SupportForFrameworksStep.java
@@ -17,13 +17,10 @@
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.util.ui.tree.TreeUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.TestOnly;
 
 import javax.swing.*;
-import javax.swing.tree.TreeNode;
 import java.util.List;
 
 /**
@@ -128,23 +125,4 @@
       return getBaseDirectory(myBuilder);
     }
   }
-
-  @TestOnly
-  public boolean enableSupport(final String frameworkId) {
-    return !TreeUtil.traverse((TreeNode)mySupportForFrameworksPanel.getFrameworksTree().getModel().getRoot(), new TreeUtil.Traverse() {
-      @Override
-      public boolean accept(Object node) {
-        if (node instanceof FrameworkSupportNode && frameworkId.equals(
-          ((FrameworkSupportNode)node).getProvider().getFrameworkType().getId())) {
-          TreeNode parent = ((FrameworkSupportNode)node).getParent();
-          if (parent instanceof FrameworkSupportNode) {
-            ((FrameworkSupportNode)parent).setChecked(true);
-          }
-          ((FrameworkSupportNode)node).setChecked(true);
-          return false;
-        }
-        return true;
-      }
-    });
-  }
 }
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
index 48a9d929..8faaa8d 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.ide.util.newProjectWizard.impl;
 
+import com.intellij.facet.impl.ui.libraries.FrameworkLibraryProvider;
 import com.intellij.framework.FrameworkGroup;
 import com.intellij.framework.FrameworkGroupVersion;
 import com.intellij.framework.FrameworkVersion;
@@ -51,6 +52,7 @@
   private final Map<String, FrameworkSupportNode> mySettingsMap = new HashMap<String, FrameworkSupportNode>();
   private final Map<String, FrameworkSupportOptionsComponent> myOptionsComponentsMap = new HashMap<String, FrameworkSupportOptionsComponent>();
   private final Map<String, FrameworkVersion> mySelectedVersions = new HashMap<String, FrameworkVersion>();
+  private FrameworkLibraryProvider myLibraryProvider;
 
   public FrameworkSupportModelBase(final @Nullable Project project, @Nullable ModuleBuilder builder, @NotNull LibrariesContainer librariesContainer) {
     myProject = project;
@@ -159,6 +161,17 @@
     return false;
   }
 
+  public FrameworkLibraryProvider getLibraryProvider() {
+    return myLibraryProvider;
+  }
+
+  public void setLibraryProvider(FrameworkLibraryProvider libraryProvider) {
+    myLibraryProvider = libraryProvider;
+    for (FrameworkSupportOptionsComponent optionsComponent : myOptionsComponentsMap.values()) {
+      optionsComponent.updateLibrariesPanel();
+    }
+  }
+
   @Nullable
   public <V extends FrameworkVersion> V getSelectedVersion(@NotNull String frameworkOrGroupId) {
     return (V)mySelectedVersions.get(frameworkOrGroupId);
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java
index bc10c31..bb631ec 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java
@@ -63,7 +63,7 @@
 
     StepSequence sequence = new StepSequence();
     for (ModuleBuilder builder : builders) {
-      sequence.addStepsForBuilder(builder, context, modulesProvider);
+      sequence.addStepsForBuilder(builder, context, modulesProvider, false);
     }
     return sequence;
   }
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java
index 81aff5b..0d057b6 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java
@@ -106,7 +106,7 @@
     MultiMap<TemplatesGroup, ProjectTemplate> map = getTemplatesMap(context);
     StepSequence sequence = new StepSequence();
     for (ProjectTemplate template : map.values()) {
-      sequence.addStepsForBuilder(template.createModuleBuilder(), context, modulesProvider);
+      sequence.addStepsForBuilder(template.createModuleBuilder(), context, modulesProvider, false);
     }
     mySelectTemplateStep = new SelectTemplateStep(context, sequence, map);
     sequence.addCommonStep(mySelectTemplateStep);
diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.java
index 47889b0..2a81296 100644
--- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.java
+++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.java
@@ -25,6 +25,7 @@
 import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.ui.DocumentAdapter;
 import com.intellij.ui.FieldPanel;
 import com.intellij.util.ui.UIUtil;
@@ -118,6 +119,24 @@
                                                  insets, 0, 0));
   }
 
+  public static NamePathComponent initNamePathComponent(WizardContext context) {
+    NamePathComponent component = new NamePathComponent(
+      IdeBundle.message("label.project.name"),
+      IdeBundle.message("label.project.files.location"),
+      IdeBundle.message("title.select.project.file.directory", IdeBundle.message("project.new.wizard.project.identification")),
+      IdeBundle.message("description.select.project.file.directory", StringUtil
+        .capitalize(IdeBundle.message("project.new.wizard.project.identification"))),
+      true, false
+    );
+    final String baseDir = context.getProjectFileDirectory();
+    final String projectName = context.getProjectName();
+    final String initialProjectName = projectName != null ? projectName : ProjectWizardUtil.findNonExistingFileName(baseDir, "untitled", "");
+    component.setPath(projectName == null ? (baseDir + File.separator + initialProjectName) : baseDir);
+    component.setNameValue(initialProjectName);
+    component.getNameComponent().select(0, initialProjectName.length());
+    return component;
+  }
+
   private String getProjectFilePath(boolean isDefault) {
     if (isDefault) {
       return getPath() + "/" + getNameValue() + ProjectFileType.DOT_DEFAULT_EXTENSION;
diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java
index 2674cd6..5397b3d 100644
--- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java
+++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java
@@ -16,7 +16,7 @@
 package com.intellij.ide.util.projectWizard;
 
 import com.intellij.ide.util.frameworkSupport.FrameworkSupportUtil;
-import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
 import com.intellij.ide.util.newProjectWizard.SourcePathsStep;
 import com.intellij.ide.util.newProjectWizard.SupportForFrameworksStep;
 import com.intellij.openapi.projectRoots.Sdk;
@@ -114,7 +114,7 @@
     }
     projectSdkStep = new ProjectJdkStep(wizardContext) {
       public boolean isStepVisible() {
-        final Sdk newProjectJdk = AddModuleWizard.getProjectSdkByDefault(wizardContext);
+        final Sdk newProjectJdk = AbstractProjectWizard.getProjectSdkByDefault(wizardContext);
         if (newProjectJdk == null) return true;
         final ProjectBuilder projectBuilder = wizardContext.getProjectBuilder();
         return projectBuilder != null && !projectBuilder.isSuitableSdk(newProjectJdk);
@@ -127,7 +127,7 @@
   @Nullable
   @Override
   public Sdk getNewProjectSdk(WizardContext wizardContext) {
-    return AddModuleWizard.getNewProjectJdk(wizardContext);
+    return AbstractProjectWizard.getNewProjectJdk(wizardContext);
   }
 
   @Override
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaResourceRootEditHandlerBase.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaResourceRootEditHandlerBase.java
index 806dd60..3c2b3a2 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaResourceRootEditHandlerBase.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaResourceRootEditHandlerBase.java
@@ -16,10 +16,8 @@
 package com.intellij.openapi.roots.ui.configuration;
 
 import com.intellij.openapi.actionSystem.CustomShortcutSet;
-import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.jps.model.JpsDummyElement;
-import org.jetbrains.jps.model.JpsElementFactory;
 import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 
 import javax.swing.*;
@@ -49,10 +47,4 @@
   public CustomShortcutSet getMarkRootShortcutSet() {
     return null;
   }
-
-  @NotNull
-  @Override
-  public JpsDummyElement createDefaultProperties() {
-    return JpsElementFactory.getInstance().createDummyElement();
-  }
 }
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java
index 56ef125b..a0a86e1 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.openapi.roots.ui.configuration.actions;
 
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
 import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
 import com.intellij.ide.util.newProjectWizard.AddModuleWizardPro;
 import com.intellij.ide.util.projectWizard.ModuleBuilder;
@@ -68,7 +69,7 @@
   }
 
   @Nullable
-  public Module createModuleFromWizard(Project project, @Nullable Object dataFromContext, AddModuleWizard wizard) {
+  public Module createModuleFromWizard(Project project, @Nullable Object dataFromContext, AbstractProjectWizard wizard) {
     final ProjectBuilder builder = wizard.getProjectBuilder();
     if (builder instanceof ModuleBuilder) {
       final ModuleBuilder moduleBuilder = (ModuleBuilder)builder;
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java
index 45e6a53..4d0da3e 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java
@@ -91,9 +91,7 @@
     if (myErrorLabel.isShowing()) {
       myErrorLabel.setText(errorText);
     }
-    else {
-      myErrorText = errorText;
-    }
+    myErrorText = errorText;
     myMainPanel.setVisible(true);
     myCurrentQuickFixes = quickFixes;
     myFixButton.setVisible(!quickFixes.isEmpty());
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java
index 0763407..34bd02b 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java
@@ -30,11 +30,15 @@
 import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.VirtualFileVisitor;
+import com.intellij.util.IconUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
 
 /**
  * @author nik
@@ -108,7 +112,7 @@
 
   private static class AttachUrlJavadocDescriptor extends AttachRootButtonDescriptor {
     private AttachUrlJavadocDescriptor() {
-      super(JavadocOrderRootType.getInstance(), ProjectBundle.message("module.libraries.javadoc.url.button"));
+      super(JavadocOrderRootType.getInstance(), IconUtil.getAddLinkIcon(), ProjectBundle.message("module.libraries.javadoc.url.button"));
     }
 
     @Override
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java
index 3afce2d..f4c6db4 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java
@@ -142,7 +142,7 @@
     myTreeBuilder = new LibraryTableTreeBuilder(myTree, (DefaultTreeModel)myTree.getModel(), treeStructure);
     myTreePanel.setLayout(new BorderLayout());
 
-    ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(myTree).disableUpDownActions().disableAddAction()
+    ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(myTree).disableUpDownActions()
       .setRemoveActionName(ProjectBundle.message("library.detach.action"))
       .setRemoveAction(new AnActionButtonRunnable() {
         @Override
@@ -173,29 +173,43 @@
         }
       });
 
+    List<String> actionsOrder = new ArrayList<String>();
+    actionsOrder.add("Add");
+    final List<AttachRootButtonDescriptor> popupItems = new ArrayList<AttachRootButtonDescriptor>();
+    for (AttachRootButtonDescriptor descriptor : myDescriptor.createAttachButtons()) {
+      Icon icon = descriptor.getToolbarIcon();
+      if (icon != null) {
+        AttachItemAction action = new AttachItemAction(descriptor, descriptor.getButtonText(), icon);
+        toolbarDecorator.addExtraAction(AnActionButton.fromAction(action));
+        actionsOrder.add(action.getTemplatePresentation().getText());
+      }
+      else {
+        popupItems.add(descriptor);
+      }
+    }
+    actionsOrder.add("Remove");
+
     toolbarDecorator.setAddAction(new AnActionButtonRunnable() {
       @Override
       public void run(AnActionButton button) {
-        final AnAction[] children = getActions();
-        if (children.length == 0) return;
-        final DefaultActionGroup actions = new DefaultActionGroup(children);
-        JBPopupFactory.getInstance().createActionGroupPopup(null, actions,
+        if (popupItems.isEmpty()) {
+          new AttachFilesAction(myDescriptor.getAttachFilesActionName()).actionPerformed(null);
+          return;
+        }
+
+        List<AnAction> actions = new ArrayList<AnAction>();
+        actions.add(new AttachFilesAction(myDescriptor.getAttachFilesActionName()));
+        for (AttachRootButtonDescriptor descriptor : popupItems) {
+          actions.add(new AttachItemAction(descriptor, descriptor.getButtonText(), null));
+        }
+        final DefaultActionGroup group = new DefaultActionGroup(actions);
+        JBPopupFactory.getInstance().createActionGroupPopup(null, group,
                                                             DataManager.getInstance().getDataContext(button.getContextComponent()),
                                                             JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, true)
           .show(button.getPreferredPopupPoint());
       }
-
-      private AnAction[] getActions() {
-        List<AnAction> actions = new ArrayList<AnAction>();
-        actions.add(new AttachFilesAction(myDescriptor.getAttachFilesActionName()));
-        for (AttachRootButtonDescriptor descriptor : myDescriptor.createAttachButtons()) {
-          actions.add(new AttachItemAction(descriptor, descriptor.getButtonText()));
-        }
-        return actions.toArray(new AnAction[actions.size()]);
-      }
     });
-
-
+    toolbarDecorator.setButtonComparator(ArrayUtil.toStringArray(actionsOrder));
 
     myTreePanel.add(toolbarDecorator.createPanel(), BorderLayout.CENTER);
     ToolbarDecorator.findRemoveButton(myTreePanel).addCustomUpdater(new AnActionButtonUpdater() {
@@ -406,8 +420,9 @@
   private class AttachItemAction extends AttachItemActionBase {
     private final AttachRootButtonDescriptor myDescriptor;
 
-    protected AttachItemAction(AttachRootButtonDescriptor descriptor, String title) {
+    protected AttachItemAction(AttachRootButtonDescriptor descriptor, String title, final Icon icon) {
       super(title);
+      getTemplatePresentation().setIcon(icon);
       myDescriptor = descriptor;
     }
 
@@ -472,23 +487,4 @@
   public void removeListener(Runnable listener) {
     myListeners.remove(listener);
   }
-
-  @Nullable
-  private static Class<?> getElementsClass(Object[] elements) {
-    if (elements.length == 0) {
-      return null;
-    }
-    Class<?> cls = null;
-    for (Object element : elements) {
-      if (cls == null) {
-        cls = element.getClass();
-      }
-      else {
-        if (!cls.equals(element.getClass())) {
-          return null;
-        }
-      }
-    }
-    return cls;
-  }
 }
diff --git a/java/idea-ui/src/com/intellij/platform/templates/ArchivedTemplatesFactory.java b/java/idea-ui/src/com/intellij/platform/templates/ArchivedTemplatesFactory.java
index 919f952..08c673f 100644
--- a/java/idea-ui/src/com/intellij/platform/templates/ArchivedTemplatesFactory.java
+++ b/java/idea-ui/src/com/intellij/platform/templates/ArchivedTemplatesFactory.java
@@ -132,7 +132,7 @@
         for (String child : children) {
           if (child.endsWith(ZIP)) {
             URL templateUrl = new URL(url.first.toExternalForm() + "/" + child);
-            String name = child.substring(0, child.length() - ZIP.length()).replace('_', ' ');
+            String name = getTemplateName(child);
             templates.add(new LocalArchivedTemplate(name, templateUrl, url.second));
           }
         }
@@ -144,6 +144,10 @@
     return templates.toArray(new ProjectTemplate[templates.size()]);
   }
 
+  public static String getTemplateName(String child) {
+    return child.substring(0, child.length() - ZIP.length()).replace('_', ' ');
+  }
+
   @Override
   public int getGroupWeight(String group) {
     return CUSTOM_GROUP.equals(group) ? -2 : 0;
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
index 0aeb2bb..cb34a20 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
@@ -30,6 +30,7 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.projectRoots.JavaSdkVersion;
 import com.intellij.openapi.projectRoots.JavaVersionService;
+import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.pom.java.LanguageLevel;
@@ -37,6 +38,7 @@
 import com.intellij.psi.controlFlow.ControlFlowUtil;
 import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef;
 import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
+import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
 import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl;
 import com.intellij.psi.javadoc.PsiDocComment;
 import com.intellij.psi.javadoc.PsiDocTagValue;
@@ -311,16 +313,28 @@
                     myHolder.add(result);
                   }
                   else {
-                    for (int i = 0; i < lambdaParameters.length; i++) {
-                      PsiParameter lambdaParameter = lambdaParameters[i];
-                      if (!TypeConversionUtil.isAssignable(lambdaParameter.getType(),
-                                                           GenericsUtil.eliminateWildcards(
-                                                             LambdaUtil.getSubstitutor(interfaceMethod, resolveResult)
-                                                               .substitute(parameters[i].getType())))) {
-                        HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(lambdaParameter)
-                          .descriptionAndTooltip(incompatibleTypesMessage).create();
-                        myHolder.add(result);
-                        break;
+                    final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
+                    if (expression.hasFormalParameterTypes()) {
+                      for (int i = 0; i < lambdaParameters.length; i++) {
+                        if (!Comparing.equal(lambdaParameters[i].getType(), substitutor.substitute(parameters[i].getType()))) {
+                          HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
+                            .range(lambdaParameters[i])
+                            .descriptionAndTooltip(incompatibleTypesMessage)
+                            .create();
+                          myHolder.add(result);
+                          break;
+                        }
+                      }
+                    } else {
+                      for (int i = 0; i < lambdaParameters.length; i++) {
+                        PsiParameter lambdaParameter = lambdaParameters[i];
+                        if (!TypeConversionUtil.isAssignable(lambdaParameter.getType(),
+                                                             GenericsUtil.eliminateWildcards(substitutor.substitute(parameters[i].getType())))) {
+                          HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(lambdaParameter)
+                            .descriptionAndTooltip(incompatibleTypesMessage).create();
+                          myHolder.add(result);
+                          break;
+                        }
                       }
                     }
                   }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
index 7a747834..4554b15 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
@@ -58,14 +58,13 @@
     super(factory);
   }
 
-  @Override
-  protected DfaMemoryStateImpl createNew() {
-    return new ExpressionTypeMemoryState(getFactory());
+  private ExpressionTypeMemoryState(DfaMemoryStateImpl toCopy) {
+    super(toCopy);
   }
 
   @Override
   public DfaMemoryStateImpl createCopy() {
-    final ExpressionTypeMemoryState copy = (ExpressionTypeMemoryState)super.createCopy();
+    final ExpressionTypeMemoryState copy = new ExpressionTypeMemoryState(this);
     copy.myStates.putAll(myStates);
     return copy;
   }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
index 58bb1fc..fed5b5b 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
@@ -22,7 +22,6 @@
 import com.intellij.codeInspection.dataFlow.instructions.*;
 import com.intellij.codeInspection.dataFlow.value.*;
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
@@ -100,24 +99,7 @@
     return JavaPsiFacade.getElementFactory(manager.getProject()).createTypeByFQClassName(fqn, scope);
   }
 
-  private boolean myRecursionStopper = false;
-
   private <T extends Instruction> T addInstruction(T i) {
-    ProgressManager.checkCanceled();
-
-    if (!myRecursionStopper) {
-      myRecursionStopper = true;
-      try {
-        // add extra conditional goto in order to handle possible runtime exceptions that could be caught by finally block
-        if (i instanceof BranchingInstruction || i instanceof AssignInstruction || i instanceof MethodCallInstruction) {
-          addConditionalRuntimeThrow();
-        }
-      }
-      finally {
-        myRecursionStopper = false;
-      }
-    }
-
     myCurrentFlow.addInstruction(i);
     return i;
   }
@@ -137,7 +119,10 @@
 
   private void finishElement(PsiElement element) {
     myCurrentFlow.finishElement(element);
-    assert element == myElementStack.pop();
+    PsiElement popped = myElementStack.pop();
+    if (element != popped) {
+      throw new AssertionError("Expected " + element + ", popped " + popped);
+    }
   }
 
   @Override
@@ -146,64 +131,60 @@
   }
 
   @Override public void visitAssignmentExpression(PsiAssignmentExpression expression) {
+    PsiExpression lExpr = expression.getLExpression();
+    PsiExpression rExpr = expression.getRExpression();
+
     startElement(expression);
+    if (rExpr == null) {
+      pushUnknown();
+      finishElement(expression);
+      return;
+    }
 
-    try {
-      PsiExpression lExpr = expression.getLExpression();
-      PsiExpression rExpr = expression.getRExpression();
+    lExpr.accept(this);
 
-      if (rExpr == null) {
-        pushUnknown();
-        return;
-      }
-
-      lExpr.accept(this);
-
-      IElementType op = expression.getOperationTokenType();
-      PsiType type = expression.getType();
-      boolean isBoolean = PsiType.BOOLEAN.equals(type);
-      if (op == JavaTokenType.EQ) {
-        rExpr.accept(this);
-        generateBoxingUnboxingInstructionFor(rExpr, type);
-      }
-      else if (op == JavaTokenType.ANDEQ) {
-        if (isBoolean) {
-          generateNonLazyExpression(true, lExpr, rExpr, type);
-        }
-        else {
-          generateDefaultBinOp(lExpr, rExpr, type);
-        }
-      }
-      else if (op == JavaTokenType.OREQ) {
-        if (isBoolean) {
-          generateNonLazyExpression(false, lExpr, rExpr, type);
-        }
-        else {
-          generateDefaultBinOp(lExpr, rExpr, type);
-        }
-      }
-      else if (op == JavaTokenType.XOREQ) {
-        if (isBoolean) {
-          generateXorExpression(expression, new PsiExpression[]{lExpr, rExpr}, type);
-        }
-        else {
-          generateDefaultBinOp(lExpr, rExpr, type);
-        }
-      }
-      else if (op == JavaTokenType.PLUSEQ && type != null && type.equalsToText(JAVA_LANG_STRING)) {
-        lExpr.accept(this);
-        rExpr.accept(this);
-        addInstruction(new BinopInstruction(JavaTokenType.PLUS, null, lExpr.getProject()));
+    IElementType op = expression.getOperationTokenType();
+    PsiType type = expression.getType();
+    boolean isBoolean = PsiType.BOOLEAN.equals(type);
+    if (op == JavaTokenType.EQ) {
+      rExpr.accept(this);
+      generateBoxingUnboxingInstructionFor(rExpr, type);
+    }
+    else if (op == JavaTokenType.ANDEQ) {
+      if (isBoolean) {
+        generateNonLazyExpression(true, lExpr, rExpr, type);
       }
       else {
         generateDefaultBinOp(lExpr, rExpr, type);
       }
+    }
+    else if (op == JavaTokenType.OREQ) {
+      if (isBoolean) {
+        generateNonLazyExpression(false, lExpr, rExpr, type);
+      }
+      else {
+        generateDefaultBinOp(lExpr, rExpr, type);
+      }
+    }
+    else if (op == JavaTokenType.XOREQ) {
+      if (isBoolean) {
+        generateXorExpression(expression, new PsiExpression[]{lExpr, rExpr}, type);
+      }
+      else {
+        generateDefaultBinOp(lExpr, rExpr, type);
+      }
+    }
+    else if (op == JavaTokenType.PLUSEQ && type != null && type.equalsToText(JAVA_LANG_STRING)) {
+      lExpr.accept(this);
+      rExpr.accept(this);
+      addInstruction(new BinopInstruction(JavaTokenType.PLUS, null, lExpr.getProject()));
+    }
+    else {
+      generateDefaultBinOp(lExpr, rExpr, type);
+    }
 
-      addInstruction(new AssignInstruction(rExpr));
-    }
-    finally {
-      finishElement(expression);
-    }
+    addInstruction(new AssignInstruction(rExpr));
+    finishElement(expression);
   }
 
   private void generateDefaultBinOp(PsiExpression lExpr, PsiExpression rExpr, final PsiType exprType) {
@@ -658,11 +639,13 @@
 
     if (exception != null) {
       exception.accept(this);
+      addConditionalRuntimeThrow();
       addInstruction(new DupInstruction());
       addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null));
       addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, statement.getProject()));
       ConditionalGotoInstruction gotoInstruction = new ConditionalGotoInstruction(null, true, null);
       addInstruction(gotoInstruction);
+      addInstruction(new PushInstruction(myFactory.createTypeValue(myNpe, Nullness.NOT_NULL), null));
       addThrowCode(myNpe);
       gotoInstruction.setOffset(myCurrentFlow.getInstructionCount());
       addThrowCode(exception.getType());
@@ -1008,42 +991,40 @@
   public void visitPolyadicExpression(PsiPolyadicExpression expression) {
     startElement(expression);
 
-    try {
-      DfaValue dfaValue = myFactory.createValue(expression);
-      if (dfaValue != null) {
-        addInstruction(new PushInstruction(dfaValue, expression));
-        return;
-      }
-      IElementType op = expression.getOperationTokenType();
-
-      PsiExpression[] operands = expression.getOperands();
-      if (operands.length <= 1) {
-        pushUnknown();
-        return;
-      }
-      PsiType type = expression.getType();
-      if (op == JavaTokenType.ANDAND) {
-        generateAndExpression(operands, type, true);
-      }
-      else if (op == JavaTokenType.OROR) {
-        generateOrExpression(operands, type, true);
-      }
-      else if (op == JavaTokenType.XOR && PsiType.BOOLEAN.equals(type)) {
-        generateXorExpression(expression, operands, type);
-      }
-      else if (op == JavaTokenType.AND && PsiType.BOOLEAN.equals(type)) {
-        generateAndExpression(operands, type, false);
-      }
-      else if (op == JavaTokenType.OR && PsiType.BOOLEAN.equals(type)) {
-        generateOrExpression(operands, type, false);
-      }
-      else {
-        generateOther(expression, op, operands, type);
-      }
-    }
-    finally {
+    DfaValue dfaValue = myFactory.createValue(expression);
+    if (dfaValue != null) {
+      addInstruction(new PushInstruction(dfaValue, expression));
       finishElement(expression);
+      return;
     }
+    IElementType op = expression.getOperationTokenType();
+
+    PsiExpression[] operands = expression.getOperands();
+    if (operands.length <= 1) {
+      pushUnknown();
+      finishElement(expression);
+      return;
+    }
+    PsiType type = expression.getType();
+    if (op == JavaTokenType.ANDAND) {
+      generateAndExpression(operands, type, true);
+    }
+    else if (op == JavaTokenType.OROR) {
+      generateOrExpression(operands, type, true);
+    }
+    else if (op == JavaTokenType.XOR && PsiType.BOOLEAN.equals(type)) {
+      generateXorExpression(expression, operands, type);
+    }
+    else if (op == JavaTokenType.AND && PsiType.BOOLEAN.equals(type)) {
+      generateAndExpression(operands, type, false);
+    }
+    else if (op == JavaTokenType.OR && PsiType.BOOLEAN.equals(type)) {
+      generateOrExpression(operands, type, false);
+    }
+    else {
+      generateOther(expression, op, operands, type);
+    }
+    finishElement(expression);
   }
 
   private void generateOther(PsiPolyadicExpression expression, IElementType op, PsiExpression[] operands, PsiType type) {
@@ -1106,6 +1087,7 @@
       addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.UNBOXING, expectedType));
     }
     else if (TypeConversionUtil.isAssignableFromPrimitiveWrapper(expectedType) && TypeConversionUtil.isPrimitiveAndNotNull(exprType)) {
+      addConditionalRuntimeThrow();
       addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.BOXING, expectedType));
     }
     else if (exprType != expectedType &&
@@ -1275,7 +1257,7 @@
       if (type instanceof PsiClassType) {
         type = ((PsiClassType)type).rawType();
       }
-      addInstruction(new PushInstruction(myFactory.getTypeFactory().createTypeValue(type), null));
+      addInstruction(new PushInstruction(myFactory.createTypeValue(type, Nullness.UNKNOWN), null));
       addInstruction(new InstanceofInstruction(expression, expression.getProject(), operand, type));
     }
     else {
@@ -1301,58 +1283,56 @@
   }
 
   @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) {
-    try {
-      startElement(expression);
+    startElement(expression);
 
-      if (handleContracts(expression, getCallContracts(expression))) {
-        return;
-      }
-
-      PsiReferenceExpression methodExpression = expression.getMethodExpression();
-      PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
-
-      if (qualifierExpression != null) {
-        qualifierExpression.accept(this);
-      }
-      else {
-        pushUnknown();
-      }
-
-      PsiExpression[] expressions = expression.getArgumentList().getExpressions();
-      PsiElement method = methodExpression.resolve();
-      PsiParameter[] parameters = method instanceof PsiMethod ? ((PsiMethod)method).getParameterList().getParameters() : null;
-      for (int i = 0; i < expressions.length; i++) {
-        PsiExpression paramExpr = expressions[i];
-        paramExpr.accept(this);
-        if (parameters != null && i < parameters.length) {
-          generateBoxingUnboxingInstructionFor(paramExpr, parameters[i].getType());
-        }
-      }
-
-      addInstruction(new MethodCallInstruction(expression, createChainedVariableValue(expression)));
-
-      if (!myCatchStack.isEmpty()) {
-        addMethodThrows(expression.resolveMethod());
-      }
-
-      if (expressions.length == 1 && method instanceof PsiMethod &&
-          "equals".equals(((PsiMethod)method).getName()) && parameters.length == 1 &&
-          parameters[0].getType().equalsToText(JAVA_LANG_OBJECT) &&
-          PsiType.BOOLEAN.equals(((PsiMethod)method).getReturnType())) {
-        addInstruction(new PushInstruction(myFactory.getConstFactory().getFalse(), null));
-        addInstruction(new SwapInstruction());
-        addInstruction(new ConditionalGotoInstruction(getEndOffset(expression), true, null));
-
-        addInstruction(new PopInstruction());
-        addInstruction(new PushInstruction(myFactory.getConstFactory().getTrue(), null));
-
-        expressions[0].accept(this);
-        addInstruction(new ApplyNotNullInstruction(expression));
-      }
-    }
-    finally {
+    if (handleContracts(expression, getCallContracts(expression))) {
       finishElement(expression);
+      return;
     }
+
+    PsiReferenceExpression methodExpression = expression.getMethodExpression();
+    PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
+
+    if (qualifierExpression != null) {
+      qualifierExpression.accept(this);
+    }
+    else {
+      pushUnknown();
+    }
+
+    PsiExpression[] expressions = expression.getArgumentList().getExpressions();
+    PsiElement method = methodExpression.resolve();
+    PsiParameter[] parameters = method instanceof PsiMethod ? ((PsiMethod)method).getParameterList().getParameters() : null;
+    for (int i = 0; i < expressions.length; i++) {
+      PsiExpression paramExpr = expressions[i];
+      paramExpr.accept(this);
+      if (parameters != null && i < parameters.length) {
+        generateBoxingUnboxingInstructionFor(paramExpr, parameters[i].getType());
+      }
+    }
+
+    addConditionalRuntimeThrow();
+    addInstruction(new MethodCallInstruction(expression, createChainedVariableValue(expression)));
+
+    if (!myCatchStack.isEmpty()) {
+      addMethodThrows(expression.resolveMethod());
+    }
+
+    if (expressions.length == 1 && method instanceof PsiMethod &&
+        "equals".equals(((PsiMethod)method).getName()) && parameters.length == 1 &&
+        parameters[0].getType().equalsToText(JAVA_LANG_OBJECT) &&
+        PsiType.BOOLEAN.equals(((PsiMethod)method).getReturnType())) {
+      addInstruction(new PushInstruction(myFactory.getConstFactory().getFalse(), null));
+      addInstruction(new SwapInstruction());
+      addInstruction(new ConditionalGotoInstruction(getEndOffset(expression), true, null));
+
+      addInstruction(new PopInstruction());
+      addInstruction(new PushInstruction(myFactory.getConstFactory().getTrue(), null));
+
+      expressions[0].accept(this);
+      addInstruction(new ApplyNotNullInstruction(expression));
+    }
+    finishElement(expression);
   }
 
   private boolean handleContracts(PsiMethodCallExpression expression, List<MethodContract> _contracts) {
@@ -1527,9 +1507,9 @@
         if (type == ASSERT_IS_NULL_METHOD || type == ASSERT_IS_NOT_NULL_METHOD) {
           constraints[checkedParam] = type == ASSERT_IS_NOT_NULL_METHOD ? ValueConstraint.NULL_VALUE : ValueConstraint.NOT_NULL_VALUE;
           return Collections.singletonList(new MethodContract(constraints, ValueConstraint.THROW_EXCEPTION));
-        } else if (type == IS_NULL_METHOD || type == IS_NOT_NULL_METHOD) {
-          constraints[checkedParam] = type == IS_NULL_METHOD ? ValueConstraint.NOT_NULL_VALUE : ValueConstraint.NULL_VALUE;
-          return Collections.singletonList(new MethodContract(constraints, ValueConstraint.FALSE_VALUE));
+        } else if (type == IS_NOT_NULL_METHOD || type == IS_NULL_METHOD) {
+          constraints[checkedParam] = ValueConstraint.NULL_VALUE;
+          return Collections.singletonList(new MethodContract(constraints, type == IS_NULL_METHOD ? ValueConstraint.TRUE_VALUE : ValueConstraint.FALSE_VALUE));
         } else { //assertTrue or assertFalse
           constraints[checkedParam] = type == ASSERT_FALSE_METHOD ? ValueConstraint.TRUE_VALUE : ValueConstraint.FALSE_VALUE;
           return Collections.singletonList(new MethodContract(constraints, ValueConstraint.THROW_EXCEPTION));
@@ -1594,7 +1574,7 @@
 
     final DfaValue dfaValue;
     if (type instanceof PsiClassType) {
-      dfaValue = myFactory.getTypeFactory().createTypeValue(type);
+      dfaValue = myFactory.createTypeValue(type, Nullness.UNKNOWN);
     }
     else {
       dfaValue = null;
@@ -1623,6 +1603,7 @@
           addInstruction(new PopInstruction());
         }
       }
+      addConditionalRuntimeThrow();
       addInstruction(new MethodCallInstruction(expression, null));
     }
     else {
@@ -1640,6 +1621,7 @@
         }
       }
 
+      addConditionalRuntimeThrow();
       addInstruction(new MethodCallInstruction(expression, null));
 
       if (!myCatchStack.isEmpty()) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
index bbac522..b462090 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
@@ -33,8 +33,10 @@
 import com.intellij.codeInspection.*;
 import com.intellij.codeInspection.dataFlow.instructions.*;
 import com.intellij.codeInspection.dataFlow.value.DfaConstValue;
+import com.intellij.codeInspection.dataFlow.value.DfaValue;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.WriteExternalException;
 import com.intellij.openapi.util.text.StringUtil;
@@ -47,6 +49,7 @@
 import com.intellij.util.ArrayUtilRt;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.MultiMap;
 import org.jdom.Element;
 import org.jetbrains.annotations.NonNls;
@@ -145,7 +148,7 @@
     PsiClass containingClass = PsiTreeUtil.getParentOfType(scope, PsiClass.class);
     if (containingClass != null && PsiUtil.isLocalOrAnonymousClass(containingClass)) return;
 
-    final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(SUGGEST_NULLABLE_ANNOTATIONS) {
+    final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner() {
       @Override
       protected boolean shouldCheckTimeLimit() {
         if (!onTheFly) return false;
@@ -159,7 +162,7 @@
                                             ProblemsHolder holder,
                                             StandardDataFlowRunner dfaRunner,
                                             Collection<DfaMemoryState> initialStates) {
-    final StandardInstructionVisitor visitor = new DataFlowInstructionVisitor(dfaRunner);
+    final DataFlowInstructionVisitor visitor = new DataFlowInstructionVisitor(dfaRunner);
     final RunnerResult rc = dfaRunner.analyzeMethod(scope, visitor, IGNORE_ASSERT_STATEMENTS, initialStates);
     if (rc == RunnerResult.OK) {
       createDescription(dfaRunner, holder, visitor);
@@ -213,7 +216,7 @@
   protected void addSurroundWithIfFix(PsiExpression qualifier, List<LocalQuickFix> fixes) {
   }
 
-  private void createDescription(StandardDataFlowRunner runner, ProblemsHolder holder, StandardInstructionVisitor visitor) {
+  private void createDescription(StandardDataFlowRunner runner, ProblemsHolder holder, DataFlowInstructionVisitor visitor) {
     Pair<Set<Instruction>, Set<Instruction>> constConditions = runner.getConstConditionalExpressions();
     Set<Instruction> trueSet = constConditions.getFirst();
     Set<Instruction> falseSet = constConditions.getSecond();
@@ -221,28 +224,25 @@
     ArrayList<Instruction> allProblems = new ArrayList<Instruction>();
     allProblems.addAll(trueSet);
     allProblems.addAll(falseSet);
-    allProblems.addAll(runner.getNPEInstructions());
     allProblems.addAll(runner.getCCEInstructions());
     allProblems.addAll(StandardDataFlowRunner.getRedundantInstanceofs(runner, visitor));
 
-    Collections.sort(allProblems, new Comparator<Instruction>() {
-      @Override
-      public int compare(Instruction i1, Instruction i2) {
-        return i1.getIndex() - i2.getIndex();
-      }
-    });
-
     HashSet<PsiElement> reportedAnchors = new HashSet<PsiElement>();
+    for (PsiElement element : visitor.getProblems(NullabilityProblem.callNPE)) {
+      if (reportedAnchors.add(element)) {
+        reportCallMayProduceNpe(holder, (PsiMethodCallExpression)element);
+      }
+    }
+    for (PsiElement element : visitor.getProblems(NullabilityProblem.fieldAccessNPE)) {
+      if (reportedAnchors.add(element)) {
+        PsiElement parent = element.getParent();
+        PsiElement fieldAccess = parent instanceof PsiArrayAccessExpression || parent instanceof PsiReferenceExpression ? parent : element;
+        reportFieldAccessMayProduceNpe(holder, element, (PsiExpression)fieldAccess);
+      }
+    }
 
     for (Instruction instruction : allProblems) {
-      if (instruction instanceof MethodCallInstruction) {
-        reportCallMayProduceNpe(holder, (MethodCallInstruction)instruction, reportedAnchors);
-      }
-      else if (instruction instanceof FieldReferenceInstruction &&
-               reportedAnchors.add(((FieldReferenceInstruction)instruction).getElementToAssert())) {
-        reportFieldAccessMayProduceNpe(holder, (FieldReferenceInstruction)instruction);
-      }
-      else if (instruction instanceof TypeCastInstruction &&
+      if (instruction instanceof TypeCastInstruction &&
                reportedAnchors.add(((TypeCastInstruction)instruction).getCastExpression().getCastType())) {
         reportCastMayFail(holder, (TypeCastInstruction)instruction);
       }
@@ -251,11 +251,15 @@
       }
     }
 
-    reportNullableArguments(runner, holder, reportedAnchors);
-    reportNullableAssignments(runner, holder, reportedAnchors);
-    reportUnboxedNullables(runner, holder, reportedAnchors);
-    reportNullableReturns(runner, holder, reportedAnchors);
-    reportNullableArgumentsPassedToNonAnnotated(runner, holder, reportedAnchors);
+    reportNullableArguments(visitor, holder, reportedAnchors);
+    reportNullableAssignments(visitor, holder, reportedAnchors);
+    reportUnboxedNullables(visitor, holder, reportedAnchors);
+    if (!runner.isInNullableMethod() && runner.isInMethod() && (runner.isInNotNullMethod() || SUGGEST_NULLABLE_ANNOTATIONS)) {
+      reportNullableReturns(runner, visitor, holder, reportedAnchors);
+    }
+    if (SUGGEST_NULLABLE_ANNOTATIONS) {
+      reportNullableArgumentsPassedToNonAnnotated(visitor, holder, reportedAnchors);
+    }
 
     if (REPORT_CONSTANT_REFERENCE_VALUES) {
       reportConstantReferenceValues(holder, visitor, reportedAnchors);
@@ -317,15 +321,14 @@
     return value instanceof String ? "\"" + StringUtil.escapeStringCharacters((String)value) + "\"" : String.valueOf(value);
   }
 
-  private void reportNullableArgumentsPassedToNonAnnotated(StandardDataFlowRunner runner, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
-    Set<PsiExpression> exprs = runner.getNullableArgumentsPassedToNonAnnotatedParam();
-    for (PsiExpression expr : exprs) {
+  private void reportNullableArgumentsPassedToNonAnnotated(DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
+    for (PsiElement expr : visitor.getProblems(NullabilityProblem.passingNullableArgumentToNonAnnotatedParameter)) {
       if (reportedAnchors.contains(expr)) continue;
 
       final String text = isNullLiteralExpression(expr)
                           ? "Passing <code>null</code> argument to non annotated parameter"
                           : "Argument <code>#ref</code> #loc might be null but passed to non annotated parameter";
-      LocalQuickFix[] fixes = createNPEFixes(expr, expr);
+      LocalQuickFix[] fixes = createNPEFixes((PsiExpression)expr, (PsiExpression)expr);
       final PsiElement parent = expr.getParent();
       if (parent instanceof PsiExpressionList) {
         final int idx = ArrayUtilRt.find(((PsiExpressionList)parent).getExpressions(), expr);
@@ -349,22 +352,15 @@
     }
   }
 
-  private void reportCallMayProduceNpe(ProblemsHolder holder, MethodCallInstruction mcInstruction, Set<PsiElement> reportedAnchors) {
-    if (mcInstruction.getCallExpression() instanceof PsiMethodCallExpression) {
-      PsiMethodCallExpression callExpression = (PsiMethodCallExpression)mcInstruction.getCallExpression();
-      if (!reportedAnchors.add(callExpression)) return;
+  private void reportCallMayProduceNpe(ProblemsHolder holder, PsiMethodCallExpression callExpression) {
+    LocalQuickFix[] fix = createNPEFixes(callExpression.getMethodExpression().getQualifierExpression(), callExpression);
 
-      LocalQuickFix[] fix = createNPEFixes(callExpression.getMethodExpression().getQualifierExpression(), callExpression);
-
-      holder.registerProblem(callExpression,
-                             InspectionsBundle.message("dataflow.message.npe.method.invocation"),
-                             fix);
-    }
+    holder.registerProblem(callExpression,
+                           InspectionsBundle.message("dataflow.message.npe.method.invocation"),
+                           fix);
   }
 
-  private void reportFieldAccessMayProduceNpe(ProblemsHolder holder, FieldReferenceInstruction frInstruction) {
-    PsiElement elementToAssert = frInstruction.getElementToAssert();
-    PsiExpression expression = frInstruction.getExpression();
+  private void reportFieldAccessMayProduceNpe(ProblemsHolder holder, PsiElement elementToAssert, PsiExpression expression) {
     if (expression instanceof PsiArrayAccessExpression) {
       LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression);
       holder.registerProblem(expression,
@@ -382,8 +378,11 @@
 
   private static void reportCastMayFail(ProblemsHolder holder, TypeCastInstruction instruction) {
     PsiTypeCastExpression typeCast = instruction.getCastExpression();
-    holder.registerProblem(typeCast.getCastType(),
-                           InspectionsBundle.message("dataflow.message.cce", typeCast.getOperand().getText()));
+    PsiExpression operand = typeCast.getOperand();
+    PsiTypeElement castType = typeCast.getCastType();
+    assert castType != null;
+    assert operand != null;
+    holder.registerProblem(castType, InspectionsBundle.message("dataflow.message.cce", operand.getText()));
   }
 
   private void handleBranchingInstruction(ProblemsHolder holder,
@@ -413,7 +412,7 @@
     }
     else if (psiAnchor != null && !reportedAnchors.contains(psiAnchor) && !isCompileConstantInIfCondition(psiAnchor)) {
       boolean evaluatesToTrue = trueSet.contains(instruction);
-      if (onTheLeftSideOfConditionalAssignemnt(psiAnchor)) {
+      if (onTheLeftSideOfConditionalAssignment(psiAnchor)) {
         holder.registerProblem(
           psiAnchor,
           InspectionsBundle.message("dataflow.message.pointless.assignment.expression", Boolean.toString(evaluatesToTrue)),
@@ -436,21 +435,20 @@
            visitor.silenceConstantCondition(psiAnchor);
   }
 
-  private void reportNullableArguments(StandardDataFlowRunner runner, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
-    Set<PsiExpression> exprs = runner.getNullableArguments();
-    for (PsiExpression expr : exprs) {
+  private void reportNullableArguments(DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
+    for (PsiElement expr : visitor.getProblems(NullabilityProblem.passingNullableToNotNullParameter)) {
       if (!reportedAnchors.add(expr)) continue;
 
       final String text = isNullLiteralExpression(expr)
                           ? InspectionsBundle.message("dataflow.message.passing.null.argument")
                           : InspectionsBundle.message("dataflow.message.passing.nullable.argument");
-      LocalQuickFix[] fixes = createNPEFixes(expr, expr);
+      LocalQuickFix[] fixes = createNPEFixes((PsiExpression)expr, (PsiExpression)expr);
       holder.registerProblem(expr, text, fixes);
     }
   }
 
-  private static void reportNullableAssignments(StandardDataFlowRunner runner, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
-    for (PsiExpression expr : runner.getNullableAssignments()) {
+  private static void reportNullableAssignments(DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
+    for (PsiElement expr : visitor.getProblems(NullabilityProblem.assigningToNotNull)) {
       if (!reportedAnchors.add(expr)) continue;
 
       final String text = isNullLiteralExpression(expr)
@@ -460,16 +458,16 @@
     }
   }
 
-  private static void reportUnboxedNullables(StandardDataFlowRunner runner, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
-    for (PsiExpression expr : runner.getUnboxedNullables()) {
+  private static void reportUnboxedNullables(DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
+    for (PsiElement expr : visitor.getProblems(NullabilityProblem.unboxingNullable)) {
       if (!reportedAnchors.add(expr)) continue;
       holder.registerProblem(expr, InspectionsBundle.message("dataflow.message.unboxing"));
     }
   }
 
-  private static void reportNullableReturns(StandardDataFlowRunner runner, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
-    for (PsiReturnStatement statement : runner.getNullableReturns()) {
-      final PsiExpression expr = statement.getReturnValue();
+  private static void reportNullableReturns(StandardDataFlowRunner runner, DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
+    for (PsiElement statement : visitor.getProblems(NullabilityProblem.nullableReturn)) {
+      final PsiExpression expr = ((PsiReturnStatement)statement).getReturnValue();
       assert expr != null;
       if (!reportedAnchors.add(expr)) continue;
 
@@ -547,7 +545,7 @@
     return parent instanceof PsiIfStatement && ((PsiIfStatement)parent).getCondition() == element;
   }
 
-  private static boolean isNullLiteralExpression(PsiExpression expr) {
+  private static boolean isNullLiteralExpression(PsiElement expr) {
     if (expr instanceof PsiLiteralExpression) {
       final PsiLiteralExpression literalExpression = (PsiLiteralExpression)expr;
       return PsiType.NULL.equals(literalExpression.getType());
@@ -555,7 +553,7 @@
     return false;
   }
 
-  private static boolean onTheLeftSideOfConditionalAssignemnt(final PsiElement psiAnchor) {
+  private static boolean onTheLeftSideOfConditionalAssignment(final PsiElement psiAnchor) {
     final PsiElement parent = psiAnchor.getParent();
     if (parent instanceof PsiAssignmentExpression) {
       final PsiAssignmentExpression expression = (PsiAssignmentExpression)parent;
@@ -699,45 +697,55 @@
 
   private static class DataFlowInstructionVisitor extends StandardInstructionVisitor {
     private final StandardDataFlowRunner myRunner;
+    private final MultiMap<NullabilityProblem, PsiElement> myProblems = new MultiMap<NullabilityProblem, PsiElement>();
+    private final Map<Pair<NullabilityProblem, PsiElement>, StateInfo> myStateInfos = ContainerUtil.newHashMap();
 
     private DataFlowInstructionVisitor(StandardDataFlowRunner runner) {
       myRunner = runner;
     }
 
     @Override
-    protected void onAssigningToNotNullableVariable(AssignInstruction instruction) {
-      myRunner.onAssigningToNotNullableVariable(instruction.getRExpression());
-    }
-
-    @Override
-    protected void onNullableReturn(CheckReturnValueInstruction instruction) {
-      myRunner.onNullableReturn(instruction.getReturn());
-    }
-
-    @Override
     protected void onInstructionProducesCCE(TypeCastInstruction instruction) {
       myRunner.onInstructionProducesCCE(instruction);
     }
-
-    @Override
-    protected void onInstructionProducesNPE(Instruction instruction) {
-      if (instruction instanceof MethodCallInstruction &&
-          ((MethodCallInstruction)instruction).getMethodType() == MethodCallInstruction.MethodType.UNBOXING) {
-        myRunner.onUnboxingNullable(((MethodCallInstruction)instruction).getContext());
-      }
-      else {
-        myRunner.onInstructionProducesNPE(instruction);
-      }
+    
+    Collection<PsiElement> getProblems(final NullabilityProblem kind) {
+      return ContainerUtil.filter(myProblems.get(kind), new Condition<PsiElement>() {
+        @Override
+        public boolean value(PsiElement psiElement) {
+          StateInfo info = myStateInfos.get(Pair.create(kind, psiElement));
+          // non-ephemeral NPE should be reported
+          // ephemeral NPE should also be reported if only ephemeral states have reached a particular problematic instruction
+          //  (e.g. if it's inside "if (var == null)" check after contract method invocation
+          return info.normalNpe || info.ephemeralNpe && !info.normalOk;
+        }
+      });
     }
 
     @Override
-    protected void onPassingNullParameter(PsiExpression arg) {
-      myRunner.onPassingNullParameter(arg);
+    protected boolean checkNotNullable(DfaMemoryState state, DfaValue value, NullabilityProblem problem, PsiElement anchor) {
+      boolean ok = super.checkNotNullable(state, value, problem, anchor);
+      if (!ok && anchor != null) {
+        myProblems.putValue(problem, anchor);
+      }
+      Pair<NullabilityProblem, PsiElement> key = Pair.create(problem, anchor);
+      StateInfo info = myStateInfos.get(key);
+      if (info == null) {
+        myStateInfos.put(key, info = new StateInfo());
+      }
+      if (state.isEphemeral() && !ok) {
+        info.ephemeralNpe = true;
+      } else if (!state.isEphemeral()) {
+        if (ok) info.normalOk = true;
+        else info.normalNpe = true;
+      }
+      return ok;
     }
-
-    @Override
-    protected void onPassingNullParameterToNonAnnotated(DataFlowRunner runner, PsiExpression arg) {
-      myRunner.onPassingNullParameterToNonAnnotated(arg);
+    
+    private static class StateInfo {
+      boolean ephemeralNpe;
+      boolean normalNpe;
+      boolean normalOk;
     }
   }
 }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
index 298b51b..38c242bc 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
@@ -24,10 +24,7 @@
  */
 package com.intellij.codeInspection.dataFlow;
 
-import com.intellij.codeInspection.dataFlow.instructions.BranchingInstruction;
-import com.intellij.codeInspection.dataFlow.instructions.EmptyInstruction;
-import com.intellij.codeInspection.dataFlow.instructions.Instruction;
-import com.intellij.codeInspection.dataFlow.instructions.MethodCallInstruction;
+import com.intellij.codeInspection.dataFlow.instructions.*;
 import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
 import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
 import com.intellij.openapi.application.ApplicationManager;
@@ -38,7 +35,9 @@
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.MultiMap;
+import com.intellij.util.containers.MultiMapBasedOnSet;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -108,6 +107,17 @@
       myInstructions = flow.getInstructions();
       myFields = flow.getFields();
       myNestedClosures.clear();
+      
+      Set<Instruction> joinInstructions = ContainerUtil.newHashSet();
+      for (Instruction instruction : myInstructions) {
+        if (instruction instanceof GotoInstruction) {
+          joinInstructions.add(myInstructions[((GotoInstruction)instruction).getOffset()]);
+        } else if (instruction instanceof ConditionalGotoInstruction) {
+          joinInstructions.add(myInstructions[((ConditionalGotoInstruction)instruction).getOffset()]);
+        } else if (instruction instanceof GosubInstruction) {
+          joinInstructions.add(myInstructions[((GosubInstruction)instruction).getSubprogramOffset()]);
+        }
+      }
 
       if (LOG.isDebugEnabled()) {
         LOG.debug("Analyzing code block: " + psiBlock.getText());
@@ -123,47 +133,61 @@
         return RunnerResult.TOO_COMPLEX;
       }
 
-      final ArrayList<DfaInstructionState> queue = new ArrayList<DfaInstructionState>();
+      final StateQueue queue = new StateQueue();
       for (final DfaMemoryState initialState : initialStates) {
-        queue.add(new DfaInstructionState(myInstructions[0], initialState));
+        queue.offer(new DfaInstructionState(myInstructions[0], initialState));
       }
 
+      MultiMapBasedOnSet<BranchingInstruction, DfaMemoryState> processedStates = new MultiMapBasedOnSet<BranchingInstruction, DfaMemoryState>();
+      MultiMapBasedOnSet<BranchingInstruction, DfaMemoryState> incomingStates = new MultiMapBasedOnSet<BranchingInstruction, DfaMemoryState>();
+
       WorkingTimeMeasurer measurer = new WorkingTimeMeasurer(shouldCheckTimeLimit() ? ourTimeLimit : ourTimeLimit * 42);
       int count = 0;
       while (!queue.isEmpty()) {
-        if (count % 64 == 0 && measurer.isTimeOver()) {
-          LOG.debug("Too complex because the analysis took too long");
-          psiBlock.putUserData(TOO_EXPENSIVE_HASH, psiBlock.getText().hashCode());
-          return RunnerResult.TOO_COMPLEX;
-        }
-        ProgressManager.checkCanceled();
+        for (DfaInstructionState instructionState : queue.getNextInstructionStates(joinInstructions)) {
+          if (count++ % 1024 == 0 && measurer.isTimeOver()) {
+            LOG.debug("Too complex because the analysis took too long");
+            psiBlock.putUserData(TOO_EXPENSIVE_HASH, psiBlock.getText().hashCode());
+            return RunnerResult.TOO_COMPLEX;
+          }
+          ProgressManager.checkCanceled();
 
-        DfaInstructionState instructionState = queue.remove(0);
-        if (LOG.isDebugEnabled()) {
-          LOG.debug(instructionState.toString());
-        }
-        //System.out.println(instructionState.toString());
+          if (LOG.isDebugEnabled()) {
+            LOG.debug(instructionState.toString());
+          }
+          //System.out.println(instructionState.toString());
 
-        Instruction instruction = instructionState.getInstruction();
-        long distance = instructionState.getDistanceFromStart();
+          Instruction instruction = instructionState.getInstruction();
 
-        if (instruction instanceof BranchingInstruction) {
-          if (!instruction.setMemoryStateProcessed(instructionState.getMemoryState().createCopy())) {
-            LOG.debug("Too complex because too many different possible states");
-            return RunnerResult.TOO_COMPLEX; // Too complex :(
+          if (instruction instanceof BranchingInstruction) {
+            BranchingInstruction branching = (BranchingInstruction)instruction;
+            if (processedStates.get(branching).contains(instructionState.getMemoryState())) {
+              continue;
+            }
+            if (processedStates.get(branching).size() > MAX_STATES_PER_BRANCH) {
+              LOG.debug("Too complex because too many different possible states");
+              return RunnerResult.TOO_COMPLEX; // Too complex :(
+            }
+            processedStates.putValue(branching, instructionState.getMemoryState().createCopy());
+          }
+
+          DfaInstructionState[] after = acceptInstruction(visitor, instructionState);
+          for (DfaInstructionState state : after) {
+            Instruction nextInstruction = state.getInstruction();
+            if (nextInstruction.getIndex() >= endOffset) {
+              continue;
+            }
+            if (nextInstruction instanceof BranchingInstruction) {
+              BranchingInstruction branching = (BranchingInstruction)nextInstruction;
+              if (processedStates.get(branching).contains(state.getMemoryState()) || 
+                  incomingStates.get(branching).contains(state.getMemoryState())) {
+                continue;
+              }
+              incomingStates.putValue(branching, state.getMemoryState().createCopy());
+            }
+            queue.offer(state);
           }
         }
-
-        DfaInstructionState[] after = acceptInstruction(visitor, instructionState);
-        for (DfaInstructionState state : after) {
-          Instruction nextInstruction = state.getInstruction();
-          if ((!(nextInstruction instanceof BranchingInstruction) || !nextInstruction.isMemoryStateProcessed(state.getMemoryState())) && instruction.getIndex() < endOffset) {
-            state.setDistanceFromStart(distance + 1);
-            queue.add(state);
-          }
-        }
-
-        count++;
       }
 
       psiBlock.putUserData(TOO_EXPENSIVE_HASH, null);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java
index 87d8b8a..1683807 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java
@@ -25,23 +25,26 @@
 package com.intellij.codeInspection.dataFlow;
 
 import com.intellij.codeInspection.dataFlow.instructions.Instruction;
+import com.intellij.openapi.util.Pair;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 
-public class DfaInstructionState {
+import java.util.Collections;
+import java.util.List;
+import java.util.PriorityQueue;
+import java.util.Set;
+
+public class DfaInstructionState implements Comparable<DfaInstructionState> {
   public static final DfaInstructionState[] EMPTY_ARRAY = new DfaInstructionState[0];
   private final DfaMemoryState myBeforeMemoryState;
   private final Instruction myInstruction;
-  private long myDistanceFromStart = 0;
 
   public DfaInstructionState(@NotNull Instruction myInstruction, @NotNull DfaMemoryState myBeforeMemoryState) {
     this.myBeforeMemoryState = myBeforeMemoryState;
     this.myInstruction = myInstruction;
   }
 
-  public long getDistanceFromStart() { return myDistanceFromStart; }
-
-  public void setDistanceFromStart(long distanceFromStart) { myDistanceFromStart = distanceFromStart; }
-
   @NotNull
   public Instruction getInstruction() {
     return myInstruction;
@@ -55,4 +58,58 @@
   public String toString() {
     return getInstruction().getIndex() + " " + getInstruction() + ":   " + getMemoryState().toString();
   }
+
+  @Override
+  public int compareTo(@NotNull DfaInstructionState o) {
+    return myInstruction.getIndex() - o.myInstruction.getIndex();
+  }
 }
+
+class StateQueue {
+  private final PriorityQueue<DfaInstructionState> myQueue = new PriorityQueue<DfaInstructionState>();
+  private final Set<Pair<Instruction, DfaMemoryState>> mySet = ContainerUtil.newHashSet();
+  
+  void offer(DfaInstructionState state) {
+    if (mySet.add(Pair.create(state.getInstruction(), state.getMemoryState()))) {
+      myQueue.offer(state);
+    }
+  }
+
+  boolean isEmpty() {
+    return myQueue.isEmpty();
+  }
+
+  List<DfaInstructionState> getNextInstructionStates(Set<Instruction> joinInstructions) {
+    DfaInstructionState state = myQueue.poll();
+    final Instruction instruction = state.getInstruction();
+    mySet.remove(Pair.create(instruction, state.getMemoryState()));
+
+    DfaInstructionState next = myQueue.peek();
+    if (next == null || next.compareTo(state) != 0) return Collections.singletonList(state);
+
+    List<DfaMemoryStateImpl> memoryStates = ContainerUtil.newArrayList();
+    memoryStates.add((DfaMemoryStateImpl)state.getMemoryState());
+    while (!myQueue.isEmpty() && myQueue.peek().compareTo(state) == 0) {
+      DfaMemoryState anotherState = myQueue.poll().getMemoryState();
+      mySet.remove(Pair.create(instruction, anotherState));
+      memoryStates.add((DfaMemoryStateImpl)anotherState);
+    }
+
+    if (memoryStates.size() > 1 && joinInstructions.contains(instruction)) {
+      while (true) {
+        List<DfaMemoryStateImpl> nextStates = new StateMerger(memoryStates).merge();
+        if (nextStates == null) break;
+        memoryStates = nextStates;
+      }
+    }
+
+    return ContainerUtil.map(memoryStates, new Function<DfaMemoryStateImpl, DfaInstructionState>() {
+      @Override
+      public DfaInstructionState fun(DfaMemoryStateImpl state) {
+        return new DfaInstructionState(instruction, state);
+      }
+    });
+  }
+  
+  
+}
\ No newline at end of file
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
index 8309670..106267af 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
@@ -59,4 +59,13 @@
 
   @Nullable
   DfaConstValue getConstantValue(DfaVariableValue value);
+
+  /**
+   * Ephemeral means a state that was created when considering a method contract and checking if one of its arguments is null.
+   * With explicit null check, that would result in any non-annotated variable being treated as nullable and producing possible NPE warnings later.
+   * With contracts, we don't want this. So the state where this variable is null is marked ephemeral and no NPE warnings are issued for such states. 
+   */
+  void markEphemeral();
+  
+  boolean isEphemeral();
 }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
index d77a0f9..f5430d5 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
@@ -26,6 +26,7 @@
 
 import com.intellij.codeInspection.dataFlow.value.*;
 import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.util.UnorderedPair;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.util.TypeConversionUtil;
@@ -41,43 +42,50 @@
 public class DfaMemoryStateImpl implements DfaMemoryState {
   private final DfaValueFactory myFactory;
 
-  private final List<SortedIntSet> myEqClasses = new ArrayList<SortedIntSet>();
-  private final Stack<DfaValue> myStack = new Stack<DfaValue>();
-  private TIntStack myOffsetStack = new TIntStack(1);
-  private final TLongHashSet myDistinctClasses = new TLongHashSet();
-  private final THashMap<DfaVariableValue,DfaVariableState> myVariableStates = new THashMap<DfaVariableValue, DfaVariableState>();
-  private final THashSet<DfaVariableValue> myUnknownVariables = new THashSet<DfaVariableValue>();
+  private final List<EqClass> myEqClasses;
+  private final Stack<DfaValue> myStack;
+  private TIntStack myOffsetStack;
+  private final TLongHashSet myDistinctClasses;
+  private final Map<DfaVariableValue,DfaVariableState> myVariableStates;
+  private final Map<DfaVariableValue,DfaVariableState> myDefaultVariableStates; 
+  private final Set<DfaVariableValue> myUnknownVariables;
+  private boolean myEphemeral;
 
   public DfaMemoryStateImpl(final DfaValueFactory factory) {
     myFactory = factory;
+    myDefaultVariableStates = ContainerUtil.newTroveMap();
+    myEqClasses = ContainerUtil.newArrayList();
+    myUnknownVariables = ContainerUtil.newTroveSet();
+    myVariableStates = ContainerUtil.newTroveMap();
+    myDistinctClasses = new TLongHashSet();
+    myOffsetStack = new TIntStack();
+    myStack = new Stack<DfaValue>();
+  }
+
+  protected DfaMemoryStateImpl(DfaMemoryStateImpl toCopy) {
+    myFactory = toCopy.myFactory;
+    myEphemeral = toCopy.myEphemeral;
+    myDefaultVariableStates = toCopy.myDefaultVariableStates; // shared between all states
+    
+    myStack = new Stack<DfaValue>(toCopy.myStack);
+    myDistinctClasses = new TLongHashSet(toCopy.myDistinctClasses.toArray());
+    myUnknownVariables = new THashSet<DfaVariableValue>(toCopy.myUnknownVariables);
+    myOffsetStack = toCopy.myOffsetStack;
+
+    myEqClasses = ContainerUtil.newArrayList(toCopy.myEqClasses);
+    myVariableStates = new THashMap<DfaVariableValue, DfaVariableState>(toCopy.myVariableStates);
+    
+    myCachedDistinctClassPairs = toCopy.myCachedDistinctClassPairs;
+    myCachedNonTrivialEqClasses = toCopy.myCachedNonTrivialEqClasses;
   }
 
   public DfaValueFactory getFactory() {
     return myFactory;
   }
 
-  protected DfaMemoryStateImpl createNew() {
-    return new DfaMemoryStateImpl(myFactory);
-  }
-
   @Override
   public DfaMemoryStateImpl createCopy() {
-    DfaMemoryStateImpl newState = createNew();
-
-    newState.myStack.addAll(myStack);
-    newState.myDistinctClasses.addAll(myDistinctClasses.toArray());
-    newState.myUnknownVariables.addAll(myUnknownVariables);
-    newState.myOffsetStack = new TIntStack(myOffsetStack);
-
-    for (int i = 0; i < myEqClasses.size(); i++) {
-      SortedIntSet aClass = myEqClasses.get(i);
-      newState.myEqClasses.add(aClass != null ? new SortedIntSet(aClass.toNativeArray()) : null);
-    }
-
-    for (DfaVariableValue dfaVariableValue : myVariableStates.keySet()) {
-      newState.myVariableStates.put(dfaVariableValue, myVariableStates.get(dfaVariableValue).clone());
-    }
-    return newState;
+    return new DfaMemoryStateImpl(this);
   }
 
   public boolean equals(Object obj) {
@@ -85,84 +93,70 @@
     if (!(obj instanceof DfaMemoryStateImpl)) return false;
     DfaMemoryStateImpl that = (DfaMemoryStateImpl)obj;
 
-    if (myDistinctClasses.size() != that.myDistinctClasses.size()) return false;
-    if (myStack.size() != that.myStack.size()) return false;
-    if (myOffsetStack.size() != that.myOffsetStack.size()) return false;
-    if (myVariableStates.size() != that.myVariableStates.size()) return false;
-    if (myUnknownVariables.size() != that.myUnknownVariables.size()) return false;
+    return equalsSuperficially(that) && myUnknownVariables.equals(that.myUnknownVariables) && equalsByRelations(that);
+  }
 
-    if (!myStack.equals(that.myStack)) return false;
-    if (!myOffsetStack.equals(that.myOffsetStack)) return false;
-    if (!myVariableStates.equals(that.myVariableStates)) return false;
-    if (!myUnknownVariables.equals(that.myUnknownVariables)) return false;
-    
+  boolean equalsSuperficially(DfaMemoryStateImpl other) {
+    return myEphemeral == other.myEphemeral && myStack.equals(other.myStack) && myOffsetStack.equals(other.myOffsetStack);
+  }
+
+  boolean equalsByRelations(DfaMemoryStateImpl that) {
+    if (myDistinctClasses.size() != that.myDistinctClasses.size()) return false;
     if (!getNonTrivialEqClasses().equals(that.getNonTrivialEqClasses())) return false;
     if (!getDistinctClassPairs().equals(that.getDistinctClassPairs())) return false;
-
+    if (!myVariableStates.equals(that.myVariableStates)) return false;
     return true;
   }
 
-  private Set<Set<SortedIntSet>> getDistinctClassPairs() {
-    Set<Set<SortedIntSet>> result = ContainerUtil.newHashSet();
+  private Set<UnorderedPair<EqClass>> myCachedDistinctClassPairs;
+  Set<UnorderedPair<EqClass>> getDistinctClassPairs() {
+    if (myCachedDistinctClassPairs != null) return myCachedDistinctClassPairs;
+
+    Set<UnorderedPair<EqClass>> result = ContainerUtil.newHashSet();
     for (long encodedPair : myDistinctClasses.toArray()) {
-      THashSet<SortedIntSet> pair = new THashSet<SortedIntSet>(2);
-      pair.add(myEqClasses.get(low(encodedPair)));
-      pair.add(myEqClasses.get(high(encodedPair)));
-      result.add(pair);
+      result.add(new UnorderedPair<EqClass>(myEqClasses.get(low(encodedPair)), myEqClasses.get(high(encodedPair))));
     }
-    return result;
+    return myCachedDistinctClassPairs = result;
   }
 
-  private Set<SortedIntSet> getNonTrivialEqClasses() {
-    Set<SortedIntSet> result = ContainerUtil.newHashSet();
-    for (SortedIntSet eqClass : myEqClasses) {
+  private Set<EqClass> myCachedNonTrivialEqClasses;
+  Set<EqClass> getNonTrivialEqClasses() {
+    if (myCachedNonTrivialEqClasses != null) return myCachedNonTrivialEqClasses;
+    
+    Set<EqClass> result = ContainerUtil.newHashSet();
+    for (EqClass eqClass : myEqClasses) {
       if (eqClass != null && eqClass.size() > 1) {
         result.add(eqClass);
       }
     }
-    return result;
+    return myCachedNonTrivialEqClasses = result;
   }
 
   public int hashCode() {
-    return 0;
-    //return ((myEqClasses.hashCode() * 31 + myStack.hashCode()) * 31 + myVariableStates.hashCode()) * 31 + myUnknownVariables.hashCode();
-  }
-
-  private void appendClass(StringBuilder buf, @Nullable SortedIntSet aClass) {
-    if (aClass == null) return;
-    
-    buf.append("(");
-
-    for (int i = 0; i < aClass.size(); i++) {
-      if (i > 0) buf.append(", ");
-      int value = aClass.get(i);
-      DfaValue dfaValue = myFactory.getValue(value);
-      buf.append(dfaValue);
-    }
-    buf.append(")");
+    return (((getNonTrivialEqClasses().hashCode() * 31 + 
+              getDistinctClassPairs().hashCode()) * 31 + 
+             myStack.hashCode()) * 31 + 
+            myUnknownVariables.hashCode()) * 31 + 
+           myVariableStates.hashCode();
   }
 
   @SuppressWarnings({"HardCodedStringLiteral"})
   public String toString() {
     StringBuilder result = new StringBuilder();
     result.append('<');
+    if (myEphemeral) {
+      result.append("ephemeral, ");
+    }
 
-    for (SortedIntSet set : getNonTrivialEqClasses()) {
-      appendClass(result, set);
+    for (EqClass set : getNonTrivialEqClasses()) {
+      result.append(set);
     }
 
     if (!myDistinctClasses.isEmpty()) {
       result.append("\n  distincts: ");
       List<String> distincts = new ArrayList<String>();
-      for (Set<SortedIntSet> pair : getDistinctClassPairs()) {
-        ArrayList<SortedIntSet> list = new ArrayList<SortedIntSet>(pair);
-        StringBuilder one = new StringBuilder();
-        one.append("{");
-        appendClass(one, list.get(0));
-        one.append(", ");
-        appendClass(one, list.get(1));
-        one.append("}");
-        distincts.add(one.toString());
+      for (UnorderedPair<EqClass> pair : getDistinctClassPairs()) {
+        distincts.add("{" + pair.first + ", " + pair.second + "}");
       }
       Collections.sort(distincts);
       result.append(StringUtil.join(distincts, " "));
@@ -174,7 +168,7 @@
     if (!myVariableStates.isEmpty()) {
       result.append("\n  vars: ");
       for (Map.Entry<DfaVariableValue, DfaVariableState> entry : myVariableStates.entrySet()) {
-        result.append("\n[").append(entry.getKey()).append("->").append(entry.getValue()).append("]");
+        result.append("[").append(entry.getKey()).append("->").append(entry.getValue()).append("] ");
       }
     }
     if (!myUnknownVariables.isEmpty()) {
@@ -201,11 +195,13 @@
 
   @Override
   public int popOffset() {
+    myOffsetStack = new TIntStack(myOffsetStack);
     return myOffsetStack.pop();
   }
 
   @Override
   public void pushOffset(int offset) {
+    myOffsetStack = new TIntStack(myOffsetStack);
     myOffsetStack.push(offset);
   }
 
@@ -220,13 +216,13 @@
 
     flushVariable(var);
     if (value instanceof DfaUnknownValue) {
-      getVariableState(var).setNullable(false);
+      setVariableState(var, getVariableState(var).withNullable(false));
       return;
     }
 
-    getVariableState(var).setValue(value);
+    setVariableState(var, getVariableState(var).withValue(value));
     if (value instanceof DfaTypeValue) {
-      getVariableState(var).setNullable(((DfaTypeValue)value).isNullable());
+      setVariableState(var, getVariableState(var).withNullable(((DfaTypeValue)value).isNullable()));
       DfaRelationValue dfaInstanceof = myFactory.getRelationFactory().createRelation(var, value, JavaTokenType.INSTANCEOF_KEYWORD, false);
       if (((DfaTypeValue)value).isNotNull()) {
         applyCondition(dfaInstanceof);
@@ -240,10 +236,10 @@
       applyCondition(dfaEqual);
 
       if (value instanceof DfaVariableValue) {
-        myVariableStates.put(var, getVariableState((DfaVariableValue)value).clone());
+        setVariableState(var, getVariableState((DfaVariableValue)value));
       }
       else if (value instanceof DfaBoxedValue) {
-        getVariableState(var).setNullable(false);
+        setVariableState(var, getVariableState(var).withNullable(false));
         applyCondition(compareToNull(var, true));
       }
     }
@@ -260,7 +256,7 @@
     if (!canBeReused(dfaValue) && !(((DfaBoxedValue)dfaValue).getWrappedValue() instanceof DfaConstValue)) {
       return null;
     }
-    SortedIntSet aClass = new SortedIntSet();
+    EqClass aClass = new EqClass(myFactory);
     aClass.add(dfaValue.getID());
     myEqClasses.add(aClass);
 
@@ -270,20 +266,11 @@
   @NotNull
   private List<DfaValue> getEqClassesFor(@NotNull DfaValue dfaValue) {
     int index = getEqClassIndex(dfaValue);
-    SortedIntSet set = index == -1 ? null : myEqClasses.get(index);
+    EqClass set = index == -1 ? null : myEqClasses.get(index);
     if (set == null) {
       return Collections.emptyList();
     }
-    final List<DfaValue> result = new ArrayList<DfaValue>(set.size());
-    set.forEach(new TIntProcedure() {
-      @Override
-      public boolean execute(int c1) {
-        DfaValue value = myFactory.getValue(c1);
-        result.add(value);
-        return true;
-      }
-    });
-    return result;
+    return set.getMemberValues();
   }
 
   private boolean canBeNaN(@NotNull DfaValue dfaValue) {
@@ -309,7 +296,7 @@
 
   private int getEqClassIndex(@NotNull DfaValue dfaValue) {
     for (int i = 0; i < myEqClasses.size(); i++) {
-      SortedIntSet aClass = myEqClasses.get(i);
+      EqClass aClass = myEqClasses.get(i);
       if (aClass != null && aClass.contains(dfaValue.getID())) {
         if (!canBeReused(dfaValue) && aClass.size() > 1) return -1;
         return i;
@@ -368,8 +355,8 @@
   }
 
   private boolean uniteClasses(int c1Index, int c2Index) {
-    SortedIntSet c1 = myEqClasses.get(c1Index);
-    SortedIntSet c2 = myEqClasses.get(c2Index);
+    EqClass c1 = myEqClasses.get(c1Index);
+    EqClass c2 = myEqClasses.get(c2Index);
 
     Set<DfaVariableValue> vars = ContainerUtil.newTroveSet();
     Set<DfaVariableValue> negatedVars = ContainerUtil.newTroveSet();
@@ -379,15 +366,14 @@
 
     int nConst = 0;
     for (int c : cs) {
-      DfaValue dfaValue = myFactory.getValue(c);
-      if (dfaValue instanceof DfaBoxedValue) dfaValue = ((DfaBoxedValue)dfaValue).getWrappedValue();
-      if (dfaValue instanceof DfaUnboxedValue) dfaValue = ((DfaUnboxedValue)dfaValue).getVariable();
+      DfaValue dfaValue = unwrap(myFactory.getValue(c));
       if (dfaValue instanceof DfaConstValue) nConst++;
       if (dfaValue instanceof DfaVariableValue) {
         DfaVariableValue variableValue = (DfaVariableValue)dfaValue;
         if (variableValue.isNegated()) {
           negatedVars.add(variableValue.createNegated());
-        } else {
+        }
+        else {
           vars.add(variableValue);
         }
       }
@@ -412,6 +398,7 @@
       }
     }
 
+    myEqClasses.set(c1Index, c1 = new EqClass(c1));
     for (int i = 0; i < c2.size(); i++) {
       int c = c2.get(i);
       c1.add(c);
@@ -458,7 +445,7 @@
   public boolean isNull(DfaValue dfaValue) {
     if (dfaValue instanceof DfaTypeValue && ((DfaTypeValue)dfaValue).isNotNull()) return false;
     
-    if (dfaValue instanceof DfaConstValue) return ((DfaConstValue)dfaValue).getConstant() == null;
+    if (dfaValue instanceof DfaConstValue) return ((DfaConstValue)dfaValue).getValue() == null;
 
     if (dfaValue instanceof DfaVariableValue) {
       int c1Index = getEqClassIndex(dfaValue);
@@ -495,33 +482,47 @@
   @Override
   @Nullable
   public DfaConstValue getConstantValue(DfaVariableValue value) {
-    DfaConstValue result = null;
-    for (DfaValue equal : getEqClassesFor(value)) {
-      if (equal instanceof DfaVariableValue) continue;
-      DfaConstValue constValue = asConstantValue(equal);
-      if (constValue == null) return null;
-      result = constValue;
-    }
-    return result;
+    int index = getEqClassIndex(value);
+    EqClass ec = index == -1 ? null : myEqClasses.get(index);
+    return ec == null ? null : ec.findConstant(true);
+  }
+
+  @Override
+  public void markEphemeral() {
+    myEphemeral = true;
+  }
+
+  @Override
+  public boolean isEphemeral() {
+    return myEphemeral;
   }
 
   @Override
   public boolean applyInstanceofOrNull(DfaRelationValue dfaCond) {
-    DfaValue left = dfaCond.getLeftOperand();
-    if (left instanceof DfaBoxedValue) {
-      left = ((DfaBoxedValue)left).getWrappedValue();
-    }
-    else if (left instanceof DfaUnboxedValue) {
-      left = ((DfaUnboxedValue)left).getVariable();
-    }
+    DfaValue left = unwrap(dfaCond.getLeftOperand());
 
     if (!(left instanceof DfaVariableValue)) return true;
 
     DfaVariableValue dfaVar = (DfaVariableValue)left;
     DfaTypeValue dfaType = (DfaTypeValue)dfaCond.getRightOperand();
 
-    final DfaVariableState varState = getVariableState(dfaVar);
-    return isNull(dfaVar) || varState.setInstanceofValue(dfaType);
+    if (isUnknownState(dfaVar) || isNull(dfaVar)) return true;
+    DfaVariableState newState = getVariableState(dfaVar).withInstanceofValue(dfaType);
+    if (newState != null) {
+      setVariableState(dfaVar, newState);
+      return true;
+    }
+    return false;
+  }
+
+  static DfaValue unwrap(DfaValue value) {
+    if (value instanceof DfaBoxedValue) {
+      return ((DfaBoxedValue)value).getWrappedValue();
+    }
+    else if (value instanceof DfaUnboxedValue) {
+      return ((DfaUnboxedValue)value).getVariable();
+    }
+    return value;
   }
 
   @Override
@@ -563,12 +564,25 @@
 
     if (dfaRight instanceof DfaTypeValue) {
       if (dfaLeft instanceof DfaVariableValue) {
-        DfaVariableState varState = getVariableState((DfaVariableValue)dfaLeft);
         DfaVariableValue dfaVar = (DfaVariableValue)dfaLeft;
+        if (isUnknownState(dfaVar)) return true;
+        
         if (isNegated) {
-          return varState.addNotInstanceofValue((DfaTypeValue)dfaRight) || applyCondition(compareToNull(dfaVar, false));
+          DfaVariableState newState = getVariableState(dfaVar).withNotInstanceofValue((DfaTypeValue)dfaRight);
+          if (newState != null) {
+            setVariableState(dfaVar, newState);
+            return true;
+          }
+          return applyCondition(compareToNull(dfaVar, false));
         }
-        return applyCondition(compareToNull(dfaVar, true)) && varState.setInstanceofValue((DfaTypeValue)dfaRight);
+        if (applyCondition(compareToNull(dfaVar, true))) {
+          DfaVariableState newState = getVariableState(dfaVar).withInstanceofValue((DfaTypeValue)dfaRight);
+          if (newState != null) {
+            setVariableState(dfaVar, newState);
+            return true;
+          }
+        }
+        return false;
       }
       return true;
     }
@@ -595,7 +609,9 @@
       if (isNotNull(dfaVar)) {
         return true;
       }
-      getVariableState(dfaVar).setNullable(true);
+      if (!isUnknownState(dfaVar)) {
+        setVariableState(dfaVar, getVariableState(dfaVar).withNullability(Nullness.NULLABLE));
+      }
     }
     return false;
   }
@@ -637,7 +653,7 @@
     if (!TypeConversionUtil.isPrimitiveWrapper(type)) {
       return true;
     }
-    if (negated && !isMaybeBoxedConstant(dfaRight)) {
+    if (negated && !(unwrap(dfaRight) instanceof DfaConstValue)) {
       // from the fact (wrappers are not the same) does not follow (unboxed values are not equals)
       return true;
     }
@@ -646,11 +662,6 @@
     return applyRelation(boxedFactory.createUnboxed(dfaLeft), boxedFactory.createUnboxed(dfaRight), negated);
   }
 
-  private static boolean isMaybeBoxedConstant(DfaValue val) {
-    return val instanceof DfaConstValue ||
-           val instanceof DfaBoxedValue && ((DfaBoxedValue)val).getWrappedValue() instanceof DfaConstValue;
-  }
-
   private boolean checkCompareWithBooleanLiteral(DfaValue dfaLeft, DfaValue dfaRight, boolean negated) {
     if (dfaRight instanceof DfaConstValue) {
       Object constVal = ((DfaConstValue)dfaRight).getValue();
@@ -691,18 +702,28 @@
     if (!isNegated) { //Equals
       if (c1Index.equals(c2Index)) return true;
       if (!uniteClasses(c1Index, c2Index)) return false;
+
+      for (long encodedPair : myDistinctClasses.toArray()) {
+        EqClass c1 = myEqClasses.get(low(encodedPair));
+        EqClass c2 = myEqClasses.get(high(encodedPair));
+        if (c1.findConstant(false) != null && c2.findConstant(false) != null) {
+          myDistinctClasses.remove(encodedPair);
+        }
+      }
+      myCachedDistinctClassPairs = null;
+      myCachedNonTrivialEqClasses = null;
     }
     else { // Not Equals
       if (c1Index.equals(c2Index)) return false;
       makeClassesDistinct(c1Index, c2Index);
+      myCachedDistinctClassPairs = null;
     }
 
     return true;
   }
 
   private boolean isUnknownState(DfaValue val) {
-    if (val instanceof DfaBoxedValue) return isUnknownState(((DfaBoxedValue)val).getWrappedValue());
-    if (val instanceof DfaUnboxedValue) return isUnknownState(((DfaUnboxedValue)val).getVariable());
+    val = unwrap(val);
     if (val instanceof DfaVariableValue) {
       if (myUnknownVariables.contains(val)) return true;
       DfaVariableValue negatedValue = ((DfaVariableValue)val).getNegatedValue();
@@ -731,17 +752,33 @@
     return myFactory.getRelationFactory().createRelation(dfaVar, dfaNull, JavaTokenType.EQEQ, negated);
   }
 
+  void setVariableState(DfaVariableValue dfaVar, DfaVariableState state) {
+    assert !myUnknownVariables.contains(dfaVar);
+    if (state.equals(myDefaultVariableStates.get(dfaVar))) {
+      myVariableStates.remove(dfaVar);
+    } else {
+      myVariableStates.put(dfaVar, state);
+    }
+  }
+  
   public DfaVariableState getVariableState(DfaVariableValue dfaVar) {
     DfaVariableState state = myVariableStates.get(dfaVar);
 
     if (state == null) {
-      state = createVariableState(dfaVar);
-      if (isUnknownState(dfaVar)) {
-        state.setNullable(false);
-        return state;
+      state = myDefaultVariableStates.get(dfaVar);
+      if (state == null) {
+        state = createVariableState(dfaVar);
+        DfaTypeValue initialType = dfaVar.getTypeValue();
+        if (initialType != null) {
+          state = state.withInstanceofValue(initialType);
+          assert state != null;
+        }
+        myDefaultVariableStates.put(dfaVar, state);
       }
-
-      myVariableStates.put(dfaVar, state);
+      
+      if (isUnknownState(dfaVar)) {
+        return state.withNullable(false);
+      }
     }
 
     return state;
@@ -757,28 +794,25 @@
 
   @Override
   public void flushFields(DfaVariableValue[] fields) {
-    Set<DfaVariableValue> allVars = new HashSet<DfaVariableValue>(myVariableStates.keySet());
-    Collections.addAll(allVars, fields);
-
-    Set<DfaVariableValue> dependencies  = new HashSet<DfaVariableValue>();
-    for (DfaVariableValue variableValue : allVars) {
-      dependencies.addAll(myFactory.getVarFactory().getAllQualifiedBy(variableValue));
-    }
-    allVars.addAll(dependencies);
-
-    for (DfaVariableValue value : allVars) {
-      if (myVariableStates.containsKey(value) || getEqClassIndex(value) >= 0) {
-        if (value.isFlushableByCalls()) {
-          doFlush(value);
-          myUnknownVariables.add(value);
+    for (EqClass aClass : myEqClasses) {
+      if (aClass != null) {
+        for (DfaVariableValue value : aClass.getVariables()) {
+          if (value.isFlushableByCalls()) {
+            doFlush(value, true);
+          }
         }
       }
     }
+    for (DfaVariableValue value : new ArrayList<DfaVariableValue>(myVariableStates.keySet())) {
+      if (value.isFlushableByCalls()) {
+        doFlush(value, true);
+      }
+    }
   }
 
   @Override
   public void flushVariable(@NotNull DfaVariableValue variable) {
-    doFlush(variable);
+    doFlush(variable, false);
     flushDependencies(variable);
     myUnknownVariables.remove(variable);
     myUnknownVariables.removeAll(myFactory.getVarFactory().getAllQualifiedBy(variable));
@@ -786,11 +820,15 @@
 
   public void flushDependencies(DfaVariableValue variable) {
     for (DfaVariableValue dependent : myFactory.getVarFactory().getAllQualifiedBy(variable)) {
-      doFlush(dependent);
+      doFlush(dependent, false);
     }
   }
 
-  private void doFlush(DfaVariableValue varPlain) {
+  Set<DfaVariableValue> getUnknownVariables() {
+    return myUnknownVariables;
+  }
+
+  void doFlush(DfaVariableValue varPlain, boolean markUnknown) {
     DfaVariableValue varNegated = varPlain.getNegatedValue();
 
     final int idPlain = varPlain.getID();
@@ -799,7 +837,7 @@
     int size = myEqClasses.size();
     int interruptCount = 0;
     for (int varClassIndex = 0; varClassIndex < size; varClassIndex++) {
-      final SortedIntSet varClass = myEqClasses.get(varClassIndex);
+      EqClass varClass = myEqClasses.get(varClassIndex);
       if (varClass == null) continue;
 
       for (int i = 0; i < varClass.size(); i++) {
@@ -809,6 +847,7 @@
         int cl = varClass.get(i);
         DfaValue value = myFactory.getValue(cl);
         if (mine(idPlain, value) || idNegated >= 0 && mine(idNegated, value)) {
+          myEqClasses.set(varClassIndex, varClass = new EqClass(varClass));
           varClass.remove(i);
           break;
         }
@@ -823,10 +862,10 @@
           }
         }
       }
-      else if (containsConstantsOnly(varClassIndex)) {
+      else if (varClass.containsConstantsOnly()) {
         for (long pair : myDistinctClasses.toArray()) {
-          if (low(pair) == varClassIndex && containsConstantsOnly(high(pair)) ||
-              high(pair) == varClassIndex && containsConstantsOnly(low(pair))) {
+          if (low(pair) == varClassIndex && myEqClasses.get(high(pair)).containsConstantsOnly() ||
+              high(pair) == varClassIndex && myEqClasses.get(low(pair)).containsConstantsOnly()) {
             myDistinctClasses.remove(pair);
           }
         }
@@ -837,28 +876,14 @@
     if (varNegated != null) {
       myVariableStates.remove(varNegated);
     }
-  }
-
-  @Nullable private static DfaConstValue asConstantValue(DfaValue value) {
-    if (value instanceof DfaConstValue) return (DfaConstValue)value;
-    if (value instanceof DfaBoxedValue && ((DfaBoxedValue)value).getWrappedValue() instanceof DfaConstValue) return (DfaConstValue)((DfaBoxedValue)value).getWrappedValue();
-    return null;
-  }
-
-  private boolean containsConstantsOnly(int id) {
-    SortedIntSet varClass = myEqClasses.get(id);
-    for (int i = 0; i < varClass.size(); i++) {
-      if (asConstantValue(myFactory.getValue(varClass.get(i))) == null) {
-        return false;
-      }
+    if (markUnknown) {
+      myUnknownVariables.add(varPlain);
     }
-
-    return true;
+    myCachedNonTrivialEqClasses = null;
+    myCachedDistinctClassPairs = null;
   }
 
   private static boolean mine(int id, DfaValue value) {
-    return value != null && id == value.getID() ||
-        value instanceof DfaBoxedValue && ((DfaBoxedValue)value).getWrappedValue().getID() == id ||
-        value instanceof DfaUnboxedValue && ((DfaUnboxedValue)value).getVariable().getID() == id;
+    return value != null && id == unwrap(value).getID();
   }
 }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java
index 3b493d4..8ed7836 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java
@@ -37,9 +37,6 @@
 import java.util.Set;
 
 public class DfaPsiUtil {
-  public static boolean isPlainMutableField(PsiVariable var) {
-    return !var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && !var.hasModifierProperty(PsiModifier.VOLATILE) && var instanceof PsiField;
-  }
 
   public static boolean isFinalField(PsiVariable var) {
     return var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && var instanceof PsiField;
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
index 8c3cce8..16a2a6d 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
@@ -163,9 +163,10 @@
     }
 
     @Override
-    public DfaInstructionState[] visitAssign(AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
+    public DfaInstructionState[] visitAssign(AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState _memState) {
       final Instruction nextInstruction = runner.getInstruction(instruction.getIndex() + 1);
 
+      ValuableDataFlowRunner.MyDfaMemoryState memState = (ValuableDataFlowRunner.MyDfaMemoryState)_memState;
       final DfaValue dfaSource = memState.pop();
       final DfaValue dfaDest = memState.pop();
 
@@ -176,10 +177,10 @@
         final IElementType type = parent instanceof PsiAssignmentExpression
                                   ? ((PsiAssignmentExpression)parent).getOperationTokenType() : JavaTokenType.EQ;
         // store current value - to use in case of '+='
-        final PsiExpression prevValue = ((ValuableDataFlowRunner.ValuableDfaVariableState)((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableState(var)).myExpression;
+        final PsiExpression prevValue = ((ValuableDataFlowRunner.ValuableDfaVariableState)memState.getVariableState(var)).myExpression;
         memState.setVarValue(var, dfaSource);
         // state may have been changed so re-retrieve it
-        final ValuableDataFlowRunner.ValuableDfaVariableState curState = (ValuableDataFlowRunner.ValuableDfaVariableState)((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableState(var);
+        final ValuableDataFlowRunner.ValuableDfaVariableState curState = (ValuableDataFlowRunner.ValuableDfaVariableState)memState.getVariableState(var);
         final PsiExpression curValue = curState.myExpression;
         final PsiExpression nextValue;
         if (type == JavaTokenType.PLUSEQ && prevValue != null) {
@@ -196,7 +197,7 @@
         else {
           nextValue = curValue == null ? rightValue : curValue;
         }
-        curState.myExpression = nextValue;
+        memState.setVariableState(var, curState.withExpression(nextValue));
       }
       memState.push(dfaDest);
       return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, memState)};
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
index 8173822..61d61c2 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
@@ -24,138 +24,134 @@
  */
 package com.intellij.codeInspection.dataFlow;
 
+import com.intellij.codeInspection.dataFlow.value.DfaPsiType;
 import com.intellij.codeInspection.dataFlow.value.DfaTypeValue;
 import com.intellij.codeInspection.dataFlow.value.DfaValue;
 import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
-import com.intellij.psi.*;
-import gnu.trove.THashSet;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiPrimitiveType;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.Collections;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Set;
 
-public class DfaVariableState implements Cloneable {
-  private final Set<DfaTypeValue> myInstanceofValues;
-  private final Set<DfaTypeValue> myNotInstanceofValues;
-  private Nullness myNullability;
+public class DfaVariableState {
+  protected final Set<DfaPsiType> myInstanceofValues;
+  protected final Set<DfaPsiType> myNotInstanceofValues;
+  protected final Nullness myNullability;
 
   public DfaVariableState(@NotNull DfaVariableValue dfaVar) {
-    myInstanceofValues = new HashSet<DfaTypeValue>();
-    myNotInstanceofValues = new HashSet<DfaTypeValue>();
-
-    myNullability = dfaVar.getInherentNullability();
-    DfaTypeValue initialType = dfaVar.getTypeValue();
-    if (initialType != null) {
-      setInstanceofValue(initialType);
-    }
+    this(Collections.<DfaPsiType>emptySet(), Collections.<DfaPsiType>emptySet(), dfaVar.getInherentNullability());
   }
 
-  protected DfaVariableState(final DfaVariableState toClone) {
-    myInstanceofValues = new THashSet<DfaTypeValue>(toClone.myInstanceofValues);
-    myNotInstanceofValues = new THashSet<DfaTypeValue>(toClone.myNotInstanceofValues);
-    myNullability = toClone.myNullability;
+  protected DfaVariableState(Set<DfaPsiType> instanceofValues,
+                          Set<DfaPsiType> notInstanceofValues, Nullness nullability) {
+    myInstanceofValues = instanceofValues;
+    myNotInstanceofValues = notInstanceofValues;
+    myNullability = nullability;
   }
 
   public boolean isNullable() {
     return myNullability == Nullness.NULLABLE;
   }
 
-  private boolean checkInstanceofValue(DfaTypeValue dfaType) {
+  private boolean checkInstanceofValue(DfaPsiType dfaType) {
     if (myInstanceofValues.contains(dfaType)) return true;
 
-    for (DfaTypeValue dfaTypeValue : myNotInstanceofValues) {
+    for (DfaPsiType dfaTypeValue : myNotInstanceofValues) {
       if (dfaTypeValue.isAssignableFrom(dfaType)) return false;
     }
 
-    for (DfaTypeValue dfaTypeValue : myInstanceofValues) {
+    for (DfaPsiType dfaTypeValue : myInstanceofValues) {
       if (!dfaType.isConvertibleFrom(dfaTypeValue)) return false;
     }
 
     return true;
   }
 
-  public boolean setInstanceofValue(DfaTypeValue dfaType) {
-    if (dfaType.isNullable()) {
-      myNullability = Nullness.NULLABLE;
+  @Nullable
+  public DfaVariableState withInstanceofValue(DfaTypeValue dfaType) {
+    if (dfaType.getDfaType().getPsiType() instanceof PsiPrimitiveType) return this;
+    
+    if (checkInstanceofValue(dfaType.getDfaType())) {
+      DfaVariableState result = dfaType.isNullable() ? withNullability(Nullness.NULLABLE) : this;
+      if (!myInstanceofValues.contains(dfaType.getDfaType())) {
+        HashSet<DfaPsiType> newInstanceof = ContainerUtil.newHashSet(myInstanceofValues);
+        newInstanceof.add(dfaType.getDfaType());
+        result = createCopy(newInstanceof, myNotInstanceofValues, result.myNullability);
+      }
+      return result;
     }
 
-    if (dfaType.getType() instanceof PsiPrimitiveType) return true;
-
-    if (checkInstanceofValue(dfaType)) {
-      myInstanceofValues.add(dfaType);
-      return true;
-    }
-
-    return false;
+    return null;
   }
 
-  public boolean addNotInstanceofValue(DfaTypeValue dfaType) {
-    if (myNotInstanceofValues.contains(dfaType)) return true;
+  @Nullable
+  public DfaVariableState withNotInstanceofValue(DfaTypeValue dfaType) {
+    if (myNotInstanceofValues.contains(dfaType.getDfaType())) return this;
 
-    for (DfaTypeValue dfaTypeValue : myInstanceofValues) {
-      if (dfaType.isAssignableFrom(dfaTypeValue)) return false;
+    for (DfaPsiType dfaTypeValue : myInstanceofValues) {
+      if (dfaType.getDfaType().isAssignableFrom(dfaTypeValue)) return null;
     }
 
-    myNotInstanceofValues.add(dfaType);
-    return true;
+    HashSet<DfaPsiType> newNotInstanceof = ContainerUtil.newHashSet(myNotInstanceofValues);
+    newNotInstanceof.add(dfaType.getDfaType());
+    return createCopy(myInstanceofValues, newNotInstanceof, myNullability);
   }
 
   public int hashCode() {
-    return myInstanceofValues.hashCode() + myNotInstanceofValues.hashCode();
+    return (myInstanceofValues.hashCode() * 31 + myNotInstanceofValues.hashCode()) * 31 + myNullability.hashCode();
   }
 
   public boolean equals(Object obj) {
     if (obj == this) return true;
     if (!(obj instanceof DfaVariableState)) return false;
     DfaVariableState aState = (DfaVariableState) obj;
-    return myInstanceofValues.equals(aState.myInstanceofValues) &&
-           myNotInstanceofValues.equals(aState.myNotInstanceofValues) &&
-           myNullability == aState.myNullability;
+    return myNullability == aState.myNullability &&
+           myInstanceofValues.equals(aState.myInstanceofValues) &&
+           myNotInstanceofValues.equals(aState.myNotInstanceofValues);
   }
 
-  @Override
-  protected DfaVariableState clone() {
-    return new DfaVariableState(this);
+  protected DfaVariableState createCopy(Set<DfaPsiType> instanceofValues, Set<DfaPsiType> notInstanceofValues, Nullness nullability) {
+    return new DfaVariableState(instanceofValues, notInstanceofValues, nullability);
   }
 
   public String toString() {
     @NonNls StringBuilder buf = new StringBuilder();
 
+    buf.append(myNullability);
     if (!myInstanceofValues.isEmpty()) {
-      buf.append("instanceof ");
-      for (Iterator<DfaTypeValue> iterator = myInstanceofValues.iterator(); iterator.hasNext();) {
-        DfaTypeValue dfaTypeValue = iterator.next();
-        buf.append("{").append(dfaTypeValue).append("}");
-        if (iterator.hasNext()) buf.append(", ");
-      }
+      buf.append(" instanceof ").append(StringUtil.join(myInstanceofValues, ","));
     }
 
     if (!myNotInstanceofValues.isEmpty()) {
-      buf.append("not instanceof ");
-      for (Iterator<DfaTypeValue> iterator = myNotInstanceofValues.iterator(); iterator.hasNext();) {
-        DfaTypeValue dfaTypeValue = iterator.next();
-        buf.append("{").append(dfaTypeValue).append("}");
-        if (iterator.hasNext()) buf.append(", ");
-      }
+      buf.append(" not instanceof ").append(StringUtil.join(myNotInstanceofValues, ","));
     }
-    buf.append(myNullability);
     return buf.toString();
   }
 
+  public Nullness getNullability() {
+    return myNullability;
+  }
+
   public boolean isNotNull() {
     return myNullability == Nullness.NOT_NULL;
   }
 
-  public void setNullable(final boolean nullable) {
-    if (myNullability != Nullness.NOT_NULL) {
-      myNullability = nullable ? Nullness.NULLABLE : Nullness.UNKNOWN;
-    }
+  DfaVariableState withNullability(@NotNull Nullness nullness) {
+    return myNullability == nullness ? this : createCopy(myInstanceofValues, myNotInstanceofValues, nullness);
   }
 
-  public void setValue(DfaValue value) {
+  public DfaVariableState withNullable(final boolean nullable) {
+    return myNullability != Nullness.NOT_NULL ? withNullability(nullable ? Nullness.NULLABLE : Nullness.UNKNOWN) : this;
+  }
+
+  public DfaVariableState withValue(DfaValue value) {
+    return this;
   }
 
   @Nullable
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/EqClass.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/EqClass.java
new file mode 100644
index 0000000..c6fc621
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/EqClass.java
@@ -0,0 +1,111 @@
+/*
+ * 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.codeInspection.dataFlow;
+
+import com.intellij.codeInspection.dataFlow.value.DfaConstValue;
+import com.intellij.codeInspection.dataFlow.value.DfaValue;
+import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
+import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
+import com.intellij.util.containers.ContainerUtil;
+import gnu.trove.TIntProcedure;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author peter
+ */
+class EqClass extends SortedIntSet {
+  private final DfaValueFactory myFactory;
+
+  EqClass(DfaValueFactory factory) {
+    myFactory = factory;
+  }
+
+  EqClass(EqClass toCopy) {
+    super(toCopy.toNativeArray());
+    myFactory = toCopy.myFactory;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder buf = new StringBuilder();
+    buf.append("(");
+    for (int i = 0; i < size(); i++) {
+      if (i > 0) buf.append(", ");
+      int value = get(i);
+      DfaValue dfaValue = myFactory.getValue(value);
+      buf.append(dfaValue);
+    }
+    buf.append(")");
+    return buf.toString();
+  }
+
+  List<DfaVariableValue> getVariables() {
+    List<DfaVariableValue> vars = ContainerUtil.newArrayList();
+    for (DfaValue value : getMemberValues()) {
+      value = DfaMemoryStateImpl.unwrap(value);
+      if (value instanceof DfaVariableValue) {
+        vars.add((DfaVariableValue)value);
+      }
+    }
+    return vars;
+  }
+
+  List<DfaValue> getMemberValues() {
+    final List<DfaValue> result = new ArrayList<DfaValue>(size());
+    forEach(new TIntProcedure() {
+      @Override
+      public boolean execute(int c1) {
+        DfaValue value = myFactory.getValue(c1);
+        result.add(value);
+        return true;
+      }
+    });
+    return result;
+  }
+
+  @Nullable
+  DfaConstValue findConstant(boolean wrapped) {
+    for (DfaValue value : getMemberValues()) {
+      if (wrapped) {
+        value = DfaMemoryStateImpl.unwrap(value);
+      }
+      if (value instanceof DfaConstValue) {
+        return (DfaConstValue)value;
+      }
+    }
+    return null;
+  }
+
+  @Nullable
+  private static DfaConstValue asConstantValue(DfaValue value) {
+    value = DfaMemoryStateImpl.unwrap(value);
+    return value instanceof DfaConstValue ? (DfaConstValue)value : null;
+  }
+
+  boolean containsConstantsOnly() {
+    for (int i = 0; i < size(); i++) {
+      if (asConstantValue(myFactory.getValue(get(i))) == null) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityProblem.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityProblem.java
new file mode 100644
index 0000000..8155149
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityProblem.java
@@ -0,0 +1,14 @@
+package com.intellij.codeInspection.dataFlow;
+
+/**
+ * @author peter
+ */
+public enum NullabilityProblem {
+  callNPE,
+  fieldAccessNPE,
+  unboxingNullable,
+  assigningToNotNull,
+  nullableReturn,
+  passingNullableToNotNullParameter,
+  passingNullableArgumentToNonAnnotatedParameter,
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java
index b7fc6c7..2d6ee1b 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java
@@ -27,36 +27,23 @@
 import com.intellij.codeInsight.NullableNotNullManager;
 import com.intellij.codeInspection.dataFlow.instructions.InstanceofInstruction;
 import com.intellij.codeInspection.dataFlow.instructions.Instruction;
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Pair;
-import com.intellij.psi.*;
-import gnu.trove.THashSet;
+import com.intellij.psi.CommonClassNames;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiType;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.HashSet;
 import java.util.Set;
 
 public class StandardDataFlowRunner extends DataFlowRunner {
-  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DataFlowRunner");
-
-  private final Set<Instruction> myNPEInstructions = new HashSet<Instruction>();
   private final Set<Instruction> myCCEInstructions = new HashSet<Instruction>();
-  private final Set<PsiExpression> myNullableArguments = new HashSet<PsiExpression>();
-  private final Set<PsiExpression> myNullableArgumentsPassedToNonAnnotatedParam = new HashSet<PsiExpression>();
-  private final Set<PsiExpression> myNullableAssignments = new HashSet<PsiExpression>();
-  private final Set<PsiReturnStatement> myNullableReturns = new HashSet<PsiReturnStatement>();
 
-  private final boolean mySuggestNullableAnnotations;
   private boolean myInNullableMethod = false;
   private boolean myInNotNullMethod = false;
   private boolean myIsInMethod = false;
 
-  private final Set<PsiExpression> myUnboxedNullables = new THashSet<PsiExpression>();
-
-  public StandardDataFlowRunner(boolean suggestNullableAnnotations) {
-    mySuggestNullableAnnotations = suggestNullableAnnotations;
-  }
-
   @Override
   protected void prepareAnalysis(@NotNull PsiElement psiBlock, Iterable<DfaMemoryState> initialStates) {
     myIsInMethod = psiBlock.getParent() instanceof PsiMethod;
@@ -68,17 +55,7 @@
       myInNotNullMethod = NullableNotNullManager.isNotNull(method);
     }
 
-    myNPEInstructions.clear();
     myCCEInstructions.clear();
-    myNullableArguments.clear();
-    myNullableArgumentsPassedToNonAnnotatedParam.clear();
-    myNullableAssignments.clear();
-    myNullableReturns.clear();
-    myUnboxedNullables.clear();
-  }
-
-  public void onInstructionProducesNPE(Instruction instruction) {
-    myNPEInstructions.add(instruction);
   }
 
   public void onInstructionProducesCCE(Instruction instruction) {
@@ -89,74 +66,24 @@
     return myCCEInstructions;
   }
 
-  @NotNull public Set<Instruction> getNPEInstructions() {
-    return myNPEInstructions;
-  }
-
-  @NotNull public Set<PsiReturnStatement> getNullableReturns() {
-    return myNullableReturns;
-  }
-
   public boolean isInNotNullMethod() {
     return myInNotNullMethod;
   }
 
-  @NotNull public Set<PsiExpression> getNullableArguments() {
-    return myNullableArguments;
+  public boolean isInNullableMethod() {
+    return myInNullableMethod;
   }
 
-  public Set<PsiExpression> getNullableArgumentsPassedToNonAnnotatedParam() {
-    return myNullableArgumentsPassedToNonAnnotatedParam;
-  }
-
-  @NotNull public Set<PsiExpression> getNullableAssignments() {
-    return myNullableAssignments;
-  }
-
-  @NotNull public Set<PsiExpression> getUnboxedNullables() {
-    return myUnboxedNullables;
-  }
-
-  public void onUnboxingNullable(@NotNull PsiExpression expression) {
-    LOG.assertTrue(expression.isValid());
-    if (expression.isPhysical()) {
-      myUnboxedNullables.add(expression);
-    }
-  }
-
-  public void onPassingNullParameter(PsiExpression expr) {
-    myNullableArguments.add(expr);
-  }
-
-  public void onPassingNullParameterToNonAnnotated(PsiExpression expr) {
-    if (mySuggestNullableAnnotations) {
-      myNullableArgumentsPassedToNonAnnotatedParam.add(expr);
-    }
-  }
-
-  public void onAssigningToNotNullableVariable(final PsiExpression expr) {
-    myNullableAssignments.add(expr);
-  }
-
-  public void onNullableReturn(final PsiReturnStatement statement) {
-    if (myInNullableMethod || !myIsInMethod) return;
-    if (myInNotNullMethod || mySuggestNullableAnnotations) {
-      myNullableReturns.add(statement);
-    }
+  public boolean isInMethod() {
+    return myIsInMethod;
   }
 
   public boolean problemsDetected(StandardInstructionVisitor visitor) {
     final Pair<Set<Instruction>, Set<Instruction>> constConditions = getConstConditionalExpressions();
     return !constConditions.getFirst().isEmpty()
            || !constConditions.getSecond().isEmpty()
-           || !myNPEInstructions.isEmpty()
            || !myCCEInstructions.isEmpty()
-           || !getRedundantInstanceofs(this, visitor).isEmpty()
-           || !myNullableArguments.isEmpty()
-           || !myNullableArgumentsPassedToNonAnnotatedParam.isEmpty()
-           || !myNullableAssignments.isEmpty()
-           || !myNullableReturns.isEmpty()
-           || !myUnboxedNullables.isEmpty();
+           || !getRedundantInstanceofs(this, visitor).isEmpty();
   }
 
   @NotNull public static Set<Instruction> getRedundantInstanceofs(final DataFlowRunner runner, StandardInstructionVisitor visitor) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
index 3770e49..90a6490 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
@@ -115,17 +115,15 @@
 
     if (dfaDest instanceof DfaVariableValue) {
       DfaVariableValue var = (DfaVariableValue) dfaDest;
-      final PsiModifierListOwner psiVariable = var.getPsiVariable();
-      if (DfaPsiUtil.getElementNullability(var.getVariableType(), psiVariable) == Nullness.NOT_NULL) {
-        if (!memState.checkNotNullable(dfaSource)) {
-          onAssigningToNotNullableVariable(instruction);
-        }
+      if (var.getInherentNullability() == Nullness.NOT_NULL) {
+        checkNotNullable(memState, dfaSource, NullabilityProblem.assigningToNotNull, instruction.getRExpression());
       }
-      if (!(psiVariable instanceof PsiField) || !psiVariable.hasModifierProperty(PsiModifier.VOLATILE)) {
+      final PsiModifierListOwner psi = var.getPsiVariable();
+      if (!(psi instanceof PsiField) || !psi.hasModifierProperty(PsiModifier.VOLATILE)) {
         memState.setVarValue(var, dfaSource);
       }
-    } else if (dfaDest instanceof DfaTypeValue && ((DfaTypeValue)dfaDest).isNotNull() && !memState.checkNotNullable(dfaSource)) {
-      onAssigningToNotNullableVariable(instruction);
+    } else if (dfaDest instanceof DfaTypeValue && ((DfaTypeValue)dfaDest).isNotNull()) {
+      checkNotNullable(memState, dfaSource, NullabilityProblem.assigningToNotNull, instruction.getRExpression());
     }
 
     memState.push(dfaDest);
@@ -133,27 +131,19 @@
     return nextInstruction(instruction, runner, memState);
   }
 
-  protected void onAssigningToNotNullableVariable(AssignInstruction instruction) {}
-
   @Override
   public DfaInstructionState[] visitCheckReturnValue(CheckReturnValueInstruction instruction,
                                                      DataFlowRunner runner,
                                                      DfaMemoryState memState) {
     final DfaValue retValue = memState.pop();
-    if (!memState.checkNotNullable(retValue)) {
-      onNullableReturn(instruction);
-    }
+    checkNotNullable(memState, retValue, NullabilityProblem.nullableReturn, instruction.getReturn());
     return nextInstruction(instruction, runner, memState);
   }
 
-  protected void onNullableReturn(CheckReturnValueInstruction instruction) {}
-
   @Override
   public DfaInstructionState[] visitFieldReference(FieldReferenceInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
     final DfaValue qualifier = memState.pop();
-    if (!memState.checkNotNullable(qualifier)) {
-      onInstructionProducesNPE(instruction);
-
+    if (!checkNotNullable(memState, qualifier, NullabilityProblem.fieldAccessNPE, instruction.getElementToAssert())) {
       if (qualifier instanceof DfaVariableValue) {
         memState.setVarValue((DfaVariableValue)qualifier, runner.getFactory()
           .createTypeValue(((DfaVariableValue)qualifier).getVariableType(), Nullness.NOT_NULL));
@@ -194,7 +184,7 @@
     final DfaValueFactory factory = runner.getFactory();
     DfaValue dfaExpr = factory.createValue(instruction.getCasted());
     if (dfaExpr != null) {
-      DfaTypeValue dfaType = factory.getTypeFactory().createTypeValue(instruction.getCastTo());
+      DfaTypeValue dfaType = (DfaTypeValue)factory.createTypeValue(instruction.getCastTo(), Nullness.UNKNOWN);
       DfaRelationValue dfaInstanceof = factory.getRelationFactory().createRelation(dfaExpr, dfaType, JavaTokenType.INSTANCEOF_KEYWORD, false);
       if (dfaInstanceof != null && !memState.applyInstanceofOrNull(dfaInstanceof)) {
         onInstructionProducesCCE(instruction);
@@ -218,23 +208,24 @@
       final DfaValue arg = memState.pop();
       PsiExpression expr = args[(args.length - i - 1)];
       if (map.get(expr) == Nullness.NOT_NULL) {
-        if (!memState.checkNotNullable(arg)) {
-          onPassingNullParameter(expr);
+        if (!checkNotNullable(memState, arg, NullabilityProblem.passingNullableToNotNullParameter, expr)) {
           if (arg instanceof DfaVariableValue) {
             memState.setVarValue((DfaVariableValue)arg, runner.getFactory()
               .createTypeValue(((DfaVariableValue)arg).getVariableType(), Nullness.NOT_NULL));
           }
         }
       }
-      else if (map.get(expr) == Nullness.UNKNOWN && !memState.checkNotNullable(arg)) {
-        onPassingNullParameterToNonAnnotated(runner, expr);
+      else if (map.get(expr) == Nullness.UNKNOWN) {
+        checkNotNullable(memState, arg, NullabilityProblem.passingNullableArgumentToNonAnnotatedParameter, expr);
       }
     }
 
     @NotNull final DfaValue qualifier = memState.pop();
     try {
-      if (!memState.checkNotNullable(qualifier)) {
-        onInstructionProducesNPE(instruction);
+      boolean unboxing = instruction.getMethodType() == MethodCallInstruction.MethodType.UNBOXING;
+      NullabilityProblem problem = unboxing ? NullabilityProblem.unboxingNullable : NullabilityProblem.callNPE;
+      PsiExpression anchor = unboxing ? instruction.getContext() : instruction.getCallExpression();
+      if (!checkNotNullable(memState, qualifier, problem, anchor)) {
         if (qualifier instanceof DfaVariableValue) {
           memState.setVarValue((DfaVariableValue)qualifier, runner.getFactory().createTypeValue(
             ((DfaVariableValue)qualifier).getVariableType(), Nullness.NOT_NULL));
@@ -296,11 +287,11 @@
     return TypeConversionUtil.computeCastTo(o, PsiType.LONG);
   }
 
-
-  protected void onInstructionProducesNPE(Instruction instruction) {}
-
-  protected void onPassingNullParameter(PsiExpression arg) {}
-  protected void onPassingNullParameterToNonAnnotated(DataFlowRunner runner, PsiExpression arg) {}
+  protected boolean checkNotNullable(DfaMemoryState state,
+                                     DfaValue value, NullabilityProblem problem,
+                                     PsiElement anchor) {
+    return state.checkNotNullable(value);
+  }
 
   @Override
   public DfaInstructionState[] visitBinop(BinopInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
@@ -351,11 +342,10 @@
       return null;
     }
 
-    if (isViaMethods(dfaLeft) || isViaMethods(dfaRight)) {
-      skipConstantConditionReporting(instruction.getPsiAnchor());
-    }
     myCanBeNullInInstanceof.add(instruction);
 
+    boolean specialContractTreatment = isUnknownComparisonWithNullInContract(instruction, dfaLeft, dfaRight, factory, memState);
+
     ArrayList<DfaInstructionState> states = new ArrayList<DfaInstructionState>();
 
     final DfaMemoryState trueCopy = memState.createCopy();
@@ -363,6 +353,9 @@
       if (!dfaRelation.isNegated()) {
         checkOneOperandNotNull(dfaRight, dfaLeft, factory, trueCopy);
       }
+      if (specialContractTreatment && !dfaRelation.isNegated()) {
+        trueCopy.markEphemeral();
+      }
       trueCopy.push(factory.getConstFactory().getTrue());
       instruction.setTrueReachable();
       states.add(new DfaInstructionState(next, trueCopy));
@@ -374,6 +367,9 @@
       if (dfaRelation.isNegated()) {
         checkOneOperandNotNull(dfaRight, dfaLeft, factory, falseCopy);
       }
+      if (specialContractTreatment && dfaRelation.isNegated()) {
+        falseCopy.markEphemeral();
+      }
       falseCopy.push(factory.getConstFactory().getFalse());
       instruction.setFalseReachable();
       states.add(new DfaInstructionState(next, falseCopy));
@@ -385,12 +381,25 @@
     return states.toArray(new DfaInstructionState[states.size()]);
   }
 
-  public void skipConstantConditionReporting(@Nullable PsiElement anchor) {
-    ContainerUtil.addIfNotNull(myNotToReportReachability, anchor);
+  private static boolean isUnknownComparisonWithNullInContract(BinopInstruction instruction,
+                                                               DfaValue dfaLeft,
+                                                               DfaValue dfaRight,
+                                                               DfaValueFactory factory,
+                                                               DfaMemoryState memoryState) {
+    if (instruction.getPsiAnchor() != null || dfaRight != factory.getConstFactory().getNull()) {
+      return false;
+    }
+    if (dfaLeft instanceof DfaVariableValue) {
+      return ((DfaMemoryStateImpl)memoryState).getVariableState((DfaVariableValue)dfaLeft).getNullability() == Nullness.UNKNOWN;
+    }
+    if (dfaLeft instanceof DfaTypeValue) {
+      return ((DfaTypeValue)dfaLeft).getNullness() == Nullness.UNKNOWN;
+    }
+    return false;
   }
 
-  private static boolean isViaMethods(DfaValue dfa) {
-    return dfa instanceof DfaVariableValue && ((DfaVariableValue)dfa).isViaMethods();
+  public void skipConstantConditionReporting(@Nullable PsiElement anchor) {
+    ContainerUtil.addIfNotNull(myNotToReportReachability, anchor);
   }
 
   private void handleInstanceof(InstanceofInstruction instruction, DfaValue dfaRight, DfaValue dfaLeft) {
@@ -399,7 +408,7 @@
         myCanBeNullInInstanceof.add(instruction);
       }
 
-      if (((DfaTypeValue)dfaRight).getType().isAssignableFrom(((DfaTypeValue)dfaLeft).getType())) {
+      if (((DfaTypeValue)dfaRight).getDfaType().isAssignableFrom(((DfaTypeValue)dfaLeft).getDfaType())) {
         return;
       }
     }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java
new file mode 100644
index 0000000..e886dde
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java
@@ -0,0 +1,217 @@
+/*
+ * 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.codeInspection.dataFlow;
+
+import com.intellij.codeInspection.dataFlow.value.DfaConstValue;
+import com.intellij.codeInspection.dataFlow.value.DfaValue;
+import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.UnorderedPair;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author peter
+ */
+class StateMerger {
+  private final List<DfaMemoryStateImpl> myStates;
+  private final MultiMap<UnorderedPair<DfaValue>,DfaMemoryStateImpl> myStatesByEq = new MultiMap<UnorderedPair<DfaValue>, DfaMemoryStateImpl>();
+  private final Map<DfaMemoryStateImpl, Map<DfaVariableValue, DfaConstValue>> myVarValues = ContainerUtil.newIdentityHashMap();
+
+  public StateMerger(List<DfaMemoryStateImpl> states) {
+    myStates = states;
+    for (DfaMemoryStateImpl state : myStates) {
+      ProgressManager.checkCanceled();
+      
+      Map<DfaVariableValue,DfaConstValue> varValues = ContainerUtil.newHashMap();
+      for (UnorderedPair<DfaValue> pair : getEqPairs(state)) {
+        myStatesByEq.putValue(pair, state);
+        if (pair.first instanceof DfaVariableValue && pair.second instanceof DfaConstValue) {
+          varValues.put((DfaVariableValue)pair.first, (DfaConstValue)pair.second);
+        }
+      }
+      myVarValues.put(state, varValues);
+    }
+  }
+
+  @Nullable
+  public List<DfaMemoryStateImpl> merge() {
+    for (final DfaMemoryStateImpl state : myStates) {
+      ProgressManager.checkCanceled();
+      MultiMap<DfaVariableValue, DfaValue> distincts = getDistinctsMap(state);
+      for (DfaVariableValue var : distincts.keySet()) {
+        Map<DfaValue, Collection<DfaMemoryStateImpl>> statesByValue = getCompatibleStatesByValue(state, var, distincts);
+        if (statesByValue == null) {
+          continue;
+        }
+
+        DfaMemoryStateImpl copy = copyWithoutVar(state, var);
+        
+        final Set<DfaMemoryStateImpl> complementaryStates = findComplementaryStates(var, statesByValue, copy);
+        if (complementaryStates == null) {
+          continue;
+        }
+
+        complementaryStates.add(state);
+        copy = copy.createCopy();
+        for (DfaMemoryStateImpl removedState : complementaryStates) {
+          for (DfaVariableValue unknownVar : removedState.getUnknownVariables()) {
+            copy.doFlush(unknownVar, true);
+          }
+          if (removedState.isNull(var)) {
+            copy.setVariableState(var, copy.getVariableState(var).withNullability(Nullness.NULLABLE));
+          }
+        }
+
+        List<DfaMemoryStateImpl> result = ContainerUtil.newArrayList();
+        result.add(copy);
+        result.addAll(ContainerUtil.filter(myStates, new Condition<DfaMemoryStateImpl>() {
+          @Override
+          public boolean value(DfaMemoryStateImpl state) {
+            return !complementaryStates.contains(state);
+          }
+        }));
+        return result;
+      }
+      
+    }
+    return null;
+  }
+
+  private Map<Pair<DfaMemoryStateImpl, DfaVariableValue>, DfaMemoryStateImpl> myCopyCache = ContainerUtil.newHashMap();
+  private DfaMemoryStateImpl copyWithoutVar(DfaMemoryStateImpl state, DfaVariableValue var) {
+    Pair<DfaMemoryStateImpl, DfaVariableValue> key = Pair.create(state, var);
+    DfaMemoryStateImpl copy = myCopyCache.get(key);
+    if (copy == null) {
+      copy = state.createCopy();
+      copy.flushVariable(var);
+      myCopyCache.put(key, copy);
+    }
+    return copy;
+  }
+
+  @Nullable
+  private Set<DfaMemoryStateImpl> findComplementaryStates(DfaVariableValue var,
+                                                                 Map<DfaValue, Collection<DfaMemoryStateImpl>> statesByValue,
+                                                                 DfaMemoryStateImpl mainCopy) {
+    Set<DfaMemoryStateImpl> removedStates = ContainerUtil.newTroveSet(ContainerUtil.<DfaMemoryStateImpl>identityStrategy());
+  
+  eachValue: 
+    for (DfaValue value : statesByValue.keySet()) {
+      for (DfaMemoryStateImpl originalState : statesByValue.get(value)) {
+        if (mainCopy.equalsByRelations(copyWithoutVar(originalState, var))) {
+          removedStates.add(originalState);
+          continue eachValue;
+        }
+      }
+      return null;
+    }
+    return removedStates;
+  }
+
+  @Nullable
+  private Map<DfaValue, Collection<DfaMemoryStateImpl>> getCompatibleStatesByValue(final DfaMemoryStateImpl state,
+                                                                                          final DfaVariableValue var,
+                                                                                          MultiMap<DfaVariableValue, DfaValue> distincts) {
+    Map<DfaValue, Collection<DfaMemoryStateImpl>> statesByValue = ContainerUtil.newHashMap();
+    for (DfaValue value : distincts.get(var)) {
+      List<DfaMemoryStateImpl> compatible = ContainerUtil.filter(myStatesByEq.get(createPair(var, value)), new Condition<DfaMemoryStateImpl>() {
+        @Override
+        public boolean value(DfaMemoryStateImpl state2) {
+          return areCompatible(state, state2, var);
+        }
+      });
+      if (compatible.isEmpty()) {
+        return null;
+      }
+      statesByValue.put(value, compatible);
+    }
+    return statesByValue;
+  }
+
+  private boolean areCompatible(DfaMemoryStateImpl state1, DfaMemoryStateImpl state2, DfaVariableValue differentVar) {
+    if (!state1.equalsSuperficially(state2)) {
+      return false;
+    }
+    Map<DfaVariableValue, DfaConstValue> varValues1 = myVarValues.get(state1);
+    Map<DfaVariableValue, DfaConstValue> varValues2 = myVarValues.get(state2);
+    
+    for (DfaVariableValue var : varValues1.keySet()) {
+      if (var != differentVar && varValues1.get(var) != varValues2.get(var)) {
+        return false;
+      }
+    }
+    for (DfaVariableValue var : varValues2.keySet()) {
+      if (var != differentVar && !varValues1.containsKey(var)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private static MultiMap<DfaVariableValue, DfaValue> getDistinctsMap(DfaMemoryStateImpl state) {
+    MultiMap<DfaVariableValue, DfaValue> distincts = new MultiMap<DfaVariableValue, DfaValue>();
+    for (UnorderedPair<EqClass> classPair : state.getDistinctClassPairs()) {
+      for (DfaValue value1 : classPair.first.getMemberValues()) {
+        value1 = DfaMemoryStateImpl.unwrap(value1);
+        for (DfaValue value2 : classPair.second.getMemberValues()) {
+          value2 = DfaMemoryStateImpl.unwrap(value2);
+          if (value1 instanceof DfaVariableValue) {
+            if (value2 instanceof DfaVariableValue || value2 instanceof DfaConstValue) {
+              distincts.putValue((DfaVariableValue)value1, value2);
+            }
+          }
+          if (value2 instanceof DfaVariableValue) {
+            if (value1 instanceof DfaVariableValue || value1 instanceof DfaConstValue) {
+              distincts.putValue((DfaVariableValue)value2, value1);
+            }
+          }
+        }
+      }
+    }
+    return distincts;
+  }
+
+  private static List<UnorderedPair<DfaValue>> getEqPairs(DfaMemoryStateImpl state) {
+    Set<UnorderedPair<DfaValue>> eqPairs = ContainerUtil.newHashSet();
+    for (EqClass eqClass : state.getNonTrivialEqClasses()) {
+      DfaConstValue constant = eqClass.findConstant(true);
+      List<DfaVariableValue> vars = eqClass.getVariables();
+      for (int i = 0; i < vars.size(); i++) {
+        DfaVariableValue var = vars.get(i);
+        if (constant != null) {
+          eqPairs.add(createPair(var, constant));
+        }
+        for (int j = i + 1; j < vars.size(); j++) {
+          eqPairs.add(createPair(var, vars.get(j)));
+        }
+      }
+    }
+    return ContainerUtil.newArrayList(eqPairs);
+  }
+
+  private static UnorderedPair<DfaValue> createPair(DfaVariableValue var, DfaValue val) {
+    return new UnorderedPair<DfaValue>(var, val);
+  }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
index e4631d66..87aa897 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
@@ -16,10 +16,14 @@
 
 package com.intellij.codeInspection.dataFlow;
 
+import com.intellij.codeInspection.dataFlow.value.DfaPsiType;
 import com.intellij.codeInspection.dataFlow.value.DfaValue;
 import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
 import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
 import com.intellij.psi.PsiExpression;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Set;
 
 /**
  * @author Gregory.Shrago
@@ -36,9 +40,13 @@
       super(factory);
     }
 
+    MyDfaMemoryState(DfaMemoryStateImpl toCopy) {
+      super(toCopy);
+    }
+
     @Override
-    protected DfaMemoryStateImpl createNew() {
-      return new MyDfaMemoryState(getFactory());
+    public DfaMemoryStateImpl createCopy() {
+      return new MyDfaMemoryState(this);
     }
 
     @Override
@@ -49,21 +57,37 @@
   }
 
   static class ValuableDfaVariableState extends DfaVariableState {
-    DfaValue myValue;
-    PsiExpression myExpression;
+    final DfaValue myValue;
+    final PsiExpression myExpression;
 
     private ValuableDfaVariableState(final DfaVariableValue psiVariable) {
       super(psiVariable);
+      myValue = null;
+      myExpression = null;
     }
 
-    protected ValuableDfaVariableState(final ValuableDfaVariableState state) {
-      super(state);
-      myExpression = state.myExpression;
+    private ValuableDfaVariableState(Set<DfaPsiType> instanceofValues,
+                             Set<DfaPsiType> notInstanceofValues,
+                             Nullness nullability, DfaValue value, PsiExpression expression) {
+      super(instanceofValues, notInstanceofValues, nullability);
+      myValue = value;
+      myExpression = expression;
     }
 
     @Override
-    public void setValue(final DfaValue value) {
-      myValue = value;
+    protected DfaVariableState createCopy(Set<DfaPsiType> instanceofValues, Set<DfaPsiType> notInstanceofValues, Nullness nullability) {
+      return new ValuableDfaVariableState(instanceofValues, notInstanceofValues, nullability, myValue, myExpression);
+    }
+
+    @Override
+    public DfaVariableState withValue(@Nullable final DfaValue value) {
+      if (value == myValue) return this;
+      return new ValuableDfaVariableState(myInstanceofValues, myNotInstanceofValues, myNullability, value, myExpression);
+    }
+
+    public ValuableDfaVariableState withExpression(@Nullable final PsiExpression expression) {
+      if (expression == myExpression) return this;
+      return new ValuableDfaVariableState(myInstanceofValues, myNotInstanceofValues, myNullability, myValue, expression);
     }
 
     @Override
@@ -72,8 +96,25 @@
     }
 
     @Override
-    protected ValuableDfaVariableState clone() {
-      return new ValuableDfaVariableState(this);
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (!(o instanceof ValuableDfaVariableState)) return false;
+      if (!super.equals(o)) return false;
+
+      ValuableDfaVariableState state = (ValuableDfaVariableState)o;
+
+      if (myExpression != null ? !myExpression.equals(state.myExpression) : state.myExpression != null) return false;
+      if (myValue != null ? !myValue.equals(state.myValue) : state.myValue != null) return false;
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int result = super.hashCode();
+      result = 31 * result + (myValue != null ? myValue.hashCode() : 0);
+      result = 31 * result + (myExpression != null ? myExpression.hashCode() : 0);
+      return result;
     }
   }
 }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java
index dd2514c4..6e64a6b 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java
@@ -33,6 +33,7 @@
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.tree.TokenSet;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import static com.intellij.psi.JavaTokenType.*;
 
@@ -41,11 +42,10 @@
   private final IElementType myOperationSign;
   private final Project myProject;
 
-  public BinopInstruction(IElementType opSign, PsiElement psiAnchor, @NotNull Project project) {
+  public BinopInstruction(IElementType opSign, @Nullable PsiElement psiAnchor, @NotNull Project project) {
+    super(psiAnchor);
     myProject = project;
     myOperationSign = ourSignificantOperations.contains(opSign) ? opSign : null;
-
-    setPsiAnchor(psiAnchor);
   }
 
   @Override
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java
index d1524fc..0f83d84 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java
@@ -27,17 +27,19 @@
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiLiteralExpression;
 import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
 
 public abstract class BranchingInstruction extends Instruction {
   private boolean myIsTrueReachable;
   private boolean myIsFalseReachable;
-  private boolean isConstTrue;
-  private PsiElement myExpression;
+  private final boolean isConstTrue;
+  private final PsiElement myExpression;
 
-  protected BranchingInstruction() {
+  protected BranchingInstruction(@Nullable PsiElement psiAnchor) {
     myIsTrueReachable = false;
     myIsFalseReachable = false;
-    setPsiAnchor(null);
+    myExpression = psiAnchor;
+    isConstTrue = psiAnchor != null && isBoolConst(psiAnchor);
   }
 
   public boolean isTrueReachable() {
@@ -70,8 +72,4 @@
     return "true".equals(text) || "false".equals(text);
   }
 
-  protected void setPsiAnchor(PsiElement psiAnchor) {
-    myExpression = psiAnchor;
-    isConstTrue = psiAnchor != null && isBoolConst(psiAnchor);
-  }
 }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java
index 2b93e95..212a02f 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java
@@ -33,9 +33,9 @@
   private final boolean myIsNegated;
 
   public ConditionalGotoInstruction(ControlFlow.ControlFlowOffset myOffset, boolean isNegated, PsiElement psiAnchor) {
+    super(psiAnchor);
     this.myOffset = myOffset;
     myIsNegated = isNegated;
-    setPsiAnchor(psiAnchor);
   }
 
   public boolean isNegated() {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java
index 9d2a594..dc1fd6f 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java
@@ -27,15 +27,19 @@
     mySubprogramOffset = subprogramOffset;
   }
 
+  public int getSubprogramOffset() {
+    return mySubprogramOffset.getInstructionOffset();
+  }
+
   @Override
   public DfaInstructionState[] accept(DataFlowRunner runner, DfaMemoryState stateBefore, InstructionVisitor visitor) {
     final int returnIndex = getIndex() + 1;
     stateBefore.pushOffset(returnIndex);
-    Instruction nextInstruction = runner.getInstruction(mySubprogramOffset.getInstructionOffset());
+    Instruction nextInstruction = runner.getInstruction(getSubprogramOffset());
     return new DfaInstructionState[] {new DfaInstructionState(nextInstruction, stateBefore)};
   }
 
   public String toString() {
-    return "GOSUB: " + mySubprogramOffset.getInstructionOffset();
+    return "GOSUB: " + getSubprogramOffset();
   }
 }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java
index 3286090..c4400f7 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java
@@ -34,14 +34,18 @@
     this.myOffset = myOffset;
   }
 
+  public int getOffset() {
+    return myOffset.getInstructionOffset();
+  }
+
   @Override
   public DfaInstructionState[] accept(DataFlowRunner runner, DfaMemoryState stateBefore, InstructionVisitor visitor) {
-    Instruction nextInstruction = runner.getInstruction(myOffset.getInstructionOffset());
+    Instruction nextInstruction = runner.getInstruction(getOffset());
     return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, stateBefore)};
   }
 
   public String toString() {
-    return "GOTO: " + myOffset.getInstructionOffset();
+    return "GOTO: " + getOffset();
   }
 
   public void setOffset(final int offset) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
index 5514268..096188e 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
@@ -28,18 +28,9 @@
 import com.intellij.codeInspection.dataFlow.DfaInstructionState;
 import com.intellij.codeInspection.dataFlow.DfaMemoryState;
 import com.intellij.codeInspection.dataFlow.InstructionVisitor;
-import com.intellij.openapi.progress.ProgressManager;
-
-import java.util.ArrayList;
-import java.util.List;
 
 public abstract class Instruction {
   private int myIndex;
-  private final List<DfaMemoryState> myProcessedStates;
-
-  protected Instruction() {
-    myProcessedStates = new ArrayList<DfaMemoryState>();
-  }
 
   protected final DfaInstructionState[] nextInstruction(DataFlowRunner runner, DfaMemoryState stateBefore) {
     return new DfaInstructionState[] {new DfaInstructionState(runner.getInstruction(getIndex() + 1), stateBefore)};
@@ -47,23 +38,6 @@
 
   public abstract DfaInstructionState[] accept(DataFlowRunner runner, DfaMemoryState stateBefore, InstructionVisitor visitor);
 
-  public boolean isMemoryStateProcessed(DfaMemoryState dfaMemState) {
-    for (DfaMemoryState state : myProcessedStates) {
-      ProgressManager.checkCanceled();
-      if (dfaMemState.equals(state)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  public boolean setMemoryStateProcessed(DfaMemoryState dfaMemState) {
-    if (myProcessedStates.size() > DataFlowRunner.MAX_STATES_PER_BRANCH) return false;
-    myProcessedStates.add(dfaMemState);
-    return true;
-  }
-
   public void setIndex(int index) {
     myIndex = index;
   }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaPsiType.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaPsiType.java
new file mode 100644
index 0000000..f58e44f
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaPsiType.java
@@ -0,0 +1,67 @@
+/*
+ * 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.codeInspection.dataFlow.value;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiType;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Map;
+
+/**
+ * @author peter
+ */
+public class DfaPsiType {
+  private final PsiType myPsiType;
+  private final Map<Pair<DfaPsiType, DfaPsiType>, Boolean> myAssignableCache;
+  private final Map<Pair<DfaPsiType, DfaPsiType>, Boolean> myConvertibleCache;
+
+  DfaPsiType(@NotNull PsiType psiType, Map<Pair<DfaPsiType, DfaPsiType>, Boolean> assignableCache, Map<Pair<DfaPsiType, DfaPsiType>, Boolean> convertibleCache) {
+    myPsiType = psiType;
+    myAssignableCache = assignableCache;
+    myConvertibleCache = convertibleCache;
+  }
+
+  @NotNull
+  public PsiType getPsiType() {
+    return myPsiType;
+  }
+
+  public boolean isAssignableFrom(DfaPsiType other) {
+    if (other == this) return true;
+    Pair<DfaPsiType, DfaPsiType> key = Pair.create(this, other);
+    Boolean result = myAssignableCache.get(key);
+    if (result == null) {
+      myAssignableCache.put(key, result = myPsiType.isAssignableFrom(other.myPsiType));
+    }
+    return result;
+  }
+
+  public boolean isConvertibleFrom(DfaPsiType other) {
+    if (other == this) return true;
+    Pair<DfaPsiType, DfaPsiType> key = Pair.create(this, other);
+    Boolean result = myConvertibleCache.get(key);
+    if (result == null) {
+      myConvertibleCache.put(key, result = myPsiType.isConvertibleFrom(other.myPsiType));
+    }
+    return result;
+  }
+
+  @Override
+  public String toString() {
+    return myPsiType.getPresentableText();
+  }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java
index f7b6487..193d342 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java
@@ -25,72 +25,51 @@
 package com.intellij.codeInspection.dataFlow.value;
 
 import com.intellij.codeInspection.dataFlow.Nullness;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.PsiKeyword;
-import com.intellij.psi.PsiType;
-import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.util.containers.HashMap;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
+import java.util.Map;
 
 public class DfaTypeValue extends DfaValue {
   public static class Factory {
-    private final DfaTypeValue mySharedInstance;
-    private final HashMap<String,ArrayList<DfaTypeValue>> myStringToObject;
+    private final Map<DfaPsiType,ArrayList<DfaTypeValue>> myCache = ContainerUtil.newHashMap();
     private final DfaValueFactory myFactory;
 
     Factory(DfaValueFactory factory) {
       myFactory = factory;
-      mySharedInstance = new DfaTypeValue(factory);
-      myStringToObject = new HashMap<String, ArrayList<DfaTypeValue>>();
     }
 
     @NotNull
-    public DfaTypeValue createTypeValue(@NotNull PsiType type, @NotNull Nullness nullable) {
-      type = TypeConversionUtil.erasure(type);
-      mySharedInstance.myType = type;
-      mySharedInstance.myCanonicalText = StringUtil.notNullize(type.getCanonicalText(), PsiKeyword.NULL);
-      mySharedInstance.myNullness = nullable;
-
-      String id = mySharedInstance.toString();
-      ArrayList<DfaTypeValue> conditions = myStringToObject.get(id);
+    public DfaTypeValue createTypeValue(@NotNull DfaPsiType type, @NotNull Nullness nullness) {
+      ArrayList<DfaTypeValue> conditions = myCache.get(type);
       if (conditions == null) {
         conditions = new ArrayList<DfaTypeValue>();
-        myStringToObject.put(id, conditions);
+        myCache.put(type, conditions);
       } else {
         for (DfaTypeValue aType : conditions) {
-          if (aType.hardEquals(mySharedInstance)) return aType;
+          if (aType.myNullness == nullness) return aType;
         }
       }
 
-      DfaTypeValue result = new DfaTypeValue(type, nullable, myFactory, mySharedInstance.myCanonicalText);
+      DfaTypeValue result = new DfaTypeValue(type, nullness, myFactory);
       conditions.add(result);
-      return result;
+      return new DfaTypeValue(type, nullness, myFactory);
     }
 
-    public DfaTypeValue createTypeValue(@NotNull PsiType type) {
-      return createTypeValue(type, Nullness.UNKNOWN);
-    }
   }
 
-  private PsiType myType;
-  private String myCanonicalText;
+  private DfaPsiType myType;
   private Nullness myNullness;
 
-  private DfaTypeValue(DfaValueFactory factory) {
-    super(factory);
-  }
-
-  private DfaTypeValue(PsiType type, Nullness nullness, DfaValueFactory factory, String canonicalText) {
+  private DfaTypeValue(DfaPsiType type, Nullness nullness, DfaValueFactory factory) {
     super(factory);
     myType = type;
     myNullness = nullness;
-    myCanonicalText = canonicalText;
   }
 
-  public PsiType getType() {
+  public DfaPsiType getDfaType() {
     return myType;
   }
 
@@ -102,23 +81,13 @@
     return myNullness == Nullness.NOT_NULL;
   }
 
+  public Nullness getNullness() {
+    return myNullness;
+  }
+
   @NonNls
   public String toString() {
-    return myCanonicalText + ", nullable=" + myNullness;
+    return myType + ", nullable=" + myNullness;
   }
 
-  private boolean hardEquals(DfaTypeValue aType) {
-    return myCanonicalText.equals(aType.myCanonicalText) && myNullness == aType.myNullness && myType.equals(aType.myType);
-  }
-
-  public boolean isAssignableFrom(DfaTypeValue dfaType) {
-    return dfaType != null && myType.isAssignableFrom(dfaType.myType);
-  }
-
-  public boolean isConvertibleFrom(DfaTypeValue dfaType) {
-    if (dfaType == null) return false;
-    assert myType.isValid() : "my type invalid";
-    assert dfaType.myType.isValid() : " their type invalid";
-    return myType.isConvertibleFrom(dfaType.myType);
-  }
 }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java
index e19b3ce..c78bfb1 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java
@@ -21,13 +21,7 @@
 
   protected DfaValue(final DfaValueFactory factory) {
     myFactory = factory;
-    if (factory == null) {
-      myID = 0;
-    }
-    else {
-      myID = factory.createID();
-      factory.registerValue(this);
-    }
+    myID = factory == null ? 0 : factory.registerValue(this);
   }
 
   public int getID() {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java
index f6b900f..70cb578 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java
@@ -25,24 +25,26 @@
 package com.intellij.codeInspection.dataFlow.value;
 
 import com.intellij.codeInspection.dataFlow.Nullness;
-import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Pair;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
 import com.intellij.psi.util.PsiTreeUtil;
-import gnu.trove.TIntObjectHashMap;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-public class DfaValueFactory {
-  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.value.DfaValueFactory");
+import java.util.List;
+import java.util.Map;
 
-  private int myLastID;
-  private final TIntObjectHashMap<DfaValue> myValues;
+public class DfaValueFactory {
+  private final List<DfaValue> myValues = ContainerUtil.newArrayList();
+  private final Map<Pair<DfaPsiType, DfaPsiType>, Boolean> myAssignableCache = ContainerUtil.newHashMap();
+  private final Map<Pair<DfaPsiType, DfaPsiType>, Boolean> myConvertibleCache = ContainerUtil.newHashMap();
+  private final Map<PsiType, DfaPsiType> myDfaTypes = ContainerUtil.newHashMap();
 
   public DfaValueFactory() {
-    myValues = new TIntObjectHashMap<DfaValue>();
-    myLastID = 0;
-
+    myValues.add(null);
     myVarFactory = new DfaVariableValue.Factory(this);
     myConstFactory = new DfaConstValue.Factory(this);
     myBoxedFactory = new DfaBoxedValue.Factory(this);
@@ -52,17 +54,20 @@
 
   public DfaValue createTypeValue(@Nullable PsiType type, Nullness nullability) {
     if (type == null) return DfaUnknownValue.getInstance();
-    return getTypeFactory().createTypeValue(type, nullability);
+    return getTypeFactory().createTypeValue(internType(type), nullability);
   }
 
-   int createID() {
-    myLastID++;
-    LOG.assertTrue(myLastID >= 0, "Overflow");
-    return myLastID;
+  private DfaPsiType internType(@NotNull PsiType psiType) {
+    DfaPsiType dfaType = myDfaTypes.get(psiType);
+    if (dfaType == null) {
+      myDfaTypes.put(psiType, dfaType = new DfaPsiType(TypeConversionUtil.erasure(psiType), myAssignableCache, myConvertibleCache));
+    }
+    return dfaType;
   }
 
-  void registerValue(DfaValue value) {
-    myValues.put(value.getID(), value);
+  int registerValue(DfaValue value) {
+    myValues.add(value);
+    return myValues.size() - 1;
   }
 
   public DfaValue getValue(int id) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
index e522b8f..fa2217a 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
@@ -30,6 +30,7 @@
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Trinity;
 import com.intellij.psi.*;
+import com.intellij.psi.util.TypeConversionUtil;
 import com.intellij.util.SmartList;
 import com.intellij.util.containers.MultiMap;
 import org.jetbrains.annotations.NotNull;
@@ -90,7 +91,7 @@
     myIsNegated = isNegated;
     myQualifier = qualifier;
     myVarType = varType;
-    myTypeValue = varType == null ? null : myFactory.getTypeFactory().createTypeValue(varType, Nullness.UNKNOWN);
+    myTypeValue = varType == null ? null : (DfaTypeValue)myFactory.createTypeValue(varType, Nullness.UNKNOWN);
   }
 
   @Nullable
@@ -132,7 +133,7 @@
 
   private boolean hardEquals(PsiModifierListOwner psiVar, PsiType varType, boolean negated, DfaVariableValue qualifier) {
     return psiVar == myVariable &&
-           Comparing.equal(varType, myVarType) &&
+           Comparing.equal(TypeConversionUtil.erasure(varType), TypeConversionUtil.erasure(myVarType)) &&
            negated == myIsNegated &&
            (myQualifier == null ? qualifier == null : myQualifier.hardEquals(qualifier.getPsiVariable(), qualifier.getVariableType(),
                                                                              qualifier.isNegated(), qualifier.getQualifier()));
@@ -143,10 +144,6 @@
     return myQualifier;
   }
 
-  public boolean isViaMethods() {
-    return myVariable instanceof PsiMethod || myQualifier != null && myQualifier.isViaMethods();
-  }
-
   public Nullness getInherentNullability() {
     if (myInherentNullability != null) {
       return myInherentNullability;
@@ -190,14 +187,12 @@
     return Nullness.UNKNOWN;
   }
 
-  public boolean isLocalVariable() {
-    return myVariable instanceof PsiLocalVariable || myVariable instanceof PsiParameter;
-  }
-
   public boolean isFlushableByCalls() {
-    if (isLocalVariable()) return false;
-    if (!myVariable.hasModifierProperty(PsiModifier.FINAL)) return true;
-    return myQualifier != null && myQualifier.isFlushableByCalls();
+    if (myVariable instanceof PsiLocalVariable || myVariable instanceof PsiParameter) return false;
+    if (myVariable instanceof PsiVariable && myVariable.hasModifierProperty(PsiModifier.FINAL)) {
+      return myQualifier != null && myQualifier.isFlushableByCalls();
+    }
+    return true;
   }
 
 }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaUtilImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaUtilImpl.java
index 71fa80a..c46bfb6 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaUtilImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaUtilImpl.java
@@ -223,7 +223,7 @@
       refParent = refParent.getOwner();
     }
 
-    return (RefClass)refElement;
+    return refElement instanceof RefClass ? (RefClass)refElement : null;
   }
 
   @Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
index f33c6e4..15e6d5a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
@@ -255,7 +255,7 @@
     for (OverrideImplementsAnnotationsHandler each : Extensions.getExtensions(OverrideImplementsAnnotationsHandler.EP_NAME)) {
       for (String annotation : each.getAnnotations(project)) {
         if (moduleScope != null && facade.findClass(annotation, moduleScope) == null) continue;
-        if (AnnotationUtil.isAnnotated(overridden, annotation, false, false)) {
+        if (AnnotationUtil.isAnnotated(overridden, annotation, false, false) && !AnnotationUtil.isAnnotated(method, annotation, false, false)) {
           AddAnnotationPsiFix.removePhysicalAnnotations(method, each.annotationsToRemove(project, annotation));
           AddAnnotationPsiFix.addPhysicalAnnotation(annotation, PsiNameValuePair.EMPTY_ARRAY, method.getModifierList());
         }
diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java
index b3434ac..9646ef9 100644
--- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java
@@ -21,6 +21,7 @@
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.util.text.CharArrayUtil;
+import com.intellij.xml.util.XmlStringUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -110,14 +111,18 @@
 
   @Override
   public void updateUI(final PsiAnnotationMethod p, final ParameterInfoUIContext context) {
-    @NonNls StringBuffer buffer = new StringBuffer();
+    updateUIText(p, context);
+  }
+
+  public static String updateUIText(PsiAnnotationMethod p, ParameterInfoUIContext context) {
+    @NonNls StringBuilder buffer = new StringBuilder();
     int highlightStartOffset;
     int highlightEndOffset;
     buffer.append(p.getReturnType().getPresentableText());
     buffer.append(" ");
-    highlightStartOffset = buffer.length();
+    highlightStartOffset = XmlStringUtil.escapeString(buffer.toString()).length();
     buffer.append(p.getName());
-    highlightEndOffset = buffer.length();
+    highlightEndOffset = XmlStringUtil.escapeString(buffer.toString()).length();
     buffer.append("()");
 
     if (p.getDefaultValue() != null) {
@@ -125,8 +130,8 @@
       buffer.append(p.getDefaultValue().getText());
     }
 
-    context.setupUIComponentPresentation(buffer.toString(), highlightStartOffset, highlightEndOffset, false, p.isDeprecated(),
-                                         false, context.getDefaultParameterColor());
+    return context.setupUIComponentPresentation(buffer.toString(), highlightStartOffset, highlightEndOffset, false, p.isDeprecated(),
+                                                false, context.getDefaultParameterColor());
   }
 
   private static PsiAnnotationMethod findAnnotationMethod(PsiFile file, int offset) {
diff --git a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicConstantInspection.java b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicConstantInspection.java
index 7193cc9..6fb2bc7 100644
--- a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicConstantInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicConstantInspection.java
@@ -623,7 +623,7 @@
     params.dataFlowToThis = true;
     params.scope = new AnalysisScope(new LocalSearchScope(scope), manager.getProject());
 
-    SliceRootNode rootNode = new SliceRootNode(manager.getProject(), new DuplicateMap(), SliceManager.createRootUsage(argument, params));
+    SliceRootNode rootNode = new SliceRootNode(manager.getProject(), new DuplicateMap(), SliceUsage.createRootUsage(argument, params));
 
     Collection<? extends AbstractTreeNode> children = rootNode.getChildren().iterator().next().getChildren();
     for (AbstractTreeNode child : children) {
diff --git a/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java b/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java
index fd624b1..d6be007 100644
--- a/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java
+++ b/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java
@@ -107,11 +107,13 @@
     myLanguageLevel = languageLevel;
   }
 
+  @Override
   @NotNull
   public Lexer getHighlightingLexer() {
     return new JavaHighlightingLexer(myLanguageLevel);
   }
 
+  @Override
   @NotNull
   public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
     return pack(ourMap1.get(tokenType), ourMap2.get(tokenType));
diff --git a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java
index 402e7f5..f93464e 100644
--- a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java
+++ b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java
@@ -16,7 +16,7 @@
 package com.intellij.ide.util.gotoByName;
 
 import com.intellij.ide.util.DefaultPsiElementCellRenderer;
-import com.intellij.navigation.ChooseByNameContributor;
+import com.intellij.navigation.ChooseByNameContributorEx;
 import com.intellij.navigation.NavigationItem;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
@@ -26,7 +26,9 @@
 import com.intellij.psi.search.PsiShortNamesCache;
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.util.ArrayUtil;
+import com.intellij.util.Processor;
 import com.intellij.util.containers.HashSet;
+import com.intellij.util.indexing.IdFilter;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
@@ -34,7 +36,7 @@
 import java.util.Comparator;
 import java.util.List;
 
-public class DefaultSymbolNavigationContributor implements ChooseByNameContributor {
+public class DefaultSymbolNavigationContributor implements ChooseByNameContributorEx {
   private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.DefaultSymbolNavigationContributor");
 
   @Override
@@ -91,6 +93,13 @@
     return false;
   }
 
+  public void processNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+    PsiShortNamesCache cache = PsiShortNamesCache.getInstance(scope.getProject());
+    cache.processAllClassNames(processor, scope, filter);
+    cache.processAllFieldNames(processor, scope, filter);
+    cache.processAllMethodNames(processor, scope, filter);
+  }
+
   private static class MyComparator implements Comparator<PsiModifierListOwner>{
     public static final MyComparator INSTANCE = new MyComparator();
 
diff --git a/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java b/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java
index 918b8ff..7ee3d7b 100644
--- a/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java
+++ b/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java
@@ -45,7 +45,7 @@
    */
   @Nullable
   @Override
-  public SyntaxHighlighter create(FileType fileType, @Nullable Project project, @Nullable VirtualFile file) {
+  public SyntaxHighlighter create(@NotNull FileType fileType, @Nullable Project project, @Nullable VirtualFile file) {
     if (project != null && file != null) {
       PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
       if (psiFile instanceof ClsFileImpl) {
diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
index 7baff14..d392d7a 100644
--- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
+++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
@@ -263,6 +263,9 @@
       final Indent defaultChildIndent = getChildIndent(parent, indentOptions);
       if (defaultChildIndent != null) return defaultChildIndent;
     }
+    if (child.getTreeParent() instanceof PsiLambdaExpression && child instanceof PsiCodeBlock) {
+      return Indent.getNoneIndent();
+    }
 
     return null;
   }
diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java
index 1376f44..8f090b0 100644
--- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java
+++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java
@@ -795,6 +795,12 @@
       {
         minSpaces = 1;
         minLineFeeds = 0;
+        if (myChild1 != null) {
+          ASTNode lastElement = myChild1;
+          while (lastElement.getLastChildNode() != null) lastElement = lastElement.getLastChildNode();
+          //Not to place second statement on the same line with first one, if last ends with single line comment
+          if (lastElement instanceof PsiComment && lastElement.getElementType() == JavaTokenType.END_OF_LINE_COMMENT) minLineFeeds = 1;
+        }
       }
       myResult = Spacing.createSpacing(minSpaces, 0, minLineFeeds, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
     }
@@ -1086,7 +1092,7 @@
       createParenthSpace(mySettings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE, mySettings.SPACE_WITHIN_METHOD_PARENTHESES);
     }
     else if (myRole1 == ChildRole.COMMA) {
-      createSpaceInCode(true);
+      createSpaceInCode(mySettings.SPACE_AFTER_COMMA);
     }
   }
 
diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/wrap/impl/JavaChildBlockWrapFactory.java b/java/java-impl/src/com/intellij/psi/formatter/java/wrap/impl/JavaChildBlockWrapFactory.java
index eeeae0e..ad4d8c0 100644
--- a/java/java-impl/src/com/intellij/psi/formatter/java/wrap/impl/JavaChildBlockWrapFactory.java
+++ b/java/java-impl/src/com/intellij/psi/formatter/java/wrap/impl/JavaChildBlockWrapFactory.java
@@ -19,6 +19,7 @@
 import com.intellij.formatting.Wrap;
 import com.intellij.formatting.WrapType;
 import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiMethod;
 import com.intellij.psi.PsiPolyadicExpression;
 import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
 import com.intellij.psi.formatter.java.JavaFormatterUtil;
@@ -83,7 +84,10 @@
       return Wrap.createWrap(settings.THROWS_LIST_WRAP, true);
     }
     else if (nodeType == JavaElementType.CODE_BLOCK) {
-      return Wrap.createWrap(Wrap.NORMAL, false);
+      if (settings.KEEP_SIMPLE_METHODS_IN_ONE_LINE && node.getPsi().getParent() instanceof PsiMethod && !node.textContains('\n')) {
+        return null;
+      }
+      return Wrap.createWrap(WrapType.NORMAL, false);
     }
     else if (JavaFormatterUtil.isAssignment(node)) {
       return Wrap.createWrap(settings.ASSIGNMENT_WRAP, true);
diff --git a/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java b/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java
index 7971d2f..e92396e 100644
--- a/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java
+++ b/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.psi.impl.file;
 
+import com.intellij.openapi.roots.ProjectFileIndex;
 import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
@@ -23,6 +24,7 @@
 import com.intellij.psi.impl.PsiManagerImpl;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
 
 /**
  * @author yole
@@ -34,6 +36,7 @@
     myManager = manager;
   }
 
+  @NotNull
   @Override
   public PsiDirectory createDirectory(@NotNull final VirtualFile file) {
     return new PsiJavaDirectoryImpl(myManager, file);
@@ -61,8 +64,10 @@
   }
 
   @Override
-  public boolean isPackage(PsiDirectory directory) {
-    return ProjectRootManager.getInstance(myManager.getProject()).getFileIndex().getPackageNameByDirectory(directory.getVirtualFile()) != null;
+  public boolean isPackage(@NotNull PsiDirectory directory) {
+    ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myManager.getProject()).getFileIndex();
+    VirtualFile virtualFile = directory.getVirtualFile();
+    return fileIndex.isUnderSourceRootOfType(virtualFile, JavaModuleSourceRootTypes.SOURCES) && fileIndex.getPackageNameByDirectory(virtualFile) != null;
   }
 
   @Override
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java b/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java
index 3794863..f404c40 100644
--- a/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java
+++ b/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java
@@ -24,6 +24,7 @@
 import com.intellij.psi.tree.TokenSet;
 import com.intellij.psi.xml.XmlElementType;
 import com.intellij.psi.xml.XmlTokenType;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -35,7 +36,7 @@
 
   @Override
   @Nullable
-  public Lexer getIndexingLexer(final PsiFile file) {
+  public Lexer getIndexingLexer(@NotNull final PsiFile file) {
     if (file instanceof PsiJavaFile && !(file instanceof JspFile)) {
       return JavaParserDefinition.createLexer(((PsiJavaFile)file).getLanguageLevel());
     }
@@ -44,7 +45,7 @@
 
   @Override
   @Nullable
-  public TokenSet getCommentTokenSet(final PsiFile file) {
+  public TokenSet getCommentTokenSet(@NotNull final PsiFile file) {
     if (file instanceof PsiJavaFile && !(file instanceof ServerPageFile)) {
       return TokenSet.orSet(StdTokenSets.COMMENT_BIT_SET, XML_COMMENT_BIT_SET, JavaDocTokenType.ALL_JAVADOC_TOKENS, XML_DATA_CHARS);
     }
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java b/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java
index 6011081..57539ae 100644
--- a/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java
+++ b/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 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.
@@ -32,13 +32,14 @@
 import com.intellij.psi.jsp.JspTokenType;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * @author yole
  */
 public class JspIndexPatternBuilder implements IndexPatternBuilder {
   @Override
-  public Lexer getIndexingLexer(final PsiFile file) {
+  public Lexer getIndexingLexer(@NotNull final PsiFile file) {
     if (JspPsiUtil.isInJspFile(file)) {
       EditorHighlighter highlighter = null;
 
@@ -67,7 +68,7 @@
   }
 
   @Override
-  public TokenSet getCommentTokenSet(final PsiFile file) {
+  public TokenSet getCommentTokenSet(@NotNull final PsiFile file) {
     final JspFile jspFile = JspPsiUtil.getJspFile(file);
     TokenSet commentTokens = TokenSet.orSet(JavaIndexPatternBuilder.XML_COMMENT_BIT_SET, StdTokenSets.COMMENT_BIT_SET);
     final ParserDefinition parserDefinition =
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java b/java/java-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java
index 92068c2..894b88b 100644
--- a/java/java-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java
+++ b/java/java-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2010 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.
@@ -20,6 +20,7 @@
 import com.intellij.openapi.editor.highlighter.HighlighterIterator;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.util.text.CharSequenceSubSequence;
+import org.jetbrains.annotations.NotNull;
 
 /**
 * @author Sergey Evdokimov
@@ -38,7 +39,7 @@
   }
 
   @Override
-  public void start(CharSequence buffer, int startOffset, int endOffset, int state) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int state) {
     if (myAlreadyInitializedHighlighter) {
       this.buffer = buffer;
       start = startOffset;
@@ -75,6 +76,7 @@
     iterator.advance();
   }
 
+  @NotNull
   @Override
   public CharSequence getBufferSequence() {
     return buffer;
diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java
index 8c4f926..11c77dd 100644
--- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java
@@ -87,6 +87,8 @@
   private final JRadioButton myRbAccessorPackageLocal = new JRadioButton();
   private DocCommentPanel myJavadocPolicy;
 
+  private boolean myCbUseAccessorWhenAccessibleValue;
+
   {
     myRbAccessorPackageLocal.setFocusable(false);
     myRbAccessorPrivate.setFocusable(false);
@@ -270,13 +272,23 @@
     myCbEncapsulateSet.addActionListener(checkboxListener);
     myRbFieldAsIs.addItemListener(new ItemListener() {
       public void itemStateChanged(ItemEvent e) {
-        myCbUseAccessorsWhenAccessible.setEnabled(!myRbFieldAsIs.isSelected());
+        if (myRbFieldAsIs.isSelected()) {
+          myCbUseAccessorWhenAccessibleValue = myCbUseAccessorsWhenAccessible.isSelected();
+
+          myCbUseAccessorsWhenAccessible.setSelected(true);
+          myCbUseAccessorsWhenAccessible.setEnabled(false);
+        }
+        else {
+          myCbUseAccessorsWhenAccessible.setEnabled(true);
+          myCbUseAccessorsWhenAccessible.setSelected(myCbUseAccessorWhenAccessibleValue);
+        }
       }
     }
     );
     myCbUseAccessorsWhenAccessible.setSelected(
             JavaRefactoringSettings.getInstance().ENCAPSULATE_FIELDS_USE_ACCESSORS_WHEN_ACCESSIBLE
     );
+    myCbUseAccessorWhenAccessibleValue = myCbUseAccessorsWhenAccessible.isSelected();
 
     myRbFieldPrivate.setSelected(true);
     myRbAccessorPublic.setSelected(true);
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
index eee40ea..c8007a3 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
@@ -330,7 +330,7 @@
   }
 
   private boolean isNotNull(PsiVariable outputVariable) {
-    final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(false);
+    final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner();
     final PsiCodeBlock block = myElementFactory.createCodeBlock();
     for (PsiElement element : myElements) {
       block.add(element);
diff --git a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java
index 24dd3cf..ca324a0 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.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.
@@ -261,40 +261,34 @@
 
   protected JComponent createCenterPanel() {
     final JPanel panel = new JPanel(new BorderLayout());
-    final MemberSelectionPanel memberSelectionPanel =
-      new MemberSelectionPanel(RefactorJBundle.message("members.to.extract.label"), memberInfo, "As enum") {
-        @Override
-        protected MemberSelectionTable createMemberSelectionTable(final List<MemberInfo> memberInfo, String abstractColumnHeader) {
-          return new MemberSelectionTable(memberInfo, abstractColumnHeader) {
-            @Nullable
-            @Override
-            protected Object getAbstractColumnValue(MemberInfo memberInfo) {
-              if (isExtractAsEnum()) {
-                final PsiMember member = memberInfo.getMember();
-                if (isConstantField(member)) {
-                  return Boolean.valueOf(enumConstants.contains(memberInfo));
-                }
-              }
-              return null;
-            }
-
-            @Override
-            protected boolean isAbstractColumnEditable(int rowIndex) {
-              final MemberInfo info = memberInfo.get(rowIndex);
-              if (info.isChecked()) {
-                final PsiMember member = info.getMember();
-                if (isConstantField(member)) {
-                  if (enumConstants.isEmpty()) return true;
-                  final MemberInfo currentEnumConstant = enumConstants.get(0);
-                  if (((PsiField)currentEnumConstant.getMember()).getType().equals(((PsiField)member).getType())) return true;
-                }
-              }
-              return false;
-            }
-          };
+    final MemberSelectionTable table = new MemberSelectionTable(memberInfo, "As enum") {
+      @Nullable
+      @Override
+      protected Object getAbstractColumnValue(MemberInfo memberInfo) {
+        if (isExtractAsEnum()) {
+          final PsiMember member = memberInfo.getMember();
+          if (isConstantField(member)) {
+            return Boolean.valueOf(enumConstants.contains(memberInfo));
+          }
         }
-      };
-    final MemberSelectionTable table = memberSelectionPanel.getTable();
+        return null;
+      }
+
+      @Override
+      protected boolean isAbstractColumnEditable(int rowIndex) {
+        final MemberInfo info = memberInfo.get(rowIndex);
+        if (info.isChecked()) {
+          final PsiMember member = info.getMember();
+          if (isConstantField(member)) {
+            if (enumConstants.isEmpty()) return true;
+            final MemberInfo currentEnumConstant = enumConstants.get(0);
+            if (((PsiField)currentEnumConstant.getMember()).getType().equals(((PsiField)member).getType())) return true;
+          }
+        }
+        return false;
+      }
+    };
+
     table.setMemberInfoModel(new DelegatingMemberInfoModel<PsiMember, MemberInfo>(table.getMemberInfoModel()) {
 
       @Override
@@ -342,6 +336,10 @@
         return cause;
       }
     });
+
+    final MemberSelectionPanelBase<PsiMember, MemberInfo, MemberSelectionTable> memberSelectionPanel =
+      new MemberSelectionPanelBase<PsiMember, MemberInfo, MemberSelectionTable>(RefactorJBundle.message("members.to.extract.label"), table);
+
     panel.add(memberSelectionPanel, BorderLayout.CENTER);
     table.addMemberInfoChangeListener(this);
     extractAsEnum.addActionListener(new ActionListener() {
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java
index 223a180..dac214d 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java
@@ -158,6 +158,9 @@
       }
       if (parent instanceof PsiExpression) {
         expression = (PsiExpression)parent;
+        if (expression.getText().equals(exprText)) {
+          return expression;
+        }
       } else {
         return null;
       }
diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java
index 3cca01e..d0c10ba 100644
--- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.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.
@@ -153,16 +153,17 @@
 
 
   public boolean checkConflicts(final PullUpDialog dialog) {
-    final MemberInfo[] infos = dialog.getSelectedMemberInfos();
+    final List<MemberInfo> infos = dialog.getSelectedMemberInfos();
+    final MemberInfo[] memberInfos = infos.toArray(new MemberInfo[infos.size()]);
     final PsiClass superClass = dialog.getSuperClass();
-    if (!checkWritable(superClass, infos)) return false;
+    if (!checkWritable(superClass, memberInfos)) return false;
     final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
     if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
       public void run() {
         final PsiDirectory targetDirectory = superClass.getContainingFile().getContainingDirectory();
         final PsiPackage targetPackage = targetDirectory != null ? JavaDirectoryService.getInstance().getPackage(targetDirectory) : null;
         conflicts
-          .putAllValues(PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, targetPackage, targetDirectory, dialog.getContainmentVerifier()));
+          .putAllValues(PullUpConflictsUtil.checkConflicts(memberInfos, mySubclass, superClass, targetPackage, targetDirectory, dialog.getContainmentVerifier()));
       }
     }, RefactoringBundle.message("detecting.possible.conflicts"), true, myProject)) return false;
     if (!conflicts.isEmpty()) {
diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java
index 4d5d8b5b..801612a 100644
--- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.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.
@@ -30,15 +30,16 @@
 import com.intellij.psi.search.searches.ClassInheritorsSearch;
 import com.intellij.psi.util.*;
 import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
 import com.intellij.refactoring.util.CommonRefactoringUtil;
 import com.intellij.refactoring.util.RefactoringConflictsUtil;
 import com.intellij.refactoring.util.RefactoringHierarchyUtil;
 import com.intellij.refactoring.util.RefactoringUIUtil;
 import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor;
 import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier;
-import com.intellij.refactoring.util.classMembers.MemberInfo;
 import com.intellij.usageView.UsageInfo;
 import com.intellij.util.VisibilityUtil;
+import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.MultiMap;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -51,16 +52,16 @@
 public class PullUpConflictsUtil {
   private PullUpConflictsUtil() {}
 
-  public static MultiMap<PsiElement, String> checkConflicts(final MemberInfo[] infos,
-                                        PsiClass subclass,
-                                        @Nullable PsiClass superClass,
-                                        @NotNull PsiPackage targetPackage,
-                                        @NotNull PsiDirectory targetDirectory,
-                                        final InterfaceContainmentVerifier interfaceContainmentVerifier) {
+  public static MultiMap<PsiElement, String> checkConflicts(MemberInfoBase<? extends PsiMember>[] infos,
+                                                            PsiClass subclass,
+                                                            @Nullable PsiClass superClass,
+                                                            @NotNull PsiPackage targetPackage,
+                                                            @NotNull PsiDirectory targetDirectory,
+                                                            final InterfaceContainmentVerifier interfaceContainmentVerifier) {
     return checkConflicts(infos, subclass, superClass, targetPackage, targetDirectory, interfaceContainmentVerifier, true);
   }
 
-  public static MultiMap<PsiElement, String> checkConflicts(final MemberInfo[] infos,
+  public static MultiMap<PsiElement, String> checkConflicts(final MemberInfoBase<? extends PsiMember>[] infos,
                                                             @NotNull final PsiClass subclass,
                                                             @Nullable PsiClass superClass,
                                                             @NotNull final PsiPackage targetPackage,
@@ -79,7 +80,7 @@
       isInterfaceTarget = false;
       targetRepresentativeElement = targetDirectory;
     }
-    for (MemberInfo info : infos) {
+    for (MemberInfoBase<? extends PsiMember> info : infos) {
       PsiMember member = info.getMember();
       if (member instanceof PsiMethod) {
         if (!info.isToAbstract() && !isInterfaceTarget) {
@@ -129,15 +130,15 @@
           movedMembers2Super? new ConflictingUsagesOfSubClassMembers(member, movedMembers, abstractMethods, subclass, superClass,
                                                  superClass != null ? null : targetPackage, conflicts,
                                                  interfaceContainmentVerifier)
-                            : new ConflictingUsagesOfSuperClassMemebers(member, subclass, targetPackage, movedMembers, conflicts);
+                            : new ConflictingUsagesOfSuperClassMembers(member, subclass, targetPackage, movedMembers, conflicts);
         member.accept(visitor);
       }
       checkModuleConflictsList.add(member);
     }
     for (final PsiMethod method : abstractMethods) {
-      checkModuleConflictsList.add(method.getParameterList());
-      checkModuleConflictsList.add(method.getReturnTypeElement());
-      checkModuleConflictsList.add(method.getTypeParameterList());
+      ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getParameterList());
+      ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getReturnTypeElement());
+      ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getTypeParameterList());
     }
     RefactoringConflictsUtil.analyzeModuleConflicts(subclass.getProject(), checkModuleConflictsList,
                                            new UsageInfo[0], targetRepresentativeElement, conflicts);
@@ -190,8 +191,8 @@
     return conflicts;
   }
 
-  private static void checkInterfaceTarget(MemberInfo[] infos, MultiMap<PsiElement, String> conflictsList) {
-    for (MemberInfo info : infos) {
+  private static void checkInterfaceTarget(MemberInfoBase<? extends PsiMember>[] infos, MultiMap<PsiElement, String> conflictsList) {
+    for (MemberInfoBase<? extends PsiMember> info : infos) {
       PsiElement member = info.getMember();
 
       if (member instanceof PsiField || member instanceof PsiClass) {
@@ -214,9 +215,9 @@
   }
 
   private static void checkSuperclassMembers(PsiClass superClass,
-                                             MemberInfo[] infos,
+                                             MemberInfoBase<? extends PsiMember>[] infos,
                                              MultiMap<PsiElement, String> conflictsList) {
-    for (MemberInfo info : infos) {
+    for (MemberInfoBase<? extends PsiMember> info : infos) {
       PsiMember member = info.getMember();
       boolean isConflict = false;
       if (member instanceof PsiField) {
@@ -268,7 +269,7 @@
     return false;
   }
 
-  private static class ConflictingUsagesOfSuperClassMemebers extends ClassMemberReferencesVisitor {
+  private static class ConflictingUsagesOfSuperClassMembers extends ClassMemberReferencesVisitor {
 
     private PsiMember myMember;
     private PsiClass mySubClass;
@@ -276,10 +277,10 @@
     private Set<PsiMember> myMovedMembers;
     private MultiMap<PsiElement, String> myConflicts;
 
-    public ConflictingUsagesOfSuperClassMemebers(PsiMember member, PsiClass aClass,
-                                                 PsiPackage targetPackage,
-                                                 Set<PsiMember> movedMembers,
-                                                 MultiMap<PsiElement, String> conflicts) {
+    public ConflictingUsagesOfSuperClassMembers(PsiMember member, PsiClass aClass,
+                                                PsiPackage targetPackage,
+                                                Set<PsiMember> movedMembers,
+                                                MultiMap<PsiElement, String> conflicts) {
       super(aClass);
       myMember = member;
       mySubClass = aClass;
diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java
index 526262e..6af5d47 100644
--- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java
@@ -28,43 +28,40 @@
 import com.intellij.refactoring.HelpID;
 import com.intellij.refactoring.JavaRefactoringSettings;
 import com.intellij.refactoring.RefactoringBundle;
-import com.intellij.refactoring.classMembers.MemberInfoChange;
+import com.intellij.refactoring.classMembers.MemberInfoModel;
+import com.intellij.refactoring.ui.AbstractMemberSelectionTable;
 import com.intellij.refactoring.ui.ClassCellRenderer;
 import com.intellij.refactoring.ui.DocCommentPanel;
-import com.intellij.refactoring.ui.MemberSelectionPanel;
-import com.intellij.refactoring.ui.RefactoringDialog;
+import com.intellij.refactoring.ui.MemberSelectionTable;
 import com.intellij.refactoring.util.DocCommentPolicy;
 import com.intellij.refactoring.util.RefactoringHierarchyUtil;
 import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier;
 import com.intellij.refactoring.util.classMembers.MemberInfo;
 import com.intellij.refactoring.util.classMembers.MemberInfoStorage;
 import com.intellij.refactoring.util.classMembers.UsesAndInterfacesDependencyMemberInfoModel;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.awt.*;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
-import java.util.ArrayList;
 import java.util.List;
 
 /**
  * @author dsl
  * Date: 18.06.2002
  */
-public class PullUpDialog extends RefactoringDialog {
+public class PullUpDialog extends PullUpDialogBase<MemberInfoStorage, MemberInfo, PsiMember, PsiClass> {
   private final Callback myCallback;
-  private MemberSelectionPanel myMemberSelectionPanel;
-  private MyMemberInfoModel myMemberInfoModel;
-  private final PsiClass myClass;
-  private final List<PsiClass> mySuperClasses;
-  private final MemberInfoStorage myMemberInfoStorage;
-  private List<MemberInfo> myMemberInfos;
   private DocCommentPanel myJavaDocPanel;
-  private JComboBox myClassCombo;
+
+  private final InterfaceContainmentVerifier myInterfaceContainmentVerifier = new InterfaceContainmentVerifier() {
+    public boolean checkedInterfacesContain(PsiMethod psiMethod) {
+      return PullUpHelper.checkedInterfacesContain(myMemberInfos, psiMethod);
+    }
+  };
+
   private static final String PULL_UP_STATISTICS_KEY = "pull.up##";
 
   public interface Callback {
@@ -72,42 +69,16 @@
   }
 
   public PullUpDialog(Project project, PsiClass aClass, List<PsiClass> superClasses, MemberInfoStorage memberInfoStorage, Callback callback) {
-    super(project, true);
-    myClass = aClass;
-    mySuperClasses = superClasses;
-    myMemberInfoStorage = memberInfoStorage;
-    myMemberInfos = myMemberInfoStorage.getClassMemberInfos(aClass);
+    super(project, aClass, superClasses, memberInfoStorage, JavaPullUpHandler.REFACTORING_NAME);
     myCallback = callback;
 
-    setTitle(JavaPullUpHandler.REFACTORING_NAME);
-
     init();
   }
 
-  @Nullable
-  public PsiClass getSuperClass() {
-    if (myClassCombo != null) {
-      return (PsiClass) myClassCombo.getSelectedItem();
-    }
-    else {
-      return null;
-    }
-  }
-
   public int getJavaDocPolicy() {
     return myJavaDocPanel.getPolicy();
   }
 
-  public MemberInfo[] getSelectedMemberInfos() {
-    ArrayList<MemberInfo> list = new ArrayList<MemberInfo>(myMemberInfos.size());
-    for (MemberInfo info : myMemberInfos) {
-      if (info.isChecked() && myMemberInfoModel.isMemberEnabled(info)) {
-        list.add(info);
-      }
-    }
-    return list.toArray(new MemberInfo[list.size()]);
-  }
-
   protected String getDimensionServiceKey() {
     return "#com.intellij.refactoring.memberPullUp.PullUpDialog";
   }
@@ -116,51 +87,23 @@
     return myInterfaceContainmentVerifier;
   }
 
-  protected JComponent createNorthPanel() {
-    JPanel panel = new JPanel();
-
-    panel.setLayout(new GridBagLayout());
-    GridBagConstraints gbConstraints = new GridBagConstraints();
-
-    gbConstraints.insets = new Insets(4, 0, 4, 8);
-    gbConstraints.weighty = 1;
-    gbConstraints.weightx = 1;
-    gbConstraints.gridy = 0;
-    gbConstraints.gridwidth = GridBagConstraints.REMAINDER;
-    gbConstraints.fill = GridBagConstraints.BOTH;
-    gbConstraints.anchor = GridBagConstraints.WEST;
-    final JLabel classComboLabel = new JLabel();
-    panel.add(classComboLabel, gbConstraints);
-
-    myClassCombo = new JComboBox(mySuperClasses.toArray());
-    myClassCombo.setRenderer(new ClassCellRenderer(myClassCombo.getRenderer()));
-    classComboLabel.setText(RefactoringBundle.message("pull.up.members.to", UsageViewUtil.getLongName(myClass)));
-    classComboLabel.setLabelFor(myClassCombo);
-    final PsiClass preselection = getPreselection();
-    int indexToSelect = 0;
-    if (preselection != null) {
-      indexToSelect = mySuperClasses.indexOf(preselection);
-    }
-    myClassCombo.setSelectedIndex(indexToSelect);
-    myClassCombo.addItemListener(new ItemListener() {
+  @Override
+  protected void initClassCombo(JComboBox classCombo) {
+    classCombo.setRenderer(new ClassCellRenderer(classCombo.getRenderer()));
+    classCombo.addItemListener(new ItemListener() {
       public void itemStateChanged(ItemEvent e) {
         if (e.getStateChange() == ItemEvent.SELECTED) {
-          updateMemberInfo();
           if (myMemberSelectionPanel != null) {
-            myMemberInfoModel.setSuperClass(getSuperClass());
+            ((MyMemberInfoModel)myMemberInfoModel).setSuperClass(getSuperClass());
             myMemberSelectionPanel.getTable().setMemberInfos(myMemberInfos);
             myMemberSelectionPanel.getTable().fireExternalDataChange();
           }
         }
       }
     });
-    gbConstraints.gridy++;
-    panel.add(myClassCombo, gbConstraints);
-
-    return panel;
   }
 
-  private PsiClass getPreselection() {
+  protected PsiClass getPreselection() {
     PsiClass preselection = RefactoringHierarchyUtil.getNearestBaseClass(myClass, false);
 
     final String statKey = PULL_UP_STATISTICS_KEY + myClass.getQualifiedName();
@@ -185,15 +128,6 @@
     HelpManager.getInstance().invokeHelp(HelpID.MEMBERS_PULL_UP);
   }
 
-  private void updateMemberInfo() {
-    final PsiClass targetClass = (PsiClass) myClassCombo.getSelectedItem();
-    myMemberInfos = myMemberInfoStorage.getIntermediateMemberInfosList(targetClass);
-    /*Set duplicate = myMemberInfoStorage.getDuplicatedMemberInfos(targetClass);
-    for (Iterator iterator = duplicate.getSectionsIterator(); getSectionsIterator.hasNext();) {
-      ((MemberInfo) iterator.next()).setChecked(false);
-    }*/
-  }
-
   protected void doAction() {
     if (!myCallback.checkConflicts(this)) return;
     JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC = myJavaDocPanel.getPolicy();
@@ -203,21 +137,15 @@
       StatisticsManager
         .getInstance().incUseCount(new StatisticsInfo(PULL_UP_STATISTICS_KEY + myClass.getQualifiedName(), name));
     }
-    
-    invokeRefactoring(new PullUpHelper(myClass, superClass, getSelectedMemberInfos(),
+
+    List<MemberInfo> infos = getSelectedMemberInfos();
+    invokeRefactoring(new PullUpHelper(myClass, superClass, infos.toArray(new MemberInfo[infos.size()]),
                                                new DocCommentPolicy(getJavaDocPolicy())));
     close(OK_EXIT_CODE);
   }
 
-  protected JComponent createCenterPanel() {
-    JPanel panel = new JPanel(new BorderLayout());
-    myMemberSelectionPanel = new MemberSelectionPanel(RefactoringBundle.message("members.to.be.pulled.up"), myMemberInfos, RefactoringBundle.message("make.abstract"));
-    myMemberInfoModel = new MyMemberInfoModel();
-    myMemberInfoModel.memberInfoChanged(new MemberInfoChange<PsiMember, MemberInfo>(myMemberInfos));
-    myMemberSelectionPanel.getTable().setMemberInfoModel(myMemberInfoModel);
-    myMemberSelectionPanel.getTable().addMemberInfoChangeListener(myMemberInfoModel);
-    panel.add(myMemberSelectionPanel, BorderLayout.CENTER);
-
+  @Override
+  protected void addCustomElementsToCentralPanel(JPanel panel) {
     myJavaDocPanel = new DocCommentPanel(RefactoringBundle.message("javadoc.for.abstracts"));
     myJavaDocPanel.setPolicy(JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC);
     boolean hasJavadoc = false;
@@ -233,14 +161,17 @@
     }
     UIUtil.setEnabled(myJavaDocPanel, hasJavadoc, true);
     panel.add(myJavaDocPanel, BorderLayout.EAST);
-    return panel;
   }
-  private final InterfaceContainmentVerifier myInterfaceContainmentVerifier =
-    new InterfaceContainmentVerifier() {
-      public boolean checkedInterfacesContain(PsiMethod psiMethod) {
-        return PullUpHelper.checkedInterfacesContain(myMemberInfos, psiMethod);
-      }
-    };
+
+  @Override
+  protected AbstractMemberSelectionTable<PsiMember, MemberInfo> createMemberSelectionTable(List<MemberInfo> infos) {
+    return new MemberSelectionTable(infos, RefactoringBundle.message("make.abstract"));
+  }
+
+  @Override
+  protected MemberInfoModel<PsiMember, MemberInfo> createMemberInfoModel() {
+    return new MyMemberInfoModel();
+  }
 
   private class MyMemberInfoModel extends UsesAndInterfacesDependencyMemberInfoModel {
     public MyMemberInfoModel() {
@@ -296,11 +227,9 @@
       PsiClass currentSuperClass = getSuperClass();
 
       if (currentSuperClass != null && currentSuperClass.isInterface()) {
-        PsiElement element = member.getMember();
-        if (element instanceof PsiModifierListOwner) {
-          if (((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC)) {
-            return super.checkForProblems(member);
-          }
+        PsiMember element = member.getMember();
+        if (element.hasModifierProperty(PsiModifier.STATIC)) {
+          return super.checkForProblems(member);
         }
         return OK;
       }
diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java
index ea230e3..bde3f6c 100644
--- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java
+++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java
@@ -47,6 +47,7 @@
 import com.intellij.psi.util.*;
 import com.intellij.refactoring.BaseRefactoringProcessor;
 import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
 import com.intellij.refactoring.listeners.JavaRefactoringListenerManager;
 import com.intellij.refactoring.listeners.impl.JavaRefactoringListenerManagerImpl;
 import com.intellij.refactoring.util.*;
@@ -67,7 +68,7 @@
 
 public class PullUpHelper extends BaseRefactoringProcessor{
   private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.memberPullUp.PullUpHelper");
-  private static final Key<Boolean> PRESERVE_QUALIFIER = Key.<Boolean>create("PRESERVE_QUALIFIER");
+  private static final Key<Boolean> PRESERVE_QUALIFIER = Key.create("PRESERVE_QUALIFIER");
   private final PsiClass mySourceClass;
   private final PsiClass myTargetSuperClass;
   private final boolean myIsTargetInterface;
@@ -169,158 +170,22 @@
     // correct private member visibility
     for (MemberInfo info : myMembersToMove) {
       if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue;
-      PsiModifierListOwner modifierListOwner = info.getMember();
-      if (myIsTargetInterface) {
-        PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true);
-      }
-      else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) {
-        if (info.isToAbstract() || willBeUsedInSubclass(modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) {
-          PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true);
-        }
-        if (modifierListOwner instanceof PsiClass) {
-          modifierListOwner.accept(new JavaRecursiveElementWalkingVisitor() {
-            @Override
-            public void visitMethod(PsiMethod method) {
-              check(method);
-            }
-
-            @Override
-            public void visitField(PsiField field) {
-              check(field);
-            }
-
-            @Override
-            public void visitClass(PsiClass aClass) {
-              check(aClass);
-              super.visitClass(aClass);
-            }
-
-            private void check(PsiMember member) {
-              if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
-                if (willBeUsedInSubclass(member, movedMembers, myTargetSuperClass, mySourceClass)) {
-                  PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true);
-                }
-              }
-            }
-          });
-        }
-      }
+      setCorrectVisibility(movedMembers, info);
       ChangeContextUtil.encodeContextInfo(info.getMember(), true);
     }
 
     final PsiSubstitutor substitutor = upDownSuperClassSubstitutor();
-    final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
 
     // do actual move
     for (MemberInfo info : myMembersToMove) {
       if (info.getMember() instanceof PsiMethod) {
-        PsiMethod method = (PsiMethod)info.getMember();
-        PsiMethod sibling = method;
-        PsiMethod anchor = null;
-        while (sibling != null) {
-          sibling = PsiTreeUtil.getNextSiblingOfType(sibling, PsiMethod.class);
-          if (sibling != null) {
-            anchor = MethodSignatureUtil
-              .findMethodInSuperClassBySignatureInDerived(method.getContainingClass(), myTargetSuperClass,
-                                                          sibling.getSignature(PsiSubstitutor.EMPTY), false);
-            if (anchor != null) {
-              break;
-            }
-          }
-        }
-        PsiMethod methodCopy = (PsiMethod)method.copy();
-        if (method.findSuperMethods(myTargetSuperClass).length == 0) {
-          deleteOverrideAnnotationIfFound(methodCopy);
-        }
-        boolean isOriginalMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.DEFAULT);
-        if (myIsTargetInterface || info.isToAbstract()) {
-          ChangeContextUtil.clearContextInfo(method);
-
-          if (!info.isToAbstract() && !method.hasModifierProperty(PsiModifier.ABSTRACT) && PsiUtil.isLanguageLevel8OrHigher(myTargetSuperClass)) {
-            //pull as default
-            RefactoringUtil.makeMethodDefault(methodCopy);
-            isOriginalMethodAbstract = true;
-          } else {
-            RefactoringUtil.makeMethodAbstract(myTargetSuperClass, methodCopy);
-          }
-
-          RefactoringUtil.replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
-
-          myJavaDocPolicy.processCopiedJavaDoc(methodCopy.getDocComment(), method.getDocComment(), isOriginalMethodAbstract);
-
-          final PsiMember movedElement = anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
-          CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject());
-          if (styleSettings.INSERT_OVERRIDE_ANNOTATION) {
-            if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myTargetSuperClass.isInterface() || PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) {
-              new AddAnnotationFix(Override.class.getName(), method).invoke(method.getProject(), null, mySourceClass.getContainingFile());
-            }
-          }
-          if (!PsiUtil.isLanguageLevel6OrHigher(mySourceClass) && myTargetSuperClass.isInterface()) {
-            if (isOriginalMethodAbstract) {
-              for (PsiMethod oMethod : OverridingMethodsSearch.search(method)) {
-                deleteOverrideAnnotationIfFound(oMethod);
-              }
-            }
-            deleteOverrideAnnotationIfFound(method);
-          }
-          myMembersAfterMove.add(movedElement);
-          if (isOriginalMethodAbstract) {
-            method.delete();
-          }
-        }
-        else {
-          if (isOriginalMethodAbstract) {
-            PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true);
-          }
-          RefactoringUtil.replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
-          fixReferencesToStatic(methodCopy, movedMembers);
-          final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false);
-          if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
-            superClassMethod.replace(methodCopy);
-          }
-          else {
-            final PsiMember movedElement =
-              anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
-            myMembersAfterMove.add(movedElement);
-          }
-          method.delete();
-        }
+        doMoveMethod(movedMembers, substitutor, info);
       }
       else if (info.getMember() instanceof PsiField) {
-        PsiField field = (PsiField)info.getMember();
-        field.normalizeDeclaration();
-        RefactoringUtil.replaceMovedMemberTypeParameters(field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
-        fixReferencesToStatic(field, movedMembers);
-        if (myIsTargetInterface) {
-          PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true);
-        }
-        final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(field);
-        myMembersAfterMove.add(movedElement);
-        field.delete();
+        doMoveField(movedMembers, substitutor, info);
       }
       else if (info.getMember() instanceof PsiClass) {
-        PsiClass aClass = (PsiClass)info.getMember();
-        if (Boolean.FALSE.equals(info.getOverrides())) {
-          final PsiReferenceList sourceReferenceList = info.getSourceReferenceList();
-          LOG.assertTrue(sourceReferenceList != null);
-          PsiJavaCodeReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ?
-                                            RefactoringUtil.removeFromReferenceList(sourceReferenceList, aClass) :
-                                            RefactoringUtil.findReferenceToClass(sourceReferenceList, aClass);
-          if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) {
-            RefactoringUtil.replaceMovedMemberTypeParameters(ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
-            final PsiReferenceList referenceList =
-              myTargetSuperClass.isInterface() ? myTargetSuperClass.getExtendsList() : myTargetSuperClass.getImplementsList();
-            assert referenceList != null;
-            referenceList.add(ref);
-          }
-        }
-        else {
-          RefactoringUtil.replaceMovedMemberTypeParameters(aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
-          fixReferencesToStatic(aClass, movedMembers);
-          final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(aClass);
-          myMembersAfterMove.add(movedElement);
-          aClass.delete();
-        }
+        doMoveClass(movedMembers, substitutor, info);
       }
     }
 
@@ -357,6 +222,160 @@
     }
   }
 
+  private void setCorrectVisibility(final Set<PsiMember> movedMembers, MemberInfo info) {
+    PsiModifierListOwner modifierListOwner = info.getMember();
+    if (myIsTargetInterface) {
+      PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true);
+    }
+    else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) {
+      if (info.isToAbstract() || willBeUsedInSubclass(modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) {
+        PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true);
+      }
+      if (modifierListOwner instanceof PsiClass) {
+        modifierListOwner.accept(new JavaRecursiveElementWalkingVisitor() {
+          @Override
+          public void visitMethod(PsiMethod method) {
+            check(method);
+          }
+
+          @Override
+          public void visitField(PsiField field) {
+            check(field);
+          }
+
+          @Override
+          public void visitClass(PsiClass aClass) {
+            check(aClass);
+            super.visitClass(aClass);
+          }
+
+          private void check(PsiMember member) {
+            if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
+              if (willBeUsedInSubclass(member, movedMembers, myTargetSuperClass, mySourceClass)) {
+                PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true);
+              }
+            }
+          }
+        });
+      }
+    }
+  }
+
+  private void doMoveClass(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, MemberInfo info) {
+    PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
+    PsiClass aClass = (PsiClass)info.getMember();
+    if (Boolean.FALSE.equals(info.getOverrides())) {
+      final PsiReferenceList sourceReferenceList = info.getSourceReferenceList();
+      LOG.assertTrue(sourceReferenceList != null);
+      PsiJavaCodeReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ?
+                                        RefactoringUtil.removeFromReferenceList(sourceReferenceList, aClass) :
+                                        RefactoringUtil.findReferenceToClass(sourceReferenceList, aClass);
+      if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) {
+        RefactoringUtil.replaceMovedMemberTypeParameters(ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+        final PsiReferenceList referenceList =
+          myTargetSuperClass.isInterface() ? myTargetSuperClass.getExtendsList() : myTargetSuperClass.getImplementsList();
+        assert referenceList != null;
+        referenceList.add(ref);
+      }
+    }
+    else {
+      RefactoringUtil.replaceMovedMemberTypeParameters(aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+      fixReferencesToStatic(aClass, movedMembers);
+      final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(aClass);
+      myMembersAfterMove.add(movedElement);
+      aClass.delete();
+    }
+  }
+
+  private void doMoveField(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, MemberInfo info) {
+    PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
+    PsiField field = (PsiField)info.getMember();
+    field.normalizeDeclaration();
+    RefactoringUtil.replaceMovedMemberTypeParameters(field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+    fixReferencesToStatic(field, movedMembers);
+    if (myIsTargetInterface) {
+      PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true);
+    }
+    final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(field);
+    myMembersAfterMove.add(movedElement);
+    field.delete();
+  }
+
+  private void doMoveMethod(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, MemberInfo info) {
+    PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
+    PsiMethod method = (PsiMethod)info.getMember();
+    PsiMethod sibling = method;
+    PsiMethod anchor = null;
+    while (sibling != null) {
+      sibling = PsiTreeUtil.getNextSiblingOfType(sibling, PsiMethod.class);
+      if (sibling != null) {
+        anchor = MethodSignatureUtil
+          .findMethodInSuperClassBySignatureInDerived(method.getContainingClass(), myTargetSuperClass,
+                                                      sibling.getSignature(PsiSubstitutor.EMPTY), false);
+        if (anchor != null) {
+          break;
+        }
+      }
+    }
+    PsiMethod methodCopy = (PsiMethod)method.copy();
+    if (method.findSuperMethods(myTargetSuperClass).length == 0) {
+      deleteOverrideAnnotationIfFound(methodCopy);
+    }
+    boolean isOriginalMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.DEFAULT);
+    if (myIsTargetInterface || info.isToAbstract()) {
+      ChangeContextUtil.clearContextInfo(method);
+
+      if (!info.isToAbstract() && !method.hasModifierProperty(PsiModifier.ABSTRACT) && PsiUtil.isLanguageLevel8OrHigher(myTargetSuperClass)) {
+        //pull as default
+        RefactoringUtil.makeMethodDefault(methodCopy);
+        isOriginalMethodAbstract = true;
+      } else {
+        RefactoringUtil.makeMethodAbstract(myTargetSuperClass, methodCopy);
+      }
+
+      RefactoringUtil.replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+
+      myJavaDocPolicy.processCopiedJavaDoc(methodCopy.getDocComment(), method.getDocComment(), isOriginalMethodAbstract);
+
+      final PsiMember movedElement = anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
+      CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject());
+      if (styleSettings.INSERT_OVERRIDE_ANNOTATION) {
+        if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myTargetSuperClass.isInterface() || PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) {
+          new AddAnnotationFix(Override.class.getName(), method).invoke(method.getProject(), null, mySourceClass.getContainingFile());
+        }
+      }
+      if (!PsiUtil.isLanguageLevel6OrHigher(mySourceClass) && myTargetSuperClass.isInterface()) {
+        if (isOriginalMethodAbstract) {
+          for (PsiMethod oMethod : OverridingMethodsSearch.search(method)) {
+            deleteOverrideAnnotationIfFound(oMethod);
+          }
+        }
+        deleteOverrideAnnotationIfFound(method);
+      }
+      myMembersAfterMove.add(movedElement);
+      if (isOriginalMethodAbstract) {
+        method.delete();
+      }
+    }
+    else {
+      if (isOriginalMethodAbstract) {
+        PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true);
+      }
+      RefactoringUtil.replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+      fixReferencesToStatic(methodCopy, movedMembers);
+      final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false);
+      if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
+        superClassMethod.replace(methodCopy);
+      }
+      else {
+        final PsiMember movedElement =
+          anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
+        myMembersAfterMove.add(movedElement);
+      }
+      method.delete();
+    }
+  }
+
   private PsiSubstitutor upDownSuperClassSubstitutor() {
     PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
     for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(mySourceClass)) {
@@ -909,8 +928,8 @@
     return false;
   }
 
-  public static boolean checkedInterfacesContain(Collection<MemberInfo> memberInfos, PsiMethod psiMethod) {
-    for (MemberInfo memberInfo : memberInfos) {
+  public static boolean checkedInterfacesContain(Collection<? extends MemberInfoBase<? extends PsiMember>> memberInfos, PsiMethod psiMethod) {
+    for (MemberInfoBase<? extends PsiMember> memberInfo : memberInfos) {
       if (memberInfo.isChecked() &&
           memberInfo.getMember() instanceof PsiClass &&
           Boolean.FALSE.equals(memberInfo.getOverrides())) {
diff --git a/java/java-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java b/java/java-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java
deleted file mode 100644
index 0e9397a..0000000
--- a/java/java-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.intellij.refactoring.ui;
-
-import com.intellij.psi.PsiElement;
-import com.intellij.refactoring.classMembers.MemberInfoBase;
-
-import javax.swing.*;
-
-/**
- * Nikolay.Tropin
- * 8/20/13
- */
-public abstract class AbstractMemberSelectionPanel<T extends PsiElement, M extends MemberInfoBase<T>> extends JPanel {
-  public abstract AbstractMemberSelectionTable<T, M> getTable();
-}
diff --git a/java/java-impl/src/com/intellij/refactoring/ui/MemberSelectionPanel.java b/java/java-impl/src/com/intellij/refactoring/ui/MemberSelectionPanel.java
index c503a86..28e0a88 100644
--- a/java/java-impl/src/com/intellij/refactoring/ui/MemberSelectionPanel.java
+++ b/java/java-impl/src/com/intellij/refactoring/ui/MemberSelectionPanel.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.
diff --git a/java/java-impl/src/com/intellij/slicer/DuplicateMap.java b/java/java-impl/src/com/intellij/slicer/DuplicateMap.java
index a57dc5f..426efd1 100644
--- a/java/java-impl/src/com/intellij/slicer/DuplicateMap.java
+++ b/java/java-impl/src/com/intellij/slicer/DuplicateMap.java
@@ -21,6 +21,7 @@
 import com.intellij.usageView.UsageInfo;
 import gnu.trove.THashMap;
 import gnu.trove.TObjectHashingStrategy;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.Map;
 
@@ -43,7 +44,7 @@
   };
   private final Map<SliceUsage, SliceNode> myDuplicates = new THashMap<SliceUsage, SliceNode>(USAGE_INFO_EQUALITY);
 
-  public SliceNode putNodeCheckDupe(final SliceNode node) {
+  public SliceNode putNodeCheckDupe(@NotNull final SliceNode node) {
     return ApplicationManager.getApplication().runReadAction(new Computable<SliceNode>() {
       @Override
       public SliceNode compute() {
diff --git a/java/java-impl/src/com/intellij/slicer/MyColoredTreeCellRenderer.java b/java/java-impl/src/com/intellij/slicer/MyColoredTreeCellRenderer.java
index 0e31373..c150e0f 100644
--- a/java/java-impl/src/com/intellij/slicer/MyColoredTreeCellRenderer.java
+++ b/java/java-impl/src/com/intellij/slicer/MyColoredTreeCellRenderer.java
@@ -15,12 +15,20 @@
  */
 package com.intellij.slicer;
 
+import org.jetbrains.annotations.NotNull;
+
 import javax.swing.*;
 
 /**
  * @author cdr
  */
 public interface MyColoredTreeCellRenderer {
-  void customizeCellRenderer(SliceUsageCellRenderer renderer,
-                             JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus);
+  void customizeCellRenderer(@NotNull SliceUsageCellRenderer renderer,
+                             @NotNull JTree tree,
+                             Object value,
+                             boolean selected,
+                             boolean expanded,
+                             boolean leaf,
+                             int row,
+                             boolean hasFocus);
 }
diff --git a/java/java-impl/src/com/intellij/slicer/SliceDereferenceUsage.java b/java/java-impl/src/com/intellij/slicer/SliceDereferenceUsage.java
index 106671f..8578c91 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceDereferenceUsage.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceDereferenceUsage.java
@@ -33,7 +33,7 @@
   }
 
   @Override
-  public void processChildren(Processor<SliceUsage> processor) {
+  public void processChildren(@NotNull Processor<SliceUsage> processor) {
     // no children
   }
 
diff --git a/java/java-impl/src/com/intellij/slicer/SliceForwardUtil.java b/java/java-impl/src/com/intellij/slicer/SliceForwardUtil.java
new file mode 100644
index 0000000..364b853
--- /dev/null
+++ b/java/java-impl/src/com/intellij/slicer/SliceForwardUtil.java
@@ -0,0 +1,274 @@
+/*
+ * 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.slicer;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.*;
+import com.intellij.psi.search.searches.MethodReferencesSearch;
+import com.intellij.psi.search.searches.OverridingMethodsSearch;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.MethodSignatureUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Processor;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author cdr
+ */
+public class SliceForwardUtil {
+  public static boolean processUsagesFlownFromThe(@NotNull PsiElement element, @NotNull final Processor<SliceUsage> processor, @NotNull final SliceUsage parent) {
+    Pair<PsiElement, PsiSubstitutor> pair = getAssignmentTarget(element, parent);
+    if (pair != null) {
+      PsiElement target = pair.getFirst();
+      final PsiSubstitutor substitutor = pair.getSecond();
+      if (target instanceof PsiParameter) {
+        PsiParameter parameter = (PsiParameter)target;
+        PsiElement declarationScope = parameter.getDeclarationScope();
+        if (declarationScope instanceof PsiMethod) {
+          final PsiMethod method = (PsiMethod)declarationScope;
+          final int parameterIndex = method.getParameterList().getParameterIndex(parameter);
+
+          Processor<PsiMethod> myProcessor = new Processor<PsiMethod>() {
+            @Override
+            public boolean process(PsiMethod override) {
+              if (!parent.getScope().contains(override)) return true;
+              final PsiSubstitutor superSubstitutor = method == override
+                                                      ? substitutor
+                                                      : MethodSignatureUtil.getSuperMethodSignatureSubstitutor(method.getSignature(substitutor),
+                                                                                            override.getSignature(substitutor));
+
+              PsiParameter[] parameters = override.getParameterList().getParameters();
+              if (parameters.length <= parameterIndex) return true;
+              PsiParameter actualParam = parameters[parameterIndex];
+
+              SliceUsage usage = SliceUtil.createSliceUsage(actualParam, parent, superSubstitutor);
+              return processor.process(usage);
+            }
+          };
+          if (!myProcessor.process(method)) return false;
+          return OverridingMethodsSearch.search(method, parent.getScope().toSearchScope(), true).forEach(myProcessor);
+        }
+      }
+
+      SliceUsage usage = SliceUtil.createSliceUsage(target, parent, parent.getSubstitutor());
+      return processor.process(usage);
+    }
+
+    if (element instanceof PsiReferenceExpression) {
+      PsiReferenceExpression ref = (PsiReferenceExpression)element;
+      PsiElement resolved = ref.resolve();
+      if (!(resolved instanceof PsiVariable)) return true;
+      final PsiVariable variable = (PsiVariable)resolved;
+      return processAssignedFrom(variable, ref, parent, processor);
+    }
+    if (element instanceof PsiVariable) {
+      return processAssignedFrom(element, element, parent, processor);
+    }
+    if (element instanceof PsiMethod) {
+      return processAssignedFrom(element, element, parent, processor);
+    }
+    return true;
+  }
+
+  private static boolean processAssignedFrom(final PsiElement from, final PsiElement context, final SliceUsage parent,
+                                                 final Processor<SliceUsage> processor) {
+    if (from instanceof PsiLocalVariable) {
+      return searchReferencesAndProcessAssignmentTarget(from, context, parent, processor);
+    }
+    if (from instanceof PsiParameter) {
+      PsiParameter parameter = (PsiParameter)from;
+      PsiElement scope = parameter.getDeclarationScope();
+      Collection<PsiParameter> parametersToAnalyze = new THashSet<PsiParameter>();
+      if (scope instanceof PsiMethod) {
+        final PsiMethod method = (PsiMethod)scope;
+        int index = method.getParameterList().getParameterIndex(parameter);
+
+        Collection<PsiMethod> superMethods = new THashSet<PsiMethod>(Arrays.asList(method.findDeepestSuperMethods()));
+        superMethods.add(method);
+        for (Iterator<PsiMethod> iterator = superMethods.iterator(); iterator.hasNext(); ) {
+          SliceManager.getInstance(method.getProject()).checkCanceled();
+          PsiMethod superMethod = iterator.next();
+          if (!parent.params.scope.contains(superMethod)) {
+            iterator.remove();
+          }
+        }
+
+        final THashSet<PsiMethod> implementors = new THashSet<PsiMethod>(superMethods);
+        for (PsiMethod superMethod : superMethods) {
+          SliceManager.getInstance(method.getProject()).checkCanceled();
+          if (!OverridingMethodsSearch.search(superMethod, parent.getScope().toSearchScope(), true).forEach(new Processor<PsiMethod>() {
+            @Override
+            public boolean process(PsiMethod sub) {
+              SliceManager.getInstance(method.getProject()).checkCanceled();
+              implementors.add(sub);
+              return true;
+            }
+          })) return false;
+        }
+        for (PsiMethod implementor : implementors) {
+          SliceManager.getInstance(method.getProject()).checkCanceled();
+          if (!parent.params.scope.contains(implementor)) continue;
+          if (implementor instanceof PsiCompiledElement) implementor = (PsiMethod)implementor.getNavigationElement();
+
+          PsiParameter[] parameters = implementor.getParameterList().getParameters();
+          if (index != -1 && index < parameters.length) {
+            parametersToAnalyze.add(parameters[index]);
+          }
+        }
+      }
+      else {
+        parametersToAnalyze.add(parameter);
+      }
+      for (final PsiParameter psiParameter : parametersToAnalyze) {
+        SliceManager.getInstance(from.getProject()).checkCanceled();
+
+        if (!searchReferencesAndProcessAssignmentTarget(psiParameter, null, parent, processor)) return false;
+      }
+      return true;
+    }
+    if (from instanceof PsiField) {
+      return searchReferencesAndProcessAssignmentTarget(from, null, parent, processor);
+    }
+
+    if (from instanceof PsiMethod) {
+      PsiMethod method = (PsiMethod)from;
+
+      Collection<PsiMethod> superMethods = new THashSet<PsiMethod>(Arrays.asList(method.findDeepestSuperMethods()));
+      superMethods.add(method);
+      final Set<PsiReference> processed = new THashSet<PsiReference>(); //usages of super method and overridden method can overlap
+      for (final PsiMethod containingMethod : superMethods) {
+        if (!MethodReferencesSearch.search(containingMethod, parent.getScope().toSearchScope(), true).forEach(new Processor<PsiReference>() {
+            @Override
+            public boolean process(final PsiReference reference) {
+              SliceManager.getInstance(from.getProject()).checkCanceled();
+              synchronized (processed) {
+                if (!processed.add(reference)) return true;
+              }
+              PsiElement element = reference.getElement().getParent();
+
+              return processAssignmentTarget(element, parent, processor);
+            }
+          })) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  private static boolean searchReferencesAndProcessAssignmentTarget(@NotNull PsiElement element, @Nullable final PsiElement context, final SliceUsage parent,
+                                                                    final Processor<SliceUsage> processor) {
+    return ReferencesSearch.search(element).forEach(new Processor<PsiReference>() {
+      @Override
+      public boolean process(PsiReference reference) {
+        PsiElement element = reference.getElement();
+        if (context != null && element.getTextOffset() < context.getTextOffset()) return true;
+        return processAssignmentTarget(element, parent, processor);
+      }
+    });
+  }
+
+  private static boolean processAssignmentTarget(PsiElement element, final SliceUsage parent, final Processor<SliceUsage> processor) {
+    if (!parent.params.scope.contains(element)) return true;
+    if (element instanceof PsiCompiledElement) element = element.getNavigationElement();
+    Pair<PsiElement, PsiSubstitutor> pair = getAssignmentTarget(element, parent);
+    if (pair != null) {
+      SliceUsage usage = SliceUtil.createSliceUsage(element, parent, pair.getSecond());
+      return processor.process(usage);
+    }
+    if (parent.params.showInstanceDereferences && isDereferenced(element)) {
+      SliceUsage usage = new SliceDereferenceUsage(element.getParent(), parent, parent.getSubstitutor());
+      return processor.process(usage);
+    }
+    return true;
+  }
+
+  private static boolean isDereferenced(PsiElement element) {
+    if (!(element instanceof PsiReferenceExpression)) return false;
+    PsiElement parent = element.getParent();
+    if (!(parent instanceof PsiReferenceExpression)) return false;
+    return ((PsiReferenceExpression)parent).getQualifierExpression() == element;
+  }
+
+  private static Pair<PsiElement,PsiSubstitutor> getAssignmentTarget(PsiElement element, SliceUsage parentUsage) {
+    element = complexify(element);
+    PsiElement target = null;
+    PsiSubstitutor substitutor = parentUsage.getSubstitutor();
+    //assignment
+    PsiElement parent = element.getParent();
+    if (parent instanceof PsiAssignmentExpression) {
+      PsiAssignmentExpression assignment = (PsiAssignmentExpression)parent;
+      if (element.equals(assignment.getRExpression())) {
+        PsiElement left = assignment.getLExpression();
+        if (left instanceof PsiReferenceExpression) {
+          JavaResolveResult result = ((PsiReferenceExpression)left).advancedResolve(false);
+          target = result.getElement();
+          substitutor = result.getSubstitutor();
+        }
+      }
+    }
+    else if (parent instanceof PsiVariable) {
+      PsiVariable variable = (PsiVariable)parent;
+
+      PsiElement initializer = variable.getInitializer();
+      if (element.equals(initializer)) {
+        target = variable;
+      }
+    }
+    //method call
+    else if (parent instanceof PsiExpressionList && parent.getParent() instanceof PsiCallExpression) {
+      PsiExpression[] expressions = ((PsiExpressionList)parent).getExpressions();
+      int index = ArrayUtil.find(expressions, element);
+      PsiCallExpression methodCall = (PsiCallExpression)parent.getParent();
+      JavaResolveResult result = methodCall.resolveMethodGenerics();
+      PsiMethod method = (PsiMethod)result.getElement();
+      if (index != -1 && method != null) {
+        PsiParameter[] parameters = method.getParameterList().getParameters();
+        if (index < parameters.length) {
+          target = parameters[index];
+          substitutor = result.getSubstitutor();
+        }
+      }
+    }
+    else if (parent instanceof PsiReturnStatement) {
+      PsiReturnStatement statement = (PsiReturnStatement)parent;
+      if (element.equals(statement.getReturnValue())) {
+        target = PsiTreeUtil.getParentOfType(statement, PsiMethod.class);
+      }
+    }
+
+    return target == null ? null : Pair.create(target, substitutor);
+  }
+
+  public static PsiElement complexify(@NotNull PsiElement element) {
+    PsiElement parent = element.getParent();
+    if (parent instanceof PsiParenthesizedExpression && element.equals(((PsiParenthesizedExpression)parent).getExpression())) {
+      return complexify(parent);
+    }
+    if (parent instanceof PsiTypeCastExpression && element.equals(((PsiTypeCastExpression)parent).getOperand())) {
+      return complexify(parent);
+    }
+    return element;
+  }
+}
diff --git a/java/java-impl/src/com/intellij/slicer/SliceLeafValueClassNode.java b/java/java-impl/src/com/intellij/slicer/SliceLeafValueClassNode.java
index 630d1cd..e73da41 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceLeafValueClassNode.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceLeafValueClassNode.java
@@ -44,8 +44,8 @@
   }
 
   @Override
-  public void customizeCellRenderer(SliceUsageCellRenderer renderer,
-                                    JTree tree,
+  public void customizeCellRenderer(@NotNull SliceUsageCellRenderer renderer,
+                                    @NotNull JTree tree,
                                     Object value,
                                     boolean selected,
                                     boolean expanded,
diff --git a/java/java-impl/src/com/intellij/slicer/SliceLeafValueRootNode.java b/java/java-impl/src/com/intellij/slicer/SliceLeafValueRootNode.java
index a6a4030..dee98f8 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceLeafValueRootNode.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceLeafValueRootNode.java
@@ -40,7 +40,7 @@
 
   public SliceLeafValueRootNode(@NotNull Project project, PsiElement leafExpression, SliceNode root, List<SliceNode> children,
                                 SliceAnalysisParams params) {
-    super(project, new SliceUsage(leafExpression, params), root.targetEqualUsages);
+    super(project, SliceUsage.createRootUsage(leafExpression, params), root.targetEqualUsages);
     myCachedChildren = children;
   }
 
@@ -69,8 +69,8 @@
   }
 
   @Override
-  public void customizeCellRenderer(SliceUsageCellRenderer renderer,
-                                    JTree tree,
+  public void customizeCellRenderer(@NotNull SliceUsageCellRenderer renderer,
+                                    @NotNull JTree tree,
                                     Object value,
                                     boolean selected,
                                     boolean expanded,
@@ -99,8 +99,9 @@
                                         @NotNull final SliceUsageCellRenderer renderer) {
     PsiFile file = element.getContainingFile();
     List<TextChunk> result = new ArrayList<TextChunk>();
-    ChunkExtractor.getExtractor(element.getContainingFile()).createTextChunks(usage, file.getText(), element.getTextRange().getStartOffset(), element.getTextRange().getEndOffset(),
-                                                                              false, result);
+    ChunkExtractor.getExtractor(element.getContainingFile())
+      .createTextChunks(usage, file.getText(), element.getTextRange().getStartOffset(), element.getTextRange().getEndOffset(),
+                        false, result);
 
     for (TextChunk chunk : result) {
       renderer.append(chunk.getText(), chunk.getSimpleAttributesIgnoreBackground());
diff --git a/java/java-impl/src/com/intellij/slicer/SliceManager.java b/java/java-impl/src/com/intellij/slicer/SliceManager.java
index eee7e96..42cac25 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceManager.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceManager.java
@@ -124,7 +124,7 @@
     SliceAnalysisParams params = handler.askForParams(element, dataFlowToThis, myStoredSettings, dialogTitle);
     if (params == null) return;
 
-    SliceRootNode rootNode = new SliceRootNode(myProject, new DuplicateMap(), createRootUsage(element, params));
+    SliceRootNode rootNode = new SliceRootNode(myProject, new DuplicateMap(), SliceUsage.createRootUsage(element, params));
 
     createToolWindow(dataFlowToThis, rootNode, false, getElementDescription(null, element, null));
   }
@@ -179,10 +179,6 @@
            "</body></html>";
   }
 
-  public static SliceUsage createRootUsage(@NotNull PsiElement element, @NotNull SliceAnalysisParams params) {
-    return new SliceUsage(element, params);
-  }
-
   public void checkCanceled() throws ProcessCanceledException {
     if (myCanceled) {
       throw new ProcessCanceledException();
diff --git a/java/java-impl/src/com/intellij/slicer/SliceNode.java b/java/java-impl/src/com/intellij/slicer/SliceNode.java
index df114e5..cd79d79 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceNode.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceNode.java
@@ -20,7 +20,6 @@
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.progress.impl.ProgressManagerImpl;
 import com.intellij.openapi.progress.util.ProgressIndicatorBase;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Computable;
@@ -52,6 +51,7 @@
     this.targetEqualUsages = targetEqualUsages;
   }
 
+  @NotNull
   SliceNode copy() {
     SliceUsage newUsage = getValue().copy();
     SliceNode newNode = new SliceNode(getProject(), newUsage, targetEqualUsages);
@@ -69,7 +69,7 @@
       indicator.start();
     }
     final Collection[] nodes = new Collection[1];
-    ((ProgressManagerImpl)ProgressManager.getInstance()).executeProcessUnderProgress(new Runnable(){
+    ProgressManager.getInstance().executeProcessUnderProgress(new Runnable() {
       @Override
       public void run() {
         nodes[0] = getChildrenUnderProgress(ProgressManager.getInstance().getProgressIndicator());
@@ -89,6 +89,7 @@
     return index == 0 ? null : (SliceNode)parentChildren.get(index - 1);
   }
 
+  @NotNull
   protected List<? extends AbstractTreeNode> getChildrenUnderProgress(ProgressIndicator progress) {
     if (isUpToDate()) return myCachedChildren == null ? Collections.<AbstractTreeNode>emptyList() : myCachedChildren;
     final List<SliceNode> children = new ArrayList<SliceNode>();
@@ -208,7 +209,7 @@
   }
 
   @Override
-  public void customizeCellRenderer(SliceUsageCellRenderer renderer, JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+  public void customizeCellRenderer(@NotNull SliceUsageCellRenderer renderer, @NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
     renderer.setIcon(getPresentation().getIcon(expanded));
     if (isValid()) {
       SliceUsage sliceUsage = getValue();
@@ -227,6 +228,7 @@
   @Override
   public String toString() {
     return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+            @Override
             public String compute() {
               return getValue()==null?"<null>":getValue().toString();
             }
diff --git a/java/java-impl/src/com/intellij/slicer/SlicePanel.java b/java/java-impl/src/com/intellij/slicer/SlicePanel.java
index 7c40003..78e8a3e 100644
--- a/java/java-impl/src/com/intellij/slicer/SlicePanel.java
+++ b/java/java-impl/src/com/intellij/slicer/SlicePanel.java
@@ -189,13 +189,13 @@
   @NotNull
   private JTree createTree() {
     DefaultMutableTreeNode root = new DefaultMutableTreeNode();
-    final Tree tree = new Tree(new DefaultTreeModel(root)){
+    final Tree tree = new Tree(new DefaultTreeModel(root))/* {
       @Override
       protected void paintComponent(Graphics g) {
         DuplicateNodeRenderer.paintDuplicateNodesBackground(g, this);
         super.paintComponent(g);
       }
-    };
+    }*/;
     tree.setOpaque(false);
 
     tree.setToggleClickCount(-1);
diff --git a/java/java-impl/src/com/intellij/slicer/SliceRootNode.java b/java/java-impl/src/com/intellij/slicer/SliceRootNode.java
index 5f1a915..e7b6f1d 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceRootNode.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceRootNode.java
@@ -33,7 +33,7 @@
   private final SliceUsage myRootUsage;
 
   public SliceRootNode(@NotNull Project project, @NotNull DuplicateMap targetEqualUsages, final SliceUsage rootUsage) {
-    super(project, new SliceUsage(rootUsage.getElement().getContainingFile(), rootUsage.params), targetEqualUsages);
+    super(project, SliceUsage.createRootUsage(rootUsage.getElement().getContainingFile(), rootUsage.params), targetEqualUsages);
     myRootUsage = rootUsage;
   }
 
@@ -42,6 +42,7 @@
     myCachedChildren = Collections.singletonList(node);
   }
 
+  @NotNull
   @Override
   SliceRootNode copy() {
     SliceUsage newUsage = getValue().copy();
@@ -60,6 +61,7 @@
     return myCachedChildren;
   }
 
+  @NotNull
   @Override
   public List<? extends AbstractTreeNode> getChildrenUnderProgress(ProgressIndicator progress) {
     return (List<? extends AbstractTreeNode>)getChildren();
@@ -80,8 +82,8 @@
 
 
   @Override
-  public void customizeCellRenderer(SliceUsageCellRenderer renderer,
-                                    JTree tree,
+  public void customizeCellRenderer(@NotNull SliceUsageCellRenderer renderer,
+                                    @NotNull JTree tree,
                                     Object value,
                                     boolean selected,
                                     boolean expanded,
diff --git a/java/java-impl/src/com/intellij/slicer/SliceTooComplexDFAUsage.java b/java/java-impl/src/com/intellij/slicer/SliceTooComplexDFAUsage.java
index 89360c0..de150dd 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceTooComplexDFAUsage.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceTooComplexDFAUsage.java
@@ -37,7 +37,7 @@
   }
 
   @Override
-  public void processChildren(Processor<SliceUsage> processor) {
+  public void processChildren(@NotNull Processor<SliceUsage> processor) {
     // no children
   }
 
diff --git a/java/java-impl/src/com/intellij/slicer/SliceUsage.java b/java/java-impl/src/com/intellij/slicer/SliceUsage.java
index 21a84906..0942dcc 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceUsage.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceUsage.java
@@ -21,7 +21,6 @@
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiSubstitutor;
-import com.intellij.slicer.forward.SliceFUtil;
 import com.intellij.usageView.UsageInfo;
 import com.intellij.usages.UsageInfo2UsageAdapter;
 import com.intellij.util.CommonProcessors;
@@ -44,14 +43,18 @@
     params = parent.params;
     assert params != null;
   }
-  public SliceUsage(@NotNull PsiElement element, @NotNull SliceAnalysisParams params) {
+  private SliceUsage(@NotNull PsiElement element, @NotNull SliceAnalysisParams params) {
     super(new UsageInfo(element));
     myParent = null;
     this.params = params;
     mySubstitutor = PsiSubstitutor.EMPTY;
   }
 
-  public void processChildren(Processor<SliceUsage> processor) {
+  public static SliceUsage createRootUsage(@NotNull PsiElement element, @NotNull SliceAnalysisParams params) {
+    return new SliceUsage(element, params);
+  }
+
+  public void processChildren(@NotNull Processor<SliceUsage> processor) {
     final PsiElement element = getElement();
     ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
     indicator.checkCanceled();
@@ -76,7 +79,7 @@
           SliceUtil.processUsagesFlownDownTo(element, uniqueProcessor, SliceUsage.this, mySubstitutor);
         }
         else {
-          SliceFUtil.processUsagesFlownFromThe(element, uniqueProcessor, SliceUsage.this);
+          SliceForwardUtil.processUsagesFlownFromThe(element, uniqueProcessor, SliceUsage.this);
         }
       }
     });
@@ -93,7 +96,7 @@
 
   SliceUsage copy() {
     PsiElement element = getUsageInfo().getElement();
-    return getParent() == null ? new SliceUsage(element, params) : new SliceUsage(element, getParent(),mySubstitutor);
+    return getParent() == null ? createRootUsage(element, params) : new SliceUsage(element, getParent(),mySubstitutor);
   }
 
   public PsiSubstitutor getSubstitutor() {
diff --git a/java/java-impl/src/com/intellij/slicer/SliceUsageCellRenderer.java b/java/java-impl/src/com/intellij/slicer/SliceUsageCellRenderer.java
index d2fdf1a..c12f62e 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceUsageCellRenderer.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceUsageCellRenderer.java
@@ -18,12 +18,14 @@
 import com.intellij.openapi.editor.colors.EditorColorsScheme;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.psi.util.PsiFormatUtilBase;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.ui.ColoredTreeCellRenderer;
 import com.intellij.ui.SimpleTextAttributes;
 import com.intellij.usageView.UsageTreeColors;
 import com.intellij.usageView.UsageTreeColorsScheme;
 import com.intellij.usages.TextChunk;
+import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
 import javax.swing.tree.DefaultMutableTreeNode;
@@ -41,7 +43,7 @@
   }
 
   @Override
-  public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+  public void customizeCellRenderer(@NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
     assert value instanceof DefaultMutableTreeNode;
     DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)value;
     Object userObject = treeNode.getUserObject();
@@ -58,7 +60,7 @@
     }
   }
 
-  public void customizeCellRendererFor(SliceUsage sliceUsage) {
+  public void customizeCellRendererFor(@NotNull SliceUsage sliceUsage) {
     boolean isForcedLeaf = sliceUsage instanceof SliceDereferenceUsage;
 
     TextChunk[] text = sliceUsage.getPresentation().getText();
@@ -83,12 +85,10 @@
         break;
       }
     }
+    int methodOptions = PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS | PsiFormatUtilBase.SHOW_CONTAINING_CLASS;
     String location = method != null
-                      ? PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME |
-                                                                                 PsiFormatUtil.SHOW_PARAMETERS |
-                                                                                 PsiFormatUtil.SHOW_CONTAINING_CLASS,
-                                                   PsiFormatUtil.SHOW_TYPE, 2)
-                      : aClass != null ? PsiFormatUtil.formatClass(aClass, PsiFormatUtil.SHOW_NAME) : null;
+                      ? PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, methodOptions, PsiFormatUtilBase.SHOW_TYPE, 2)
+                      : aClass != null ? PsiFormatUtil.formatClass(aClass, PsiFormatUtilBase.SHOW_NAME) : null;
     if (location != null) {
       SimpleTextAttributes attributes = SimpleTextAttributes.GRAY_ATTRIBUTES;
       append(" in " + location, attributes);
diff --git a/java/java-impl/src/com/intellij/slicer/SliceUtil.java b/java/java-impl/src/com/intellij/slicer/SliceUtil.java
index 35b63bf..a689e18 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceUtil.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceUtil.java
@@ -30,7 +30,6 @@
 import com.intellij.psi.util.MethodSignatureUtil;
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.slicer.forward.SliceFUtil;
 import com.intellij.util.ArrayUtilRt;
 import com.intellij.util.Processor;
 import gnu.trove.THashMap;
@@ -54,7 +53,7 @@
     expression = simplify(expression);
     PsiElement original = expression;
     if (expression instanceof PsiReferenceExpression) {
-      PsiElement element = SliceFUtil.complexify(expression);
+      PsiElement element = SliceForwardUtil.complexify(expression);
       if (element instanceof PsiExpression && PsiUtil.isOnAssignmentLeftHand((PsiExpression)element)) {
         PsiExpression rightSide = ((PsiAssignmentExpression)element.getParent()).getRExpression();
         return rightSide == null || handToProcessor(rightSide, processor, parent, parentSubstitutor);
@@ -238,9 +237,12 @@
     });
   }
 
+  @NotNull
   public static SliceUsage createSliceUsage(@NotNull PsiElement element, @NotNull SliceUsage parent, @NotNull PsiSubstitutor substitutor) {
     return new SliceUsage(simplify(element), parent, substitutor);
   }
+
+  @NotNull
   public static SliceUsage createTooComplexDFAUsage(@NotNull PsiElement element, @NotNull SliceUsage parent, @NotNull PsiSubstitutor substitutor) {
     return new SliceTooComplexDFAUsage(simplify(element), parent, substitutor);
   }
diff --git a/java/java-impl/src/com/intellij/slicer/forward/SliceFUtil.java b/java/java-impl/src/com/intellij/slicer/forward/SliceFUtil.java
deleted file mode 100644
index ef70197..0000000
--- a/java/java-impl/src/com/intellij/slicer/forward/SliceFUtil.java
+++ /dev/null
@@ -1,278 +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.slicer.forward;
-
-import com.intellij.openapi.util.Pair;
-import com.intellij.psi.*;
-import com.intellij.psi.search.searches.MethodReferencesSearch;
-import com.intellij.psi.search.searches.OverridingMethodsSearch;
-import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.MethodSignatureUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.slicer.SliceDereferenceUsage;
-import com.intellij.slicer.SliceManager;
-import com.intellij.slicer.SliceUsage;
-import com.intellij.slicer.SliceUtil;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.Processor;
-import gnu.trove.THashSet;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * @author cdr
- */
-public class SliceFUtil {
-  public static boolean processUsagesFlownFromThe(@NotNull PsiElement element, @NotNull final Processor<SliceUsage> processor, @NotNull final SliceUsage parent) {
-    Pair<PsiElement, PsiSubstitutor> pair = getAssignmentTarget(element, parent);
-    if (pair != null) {
-      PsiElement target = pair.getFirst();
-      final PsiSubstitutor substitutor = pair.getSecond();
-      if (target instanceof PsiParameter) {
-        PsiParameter parameter = (PsiParameter)target;
-        PsiElement declarationScope = parameter.getDeclarationScope();
-        if (declarationScope instanceof PsiMethod) {
-          final PsiMethod method = (PsiMethod)declarationScope;
-          final int parameterIndex = method.getParameterList().getParameterIndex(parameter);
-
-          Processor<PsiMethod> myProcessor = new Processor<PsiMethod>() {
-            @Override
-            public boolean process(PsiMethod override) {
-              if (!parent.getScope().contains(override)) return true;
-              final PsiSubstitutor superSubstitutor = method == override
-                                                      ? substitutor
-                                                      : MethodSignatureUtil.getSuperMethodSignatureSubstitutor(method.getSignature(substitutor),
-                                                                                            override.getSignature(substitutor));
-
-              PsiParameter[] parameters = override.getParameterList().getParameters();
-              if (parameters.length <= parameterIndex) return true;
-              PsiParameter actualParam = parameters[parameterIndex];
-
-              SliceUsage usage = SliceUtil.createSliceUsage(actualParam, parent, superSubstitutor);
-              return processor.process(usage);
-            }
-          };
-          if (!myProcessor.process(method)) return false;
-          return OverridingMethodsSearch.search(method, parent.getScope().toSearchScope(), true).forEach(myProcessor);
-        }
-      }
-
-      SliceUsage usage = SliceUtil.createSliceUsage(target, parent, parent.getSubstitutor());
-      return processor.process(usage);
-    }
-
-    if (element instanceof PsiReferenceExpression) {
-      PsiReferenceExpression ref = (PsiReferenceExpression)element;
-      PsiElement resolved = ref.resolve();
-      if (!(resolved instanceof PsiVariable)) return true;
-      final PsiVariable variable = (PsiVariable)resolved;
-      return processAssignedFrom(variable, ref, parent, processor);
-    }
-    if (element instanceof PsiVariable) {
-      return processAssignedFrom(element, element, parent, processor);
-    }
-    if (element instanceof PsiMethod) {
-      return processAssignedFrom(element, element, parent, processor);
-    }
-    return true;
-  }
-
-  private static boolean processAssignedFrom(final PsiElement from, final PsiElement context, final SliceUsage parent,
-                                                 final Processor<SliceUsage> processor) {
-    if (from instanceof PsiLocalVariable) {
-      return searchReferencesAndProcessAssignmentTarget(from, context, parent, processor);
-    }
-    if (from instanceof PsiParameter) {
-      PsiParameter parameter = (PsiParameter)from;
-      PsiElement scope = parameter.getDeclarationScope();
-      Collection<PsiParameter> parametersToAnalyze = new THashSet<PsiParameter>();
-      if (scope instanceof PsiMethod) {
-        final PsiMethod method = (PsiMethod)scope;
-        int index = method.getParameterList().getParameterIndex(parameter);
-
-        Collection<PsiMethod> superMethods = new THashSet<PsiMethod>(Arrays.asList(method.findDeepestSuperMethods()));
-        superMethods.add(method);
-        for (Iterator<PsiMethod> iterator = superMethods.iterator(); iterator.hasNext(); ) {
-          SliceManager.getInstance(method.getProject()).checkCanceled();
-          PsiMethod superMethod = iterator.next();
-          if (!parent.params.scope.contains(superMethod)) {
-            iterator.remove();
-          }
-        }
-
-        final THashSet<PsiMethod> implementors = new THashSet<PsiMethod>(superMethods);
-        for (PsiMethod superMethod : superMethods) {
-          SliceManager.getInstance(method.getProject()).checkCanceled();
-          if (!OverridingMethodsSearch.search(superMethod, parent.getScope().toSearchScope(), true).forEach(new Processor<PsiMethod>() {
-            @Override
-            public boolean process(PsiMethod sub) {
-              SliceManager.getInstance(method.getProject()).checkCanceled();
-              implementors.add(sub);
-              return true;
-            }
-          })) return false;
-        }
-        for (PsiMethod implementor : implementors) {
-          SliceManager.getInstance(method.getProject()).checkCanceled();
-          if (!parent.params.scope.contains(implementor)) continue;
-          if (implementor instanceof PsiCompiledElement) implementor = (PsiMethod)implementor.getNavigationElement();
-
-          PsiParameter[] parameters = implementor.getParameterList().getParameters();
-          if (index != -1 && index < parameters.length) {
-            parametersToAnalyze.add(parameters[index]);
-          }
-        }
-      }
-      else {
-        parametersToAnalyze.add(parameter);
-      }
-      for (final PsiParameter psiParameter : parametersToAnalyze) {
-        SliceManager.getInstance(from.getProject()).checkCanceled();
-
-        if (!searchReferencesAndProcessAssignmentTarget(psiParameter, null, parent, processor)) return false;
-      }
-      return true;
-    }
-    if (from instanceof PsiField) {
-      return searchReferencesAndProcessAssignmentTarget(from, null, parent, processor);
-    }
-
-    if (from instanceof PsiMethod) {
-      PsiMethod method = (PsiMethod)from;
-
-      Collection<PsiMethod> superMethods = new THashSet<PsiMethod>(Arrays.asList(method.findDeepestSuperMethods()));
-      superMethods.add(method);
-      final Set<PsiReference> processed = new THashSet<PsiReference>(); //usages of super method and overridden method can overlap
-      for (final PsiMethod containingMethod : superMethods) {
-        if (!MethodReferencesSearch.search(containingMethod, parent.getScope().toSearchScope(), true).forEach(new Processor<PsiReference>() {
-            @Override
-            public boolean process(final PsiReference reference) {
-              SliceManager.getInstance(from.getProject()).checkCanceled();
-              synchronized (processed) {
-                if (!processed.add(reference)) return true;
-              }
-              PsiElement element = reference.getElement().getParent();
-
-              return processAssignmentTarget(element, parent, processor);
-            }
-          })) {
-          return false;
-        }
-      }
-    }
-    return true;
-  }
-
-  private static boolean searchReferencesAndProcessAssignmentTarget(@NotNull PsiElement element, @Nullable final PsiElement context, final SliceUsage parent,
-                                                                    final Processor<SliceUsage> processor) {
-    return ReferencesSearch.search(element).forEach(new Processor<PsiReference>() {
-      @Override
-      public boolean process(PsiReference reference) {
-        PsiElement element = reference.getElement();
-        if (context != null && element.getTextOffset() < context.getTextOffset()) return true;
-        return processAssignmentTarget(element, parent, processor);
-      }
-    });
-  }
-
-  private static boolean processAssignmentTarget(PsiElement element, final SliceUsage parent, final Processor<SliceUsage> processor) {
-    if (!parent.params.scope.contains(element)) return true;
-    if (element instanceof PsiCompiledElement) element = element.getNavigationElement();
-    Pair<PsiElement, PsiSubstitutor> pair = getAssignmentTarget(element, parent);
-    if (pair != null) {
-      SliceUsage usage = SliceUtil.createSliceUsage(element, parent, pair.getSecond());
-      return processor.process(usage);
-    }
-    if (parent.params.showInstanceDereferences && isDereferenced(element)) {
-      SliceUsage usage = new SliceDereferenceUsage(element.getParent(), parent, parent.getSubstitutor());
-      return processor.process(usage);
-    }
-    return true;
-  }
-
-  private static boolean isDereferenced(PsiElement element) {
-    if (!(element instanceof PsiReferenceExpression)) return false;
-    PsiElement parent = element.getParent();
-    if (!(parent instanceof PsiReferenceExpression)) return false;
-    return ((PsiReferenceExpression)parent).getQualifierExpression() == element;
-  }
-
-  private static Pair<PsiElement,PsiSubstitutor> getAssignmentTarget(PsiElement element, SliceUsage parentUsage) {
-    element = complexify(element);
-    PsiElement target = null;
-    PsiSubstitutor substitutor = parentUsage.getSubstitutor();
-    //assignment
-    PsiElement parent = element.getParent();
-    if (parent instanceof PsiAssignmentExpression) {
-      PsiAssignmentExpression assignment = (PsiAssignmentExpression)parent;
-      if (element.equals(assignment.getRExpression())) {
-        PsiElement left = assignment.getLExpression();
-        if (left instanceof PsiReferenceExpression) {
-          JavaResolveResult result = ((PsiReferenceExpression)left).advancedResolve(false);
-          target = result.getElement();
-          substitutor = result.getSubstitutor();
-        }
-      }
-    }
-    else if (parent instanceof PsiVariable) {
-      PsiVariable variable = (PsiVariable)parent;
-
-      PsiElement initializer = variable.getInitializer();
-      if (element.equals(initializer)) {
-        target = variable;
-      }
-    }
-    //method call
-    else if (parent instanceof PsiExpressionList && parent.getParent() instanceof PsiCallExpression) {
-      PsiExpression[] expressions = ((PsiExpressionList)parent).getExpressions();
-      int index = ArrayUtil.find(expressions, element);
-      PsiCallExpression methodCall = (PsiCallExpression)parent.getParent();
-      JavaResolveResult result = methodCall.resolveMethodGenerics();
-      PsiMethod method = (PsiMethod)result.getElement();
-      if (index != -1 && method != null) {
-        PsiParameter[] parameters = method.getParameterList().getParameters();
-        if (index < parameters.length) {
-          target = parameters[index];
-          substitutor = result.getSubstitutor();
-        }
-      }
-    }
-    else if (parent instanceof PsiReturnStatement) {
-      PsiReturnStatement statement = (PsiReturnStatement)parent;
-      if (element.equals(statement.getReturnValue())) {
-        target = PsiTreeUtil.getParentOfType(statement, PsiMethod.class);
-      }
-    }
-
-    return target == null ? null : Pair.create(target, substitutor);
-  }
-
-  public static PsiElement complexify(@NotNull PsiElement element) {
-    PsiElement parent = element.getParent();
-    if (parent instanceof PsiParenthesizedExpression && element.equals(((PsiParenthesizedExpression)parent).getExpression())) {
-      return complexify(parent);
-    }
-    if (parent instanceof PsiTypeCastExpression && element.equals(((PsiTypeCastExpression)parent).getOperand())) {
-      return complexify(parent);
-    }
-    return element;
-  }
-}
diff --git a/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java b/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java
index 9e389dd..5b4a1f3 100644
--- a/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java
+++ b/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java
@@ -107,6 +107,8 @@
   public FileTemplateDescriptor getParametersMethodFileTemplateDescriptor() {
     return null;
   }
+  
+  public abstract char getMnemonic();
 
   public PsiMethod createSetUpPatternMethod(JVMElementFactory factory) {
     final FileTemplate template = FileTemplateManager.getInstance().getCodeTemplate(getSetUpMethodFileTemplateDescriptor().getFileName());
diff --git a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
index d34a360..1185d60 100644
--- a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
+++ b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
@@ -49,6 +49,7 @@
 import com.intellij.refactoring.util.RefactoringMessageUtil;
 import com.intellij.refactoring.util.RefactoringUtil;
 import com.intellij.refactoring.util.classMembers.MemberInfo;
+import com.intellij.testIntegration.JavaTestFramework;
 import com.intellij.testIntegration.TestFramework;
 import com.intellij.testIntegration.TestIntegrationUtils;
 import com.intellij.ui.EditorTextField;
@@ -123,6 +124,12 @@
 
     for (final TestFramework descriptor : Extensions.getExtensions(TestFramework.EXTENSION_NAME)) {
       final JRadioButton b = new JRadioButton(descriptor.getName());
+      if (descriptor instanceof JavaTestFramework) {
+        final char mnemonic = ((JavaTestFramework)descriptor).getMnemonic();
+        if (mnemonic > -1) {
+          b.setMnemonic(mnemonic);
+        }
+      }
       myLibraryButtons.add(b);
       group.add(b);
 
diff --git a/java/java-impl/src/com/intellij/usageView/UsageContextDataflowToPanel.java b/java/java-impl/src/com/intellij/usageView/UsageContextDataflowToPanel.java
index 226af43..b097a8a 100644
--- a/java/java-impl/src/com/intellij/usageView/UsageContextDataflowToPanel.java
+++ b/java/java-impl/src/com/intellij/usageView/UsageContextDataflowToPanel.java
@@ -122,7 +122,7 @@
     ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.FIND);
     SliceAnalysisParams params = createParams(element, dataFlowToThis);
 
-    SliceRootNode rootNode = new SliceRootNode(myProject, new DuplicateMap(), SliceManager.createRootUsage(element, params));
+    SliceRootNode rootNode = new SliceRootNode(myProject, new DuplicateMap(), SliceUsage.createRootUsage(element, params));
 
     return new SlicePanel(myProject, dataFlowToThis, rootNode, false, toolWindow) {
       @Override
diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java
index 0593133..7e344d2 100644
--- a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java
+++ b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java
@@ -50,6 +50,7 @@
     if (!(usage instanceof PsiElementUsage)) return null;
     PsiElement psiElement = ((PsiElementUsage)usage).getElement();
     PsiFile containingFile = psiElement.getContainingFile();
+    if (containingFile == null) return null;
     InjectedLanguageManager manager = InjectedLanguageManager.getInstance(containingFile.getProject());
     PsiFile topLevelFile = manager.getTopLevelFile(containingFile);
     if (topLevelFile instanceof PsiJavaFile) {
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java b/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java
index 6854c57..aa0d088 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java
@@ -120,6 +120,14 @@
 
   public abstract boolean processMethodsWithName(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope, @NotNull Processor<PsiMethod> processor);
 
+  public boolean processAllMethodNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+    return ContainerUtil.process(getAllFieldNames(), processor);
+  }
+
+  public boolean processAllFieldNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+    return ContainerUtil.process(getAllFieldNames(), processor);
+  }
+
   /**
    * Returns the list of names of all methods in the project and
    * (optionally) libraries.
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java b/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java
index e6ba22d..517a300 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java
@@ -117,6 +117,26 @@
   }
 
   @Override
+  public boolean processAllMethodNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+    for (PsiShortNamesCache cache : myCaches) {
+      if (!cache.processAllMethodNames(processor, scope, filter)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @Override
+  public boolean processAllFieldNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+    for (PsiShortNamesCache cache : myCaches) {
+      if (!cache.processAllFieldNames(processor, scope, filter)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @Override
   public void getAllClassNames(@NotNull HashSet<String> dest) {
     for (PsiShortNamesCache cache : myCaches) {
       cache.getAllClassNames(dest);
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java b/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java
index e702d01..8bc35ce 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java
@@ -122,6 +122,16 @@
   }
 
   @Override
+  public boolean processAllMethodNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+    return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.METHODS, processor, scope, filter);
+  }
+
+  @Override
+  public boolean processAllFieldNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+    return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.FIELDS, processor, scope, filter);
+  }
+
+  @Override
   @NotNull
   public PsiMethod[] getMethodsByName(@NotNull String name, @NotNull final GlobalSearchScope scope) {
     Collection<PsiMethod> methods = StubIndex.getInstance().get(JavaStubIndexKeys.METHODS, name, myManager.getProject(), new JavaSourceFilterScope(scope));
diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
index 94c1563..4cdb0f3 100644
--- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
@@ -109,9 +109,7 @@
   public static boolean isLambdaFullyInferred(PsiLambdaExpression expression, PsiType functionalInterfaceType) {
     final boolean hasParams = expression.getParameterList().getParametersCount() > 0;
     if (hasParams || getFunctionalInterfaceReturnType(functionalInterfaceType) != PsiType.VOID) {   //todo check that void lambdas without params check
-      if (hasParams && !checkRawAcceptable(expression, functionalInterfaceType)) {
-        return false;
-      }
+      
       return !dependsOnTypeParams(functionalInterfaceType, functionalInterfaceType, expression);
     }
     return true;
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceExpression.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceExpression.java
index 2d91cd4..1df1441 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceExpression.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceExpression.java
@@ -35,4 +35,6 @@
   */
   @Nullable
   PsiType getFunctionalInterfaceType();
+
+  boolean isExact();
 }
diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
index 01120c2..d72d3d8 100644
--- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
+++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
@@ -81,7 +81,7 @@
   private int getApplicabilityLevelInner() {
     if (myArgumentTypes == null) return ApplicabilityLevel.NOT_APPLICABLE;
 
-    int level = PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(!Registry.is("enable.graph.inference", false)), myArgumentTypes, myLanguageLevel);
+    int level = PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(), myArgumentTypes, myLanguageLevel);
     if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable()) level = ApplicabilityLevel.NOT_APPLICABLE;
     return level;
   }
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java b/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java
index de1e03f3..0592f9e 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java
@@ -54,7 +54,7 @@
     }
 
     @Override
-    public final void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+    public final void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
       myBuffer = buffer;
       myBufferIndex =  startOffset;
       myBufferEndOffset = endOffset;
@@ -68,6 +68,7 @@
       return myState;
     }
 
+    @NotNull
     @Override
     public CharSequence getBufferSequence() {
       return myBuffer;
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java b/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java
index db6e5e2..f1c6c19 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java
@@ -175,7 +175,7 @@
   }
 
   @Override
-  public final void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public final void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     myBuffer = buffer;
     myBufferArray = CharArrayUtil.fromSequenceWithoutCopying(buffer);
     myBufferIndex = startOffset;
@@ -417,6 +417,7 @@
     return pos;
   }
 
+  @NotNull
   @Override
   public CharSequence getBufferSequence() {
     return myBuffer;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
index bc62cc8..103b828 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
@@ -799,7 +799,7 @@
   @Override
   public void processVariants(@NotNull final PsiScopeProcessor processor) {
     final OrFilter filter = new OrFilter();
-    if (isInCode() && !(getParent() instanceof PsiImportStatement)) {
+    if (isInCode() && !(getParent() instanceof PsiImportStatement) && !(getParent() instanceof PsiReferenceList)) {
       filter.addFilter(new AndFilter(ElementClassFilter.METHOD, new NotFilter(new ConstructorFilter())));
       filter.addFilter(ElementClassFilter.VARIABLE);
     }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
index 68bb8b8..15aba88 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.psi.impl.source.resolve;
 
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.registry.Registry;
 import com.intellij.pom.java.LanguageLevel;
@@ -196,7 +197,16 @@
       .getSubstitutionForTypeParameter(typeParam, param, arg, isContraVariantPosition, languageLevel);
   }
 
+  private PsiInferenceHelper myTestHelper;
+
+  public void setTestHelper(PsiInferenceHelper testHelper) {
+    myTestHelper = testHelper;
+  }
+
   public PsiInferenceHelper getInferenceHelper(LanguageLevel languageLevel) {
+    if (ApplicationManager.getApplication().isUnitTestMode()) {
+      return myTestHelper != null ? myTestHelper : new PsiOldInferenceHelper(myManager);
+    }
     if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && Registry.is("enable.graph.inference", false)) {
       return new PsiGraphInferenceHelper(myManager);
     }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java
new file mode 100644
index 0000000..4806a51
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java
@@ -0,0 +1,92 @@
+/*
+ * 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.psi.impl.source.resolve.graphInference;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeEqualityConstraint;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class FunctionalInterfaceParameterizationUtil {
+  private static final Logger LOG = Logger.getInstance("#" + FunctionalInterfaceParameterizationUtil.class.getName());
+
+  public static boolean isWildcardParameterized(@Nullable PsiType classType) {
+    if (classType == null) return false;
+    if (classType instanceof PsiIntersectionType) {
+      for (PsiType type : ((PsiIntersectionType)classType).getConjuncts()) {
+        if (!isWildcardParameterized(type)) return false;
+      }
+    }
+    if (classType instanceof PsiClassType) {
+      for (PsiType type : ((PsiClassType)classType).getParameters()) {
+        if (type instanceof PsiWildcardType || type instanceof PsiCapturedWildcardType) {
+          return true;
+        }
+      }
+      return false;
+    }
+    LOG.error("Unexpected type: " + classType);
+    return false;
+  }
+
+  @Nullable
+  public static PsiType getFunctionalType(@Nullable PsiType psiClassType, PsiLambdaExpression expr) {
+    if (!expr.hasFormalParameterTypes() || expr.getParameterList().getParametersCount() == 0) return psiClassType;
+    if (!isWildcardParameterized(psiClassType)) {
+      return psiClassType;
+    }
+    final PsiParameter[] lambdaParams = expr.getParameterList().getParameters();
+    if (psiClassType instanceof PsiIntersectionType) {
+      for (PsiType psiType : ((PsiIntersectionType)psiClassType).getConjuncts()) {
+        final PsiType functionalType = getFunctionalType(psiType, expr);
+        if (functionalType != null) return functionalType;
+      }
+      return null;
+    }
+
+    LOG.assertTrue(psiClassType instanceof PsiClassType, "Unexpected type: " + psiClassType);
+    final PsiType[] parameters = ((PsiClassType)psiClassType).getParameters();
+    final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)psiClassType).resolveGenerics();
+    PsiClass psiClass = resolveResult.getElement();
+
+    if (psiClass != null) {
+
+      final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
+      if (interfaceMethod == null) return null;
+
+      final InferenceSession session = new InferenceSession(PsiSubstitutor.EMPTY);
+      PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
+      if (typeParameters.length != parameters.length) {
+        return null;
+      }
+
+      for (int i = 0; i < typeParameters.length; i++) {
+        session.addVariable(typeParameters[i], parameters[i]);
+      }
+
+      final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiClass.getProject());
+      final PsiParameter[] targetMethodParams = interfaceMethod.getParameterList().getParameters();
+      for (int i = 0; i < targetMethodParams.length; i++) {
+        session.addConstraint(new TypeEqualityConstraint(lambdaParams[i].getType(), targetMethodParams[i].getType()));
+      }
+
+      final PsiClassType parameterization = elementFactory.createType(psiClass, session.infer());
+      if (!isWildcardParameterized(parameterization)) return parameterization;
+    }
+    return null;
+  }
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
index a63e438..e1c3d63 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
@@ -174,8 +174,10 @@
   private void eqEq(List<PsiType> eqBounds) {
     for (int i = 0; i < eqBounds.size(); i++) {
       PsiType sBound= eqBounds.get(i);
+      if (sBound == null) continue;
       for (int j = i + 1; j < eqBounds.size(); j++) {
         final PsiType tBound = eqBounds.get(j);
+        if (tBound == null) continue;
         addConstraint(new TypeEqualityConstraint(tBound, sBound));
       }
     }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
index dba4a72..df78507 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
@@ -18,13 +18,17 @@
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Pair;
 import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiImplUtil;
+import com.intellij.psi.impl.source.resolve.graphInference.constraints.CheckedExceptionCompatibilityConstraint;
 import com.intellij.psi.impl.source.resolve.graphInference.constraints.ConstraintFormula;
 import com.intellij.psi.impl.source.resolve.graphInference.constraints.ExpressionCompatibilityConstraint;
 import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeCompatibilityConstraint;
 import com.intellij.psi.infos.MethodCandidateInfo;
 import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiTypesUtil;
 import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.ArrayUtilRt;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -38,7 +42,6 @@
 
   private Map<PsiTypeParameter, InferenceVariable> myInferenceVariables = new LinkedHashMap<PsiTypeParameter, InferenceVariable>();
   private final List<ConstraintFormula> myConstraints = new ArrayList<ConstraintFormula>();
-  private final List<ConstraintFormula> myDelayedConstraints = new ArrayList<ConstraintFormula>();
 
   private PsiSubstitutor mySiteSubstitutor;
   private PsiManager myManager;
@@ -46,6 +49,10 @@
 
   private final InferenceIncorporationPhase myIncorporationPhase = new InferenceIncorporationPhase(this);
 
+  public InferenceSession(PsiSubstitutor siteSubstitutor) {
+    mySiteSubstitutor = siteSubstitutor;
+  }
+
   public InferenceSession(PsiTypeParameter[] typeParams,
                           PsiType[] leftTypes, 
                           PsiType[] rightTypes,
@@ -75,14 +82,10 @@
 
     if (parameters.length > 0) {
       for (int i = 0; i < args.length; i++) {
-        PsiType parameterType = mySiteSubstitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType());
-        if (parameterType instanceof PsiEllipsisType) {
-          if (args.length != parameters.length || args[i] != null && !(args[i].getType() instanceof PsiArrayType)) {
-            parameterType = ((PsiEllipsisType)parameterType).getComponentType();
-          }
-        }
+        PsiType parameterType = getParameterType(parameters, args, i, mySiteSubstitutor);
         if (args[i] != null) {
           myConstraints.add(new ExpressionCompatibilityConstraint(args[i], parameterType));
+          //myConstraints.add(new CheckedExceptionCompatibilityConstraint(args[i], parameterType));
         }
       }
     }
@@ -98,11 +101,66 @@
     }
   }
 
+  public static boolean isPertinentToApplicability(PsiExpression expr, PsiMethod method) {
+    if (expr instanceof PsiLambdaExpression) {
+      if (((PsiLambdaExpression)expr).hasFormalParameterTypes()) return true;
+      for (PsiExpression expression : LambdaUtil.getReturnExpressions((PsiLambdaExpression)expr)) {
+        if (!isPertinentToApplicability(expression, method)) return false;
+      }
+      if (method.getTypeParameters().length > 0) {
+        final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expr.getParent());
+        if (parent instanceof PsiExpressionList) {
+          final PsiElement gParent = parent.getParent();
+          if (gParent instanceof PsiCallExpression && ((PsiCallExpression)gParent).getTypeArgumentList().getTypeParameterElements().length == 0) {
+            final int idx = LambdaUtil.getLambdaIdx(((PsiExpressionList)parent), expr);
+            final PsiParameter[] parameters = method.getParameterList().getParameters();
+            PsiType paramType;
+            if (idx > parameters.length - 1) {
+              final PsiType lastParamType = parameters[parameters.length - 1].getType();
+              paramType = parameters[parameters.length - 1].isVarArgs() ? ((PsiEllipsisType)lastParamType).getComponentType() : lastParamType;
+            }
+            else {
+              paramType = parameters[idx].getType();
+            }
+            final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(paramType);
+            if (psiClass instanceof PsiTypeParameter && ((PsiTypeParameter)psiClass).getOwner() == method) return false;
+          }
+        }
+      }
+      return true;
+    }
+    if (expr instanceof PsiMethodReferenceExpression) {
+      return ((PsiMethodReferenceExpression)expr).isExact();
+    }
+    if (expr instanceof PsiParenthesizedExpression) {
+      return isPertinentToApplicability(((PsiParenthesizedExpression)expr).getExpression(), method);
+    }
+    if (expr instanceof PsiConditionalExpression) {
+      final PsiExpression thenExpression = ((PsiConditionalExpression)expr).getThenExpression();
+      if (!isPertinentToApplicability(thenExpression, method)) return false;
+      final PsiExpression elseExpression = ((PsiConditionalExpression)expr).getElseExpression();
+      if (!isPertinentToApplicability(elseExpression, method)) return false;
+    }
+    return true;
+  }
+
+  private static PsiType getParameterType(PsiParameter[] parameters, PsiExpression[] args, int i, PsiSubstitutor substitutor) {
+    PsiType parameterType = substitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType());
+    if (parameterType instanceof PsiEllipsisType) {
+      if (args.length != parameters.length || PsiPolyExpressionUtil
+        .isPolyExpression(args[i]) || args[i] != null && !(args[i].getType() instanceof PsiArrayType)) {
+        parameterType = ((PsiEllipsisType)parameterType).getComponentType();
+      }
+    }
+    return parameterType;
+  }
+
   @NotNull
   public PsiSubstitutor infer() {
     repeatInferencePhases();
  
     for (InferenceVariable inferenceVariable : myInferenceVariables.values()) {
+      if (inferenceVariable.isCaptured()) continue;
       final PsiTypeParameter typeParameter = inferenceVariable.getParameter();
       PsiType instantiation = inferenceVariable.getInstantiation();
       if (instantiation == PsiType.NULL) {
@@ -136,25 +194,60 @@
       }
     }
   }
+  
+  public void addCapturedVariable(PsiTypeParameter param) {
+    if (myInferenceVariables.containsKey(param)) return; //same method call
+    final InferenceVariable variable = new InferenceVariable(param);
+    variable.setCaptured(true);
+    myInferenceVariables.put(param, variable);
+  }
 
   private void initReturnTypeConstraint(PsiMethod method, PsiCallExpression context) {
     if (PsiPolyExpressionUtil.isPolyExpression(context) || 
         context instanceof PsiNewExpression && PsiDiamondType.ourDiamondGuard.currentStack().contains(context)) {
       final PsiType returnType = method.getReturnType();
       if (!PsiType.VOID.equals(returnType) && returnType != null) {
-        final PsiType targetType = PsiPolyExpressionUtil.getTargetType(context);//todo primitive type
+        PsiType targetType = PsiTypesUtil.getExpectedTypeByParent(context);
+        if (targetType == null) {
+          final PsiElement parent = PsiUtil.skipParenthesizedExprUp(context.getParent());
+          if (parent instanceof PsiExpressionList) {
+            final PsiElement gParent = parent.getParent();
+            if (gParent instanceof PsiCallExpression) {
+              final PsiExpressionList argumentList = ((PsiCallExpression)gParent).getArgumentList();
+              if (argumentList != null) {
+                final JavaResolveResult resolveResult = ((PsiCallExpression)gParent).resolveMethodGenerics();
+                final PsiElement parentMethod = resolveResult.getElement();
+                if (parentMethod instanceof PsiMethod) {
+                  final PsiParameter[] parameters = ((PsiMethod)parentMethod).getParameterList().getParameters();
+                  PsiElement arg = context;
+                  while (arg.getParent() instanceof PsiParenthesizedExpression) {
+                    arg = parent.getParent();
+                  }
+                  final PsiExpression[] args = argumentList.getExpressions();
+                  targetType = getParameterType(parameters, args, ArrayUtilRt.find(args, arg), resolveResult.getSubstitutor());
+                }
+              }
+            }
+          } else if (parent instanceof PsiConditionalExpression) {
+            targetType = PsiTypesUtil.getExpectedTypeByParent((PsiExpression)parent);
+          }
+        }
         if (targetType != null) {
-          myConstraints.add(new TypeCompatibilityConstraint(targetType, returnType));
+          myConstraints.add(new TypeCompatibilityConstraint(targetType, PsiImplUtil.normalizeWildcardTypeByPosition(returnType, context)));
         }
       }
     }
   }
 
   public InferenceVariable getInferenceVariable(PsiType psiType) {
+    return getInferenceVariable(psiType, true);
+  }
+
+  public InferenceVariable getInferenceVariable(PsiType psiType, boolean acceptCaptured) {
     final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(psiType);
     if (psiClass instanceof PsiTypeParameter) {
       final InferenceVariable inferenceVariable = myInferenceVariables.get(psiClass);
-      if (inferenceVariable != null) {
+      if (inferenceVariable != null && (acceptCaptured || !inferenceVariable.isCaptured())) {
         return inferenceVariable;
       }
     }
@@ -162,10 +255,16 @@
   }
 
   public boolean isProperType(@Nullable PsiType type) {
-    return collectDependencies(type, null);
+    return isProperType(type, true);
   }
 
-  public boolean collectDependencies(@Nullable PsiType type, @Nullable final Set<InferenceVariable> dependencies) {
+  public boolean isProperType(@Nullable PsiType type, boolean acceptCaptured) {
+    return collectDependencies(type, null, acceptCaptured);
+  }
+
+  public boolean collectDependencies(@Nullable PsiType type,
+                                     @Nullable final Set<InferenceVariable> dependencies,
+                                     final boolean acceptCaptured) {
     if (type == null) return true;
     final Boolean isProper = type.accept(new PsiTypeVisitor<Boolean>() {
       @Nullable
@@ -191,7 +290,7 @@
       @Nullable
       @Override
       public Boolean visitClassType(PsiClassType classType) {
-        final InferenceVariable inferenceVariable = getInferenceVariable(classType);
+        final InferenceVariable inferenceVariable = getInferenceVariable(classType, acceptCaptured);
         if (inferenceVariable != null) {
           if (dependencies != null) {
             dependencies.add(inferenceVariable);
@@ -225,7 +324,7 @@
     List<ConstraintFormula> newConstraints = new ArrayList<ConstraintFormula>();
     for (int i = myConstraintIdx; i < myConstraints.size(); i++) {
       ConstraintFormula constraint = myConstraints.get(i);
-      if (!constraint.reduce(this, newConstraints, myDelayedConstraints)) {
+      if (!constraint.reduce(this, newConstraints)) {
         return false;
       }
     }
@@ -241,7 +340,7 @@
     for (List<InferenceVariable> variables : independentVars) {
       for (InferenceVariable inferenceVariable : variables) {
 
-        if (inferenceVariable.getInstantiation() != PsiType.NULL) continue;
+        if (inferenceVariable.isCaptured() || inferenceVariable.getInstantiation() != PsiType.NULL) continue;
         final PsiTypeParameter typeParameter = inferenceVariable.getParameter();
         try {
           final List<PsiType> eqBounds = inferenceVariable.getBounds(InferenceBound.EQ);
@@ -253,19 +352,18 @@
           }
           PsiType bound = null;
           for (PsiType eqBound : eqBounds) {
-            eqBound = acceptBoundsWithRecursiveDependencies(typeParameter, eqBound);
-            if (isProperType(eqBound)) {
-              bound = eqBound;
-              break;
-            }
+            bound = acceptBoundsWithRecursiveDependencies(typeParameter, eqBound);
           }
           if (bound != null) {
+            if (bound instanceof PsiCapturedWildcardType && eqBounds.size() > 1) {
+              continue;
+            }
             inferenceVariable.setInstantiation(bound);
           } else {
             PsiType lub = null;
             for (PsiType lowerBound : lowerBounds) {
               lowerBound = acceptBoundsWithRecursiveDependencies(typeParameter, lowerBound);
-              if (isProperType(lowerBound)) {
+              if (isProperType(lowerBound, false)) {
                 if (lub == null) {
                   lub = lowerBound;
                 }
@@ -281,7 +379,7 @@
               PsiType glb = null;
               for (PsiType upperBound : upperBounds) {
                 upperBound = acceptBoundsWithRecursiveDependencies(typeParameter, upperBound);
-                if (isProperType(upperBound)) {
+                if (isProperType(upperBound, false)) {
                   if (glb == null) {
                     glb = upperBound;
                   }
@@ -307,8 +405,9 @@
   }
 
   private PsiType acceptBoundsWithRecursiveDependencies(PsiTypeParameter typeParameter, PsiType bound) {
-    if (PsiPolyExpressionUtil.mentionsTypeParameters(bound, Collections.singleton(typeParameter))) {
-      return mySiteSubstitutor.put(typeParameter, null).substitute(bound);
+    if (!isProperType(bound)) {
+      final PsiSubstitutor substitutor = PsiUtil.resolveClassInType(bound) != typeParameter ? mySiteSubstitutor.put(typeParameter, null) : mySiteSubstitutor;
+      return substitutor.substitute(bound);
     }
     return bound;
   }
@@ -330,4 +429,24 @@
         myConstraints.add(constraint);
       }
   }
+
+  public Collection<PsiTypeParameter> getTypeParams() {
+    return myInferenceVariables.keySet();
+  }
+
+  public void addVariable(PsiTypeParameter typeParameter, final PsiType parameter) {
+    InferenceVariable variable = new InferenceVariable(typeParameter);
+    if (parameter instanceof PsiWildcardType) {
+      PsiType bound = ((PsiWildcardType)parameter).getBound();
+      if (bound != null) {
+        variable.addBound(bound, ((PsiWildcardType)parameter).isExtends() ? InferenceBound.UPPER : InferenceBound.LOWER);
+      } else {
+        variable.addBound(PsiType.getJavaLangObject(typeParameter.getManager(), parameter.getResolveScope()),
+                          InferenceBound.UPPER);
+      }
+    } else {
+      variable.addBound(parameter, InferenceBound.EQ);
+    }
+    myInferenceVariables.put(typeParameter, variable);
+  }
 }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
index e69f229..f750e12 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
@@ -58,7 +58,8 @@
       list = new ArrayList<PsiType>();
       myBounds.put(inferenceBound, list);
     }
-    if (!list.contains(classType)) {
+    final int idx = list.indexOf(classType);
+    if (idx < 0 || inferenceBound == InferenceBound.EQ && classType instanceof PsiCapturedWildcardType && list.get(idx) != classType) {
       list.add(classType);
       return true;
     }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java
index 4a2c412..c27ae4a 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java
@@ -41,7 +41,7 @@
       for (InferenceBound inferenceBound : InferenceBound.values()) {
         for (PsiType bound : var.getBounds(inferenceBound)) {
           final HashSet<InferenceVariable> dependencies = new HashSet<InferenceVariable>();
-          session.collectDependencies(bound, dependencies);
+          session.collectDependencies(bound, dependencies, true);
           for (InferenceVariable dependentVariable : dependencies) {
             final InferenceGraphNode<InferenceVariable> dependency = nodes.get(dependentVariable);
             if (dependency != null) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java
index 2e425e0..d6a1d46 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java
@@ -82,10 +82,6 @@
     return false;
   }
 
-  public static PsiType getTargetType(@NotNull PsiCallExpression expression) {
-    return PsiTypesUtil.getExpectedTypeByParent(expression);
-  }
-  
   public static Boolean mentionsTypeParameters(@Nullable PsiType returnType, final Set<PsiTypeParameter> typeParameters) {
     if (returnType == null) return false;
     return returnType.accept(new PsiTypeVisitor<Boolean>() {
@@ -125,7 +121,7 @@
 
   private static boolean isInAssignmentOrInvocationContext(PsiExpression expr) {
     final PsiElement context = expr.getParent();
-    return context instanceof PsiExpressionList || isAssignmentContext(expr, context);
+    return context instanceof PsiExpressionList || context instanceof PsiConditionalExpression || isAssignmentContext(expr, context);
   }
 
   private static boolean isAssignmentContext(PsiExpression expr, PsiElement context) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java
new file mode 100644
index 0000000..19f50e6
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.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 com.intellij.psi.impl.source.resolve.graphInference.constraints;
+
+import com.intellij.codeInsight.ExceptionUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * User: anna
+ */
+public class CheckedExceptionCompatibilityConstraint extends InputOutputConstraintFormula {
+  private static final Logger LOG = Logger.getInstance("#" + CheckedExceptionCompatibilityConstraint.class.getName());
+  private final PsiExpression myExpression;
+  private final PsiType myT;
+
+  public CheckedExceptionCompatibilityConstraint(PsiExpression expression, PsiType t) {
+    myExpression = expression;
+    myT = t;
+  }
+
+  @Override
+  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
+    if (!PsiPolyExpressionUtil.isPolyExpression(myExpression) ||
+        myExpression instanceof PsiCallExpression) {
+      return true;
+    }
+    if (myExpression instanceof PsiParenthesizedExpression) {
+      constraints.add(new CheckedExceptionCompatibilityConstraint(((PsiParenthesizedExpression)myExpression).getExpression(), myT));
+      return true;
+    }
+    if (myExpression instanceof PsiConditionalExpression) {
+      final PsiExpression thenExpression = ((PsiConditionalExpression)myExpression).getThenExpression();
+      if (thenExpression != null) {
+        constraints.add(new CheckedExceptionCompatibilityConstraint(thenExpression, myT));
+      }
+      final PsiExpression elseExpression = ((PsiConditionalExpression)myExpression).getElseExpression();
+      if (elseExpression != null) {
+        constraints.add(new CheckedExceptionCompatibilityConstraint(elseExpression, myT));
+      }
+      return true;
+    }
+    if (myExpression instanceof PsiLambdaExpression || myExpression instanceof PsiMethodReferenceExpression) {
+      if (LambdaHighlightingUtil.checkInterfaceFunctional(myT) != null) {
+        return false;
+      }
+      final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(myT);
+      if (interfaceMethod == null) {
+        return false;
+      }
+
+      final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, PsiUtil.resolveGenericsClassInType(myT));
+      for (PsiParameter parameter : interfaceMethod.getParameterList().getParameters()) {
+        if (!session.isProperType(substitutor.substitute(parameter.getType()))) return false;
+      }
+      final PsiType returnType = interfaceMethod.getReturnType();
+      LOG.assertTrue(returnType != null, interfaceMethod);
+      if (!session.isProperType(substitutor.substitute(returnType))) return false;
+
+      final List<PsiType>
+        expectedThrownTypes = ContainerUtil.map(interfaceMethod.getThrowsList().getReferencedTypes(), new Function<PsiType, PsiType>() {
+        @Override
+        public PsiType fun(PsiType type) {
+          return substitutor.substitute(type);
+        }
+      });
+      final List<PsiType> expectedNonProperThrownTypes = new ArrayList<PsiType>();
+      for (PsiType type : expectedThrownTypes) {
+        if (!session.isProperType(type)) {
+          expectedNonProperThrownTypes.add(type);
+        }
+      }
+      
+      final List<PsiType> thrownTypes = new ArrayList<PsiType>();
+      if (myExpression instanceof PsiLambdaExpression) {
+        //todo
+      } else {
+        final PsiElement resolve = ((PsiMethodReferenceExpression)myExpression).resolve();
+        if (resolve instanceof PsiMethod) {
+          for (PsiClassType type : ((PsiMethod)resolve).getThrowsList().getReferencedTypes()) {
+            if (!ExceptionUtil.isUncheckedException(type)) {
+              thrownTypes.add(type);
+            }
+          }
+        }
+      }
+      
+      if (expectedNonProperThrownTypes.isEmpty()) {
+        for (PsiType thrownType : thrownTypes) {
+          if (!isAddressed(expectedThrownTypes, thrownType)) return false;
+        }
+      } else {
+        final ArrayList<PsiType> expectedProperTypes = new ArrayList<PsiType>(expectedThrownTypes);
+        expectedProperTypes.retainAll(expectedNonProperThrownTypes);
+        for (PsiType thrownType : thrownTypes) {
+          if (!isAddressed(expectedProperTypes, thrownType)) {
+            for (PsiType expectedNonProperThrownType : expectedNonProperThrownTypes) {
+              constraints.add(new TypeCompatibilityConstraint(expectedNonProperThrownType, thrownType));
+            }
+          }
+        }
+      }
+    }
+
+    return true;
+  }
+
+  private static boolean isAddressed(List<PsiType> expectedThrownTypes, PsiType thrownType) {
+    for (PsiType expectedThrownType : expectedThrownTypes) {
+      if (TypeConversionUtil.isAssignable(expectedThrownType, thrownType)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @Override
+  protected PsiExpression getExpression() {
+    return myExpression;
+  }
+
+  @Override
+  protected PsiType getT() {
+    return myT;
+  }
+
+  @Override
+  protected InputOutputConstraintFormula createSelfConstraint(PsiType type, PsiExpression expression) {
+    return new CheckedExceptionCompatibilityConstraint(expression, type);
+  }
+
+  @Override
+  protected void collectReturnTypeVariables(InferenceSession session,
+                                            PsiExpression psiExpression,
+                                            PsiMethod interfaceMethod,
+                                            Set<InferenceVariable> result) {
+    final PsiType returnType = interfaceMethod.getReturnType();
+    session.collectDependencies(returnType, result, true);
+  }
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java
index 992d875..8dc8ee0 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java
@@ -23,5 +23,5 @@
  * User: anna
  */
 public interface ConstraintFormula {
-  boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints);
+  boolean reduce(InferenceSession session, List<ConstraintFormula> constraints);
 }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
index a0e6a76..7084538 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
@@ -15,18 +15,22 @@
  */
 package com.intellij.psi.impl.source.resolve.graphInference.constraints;
 
+import com.intellij.openapi.util.Pair;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
 import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
+import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl;
+import com.intellij.psi.infos.MethodCandidateInfo;
 import com.intellij.psi.util.TypeConversionUtil;
 import org.jetbrains.annotations.NotNull;
 
-import java.util.List;
+import java.util.*;
 
 /**
  * User: anna
  */
-public class ExpressionCompatibilityConstraint implements ConstraintFormula {
+public class ExpressionCompatibilityConstraint extends InputOutputConstraintFormula {
   private PsiExpression myExpression;
   private PsiType myT;
 
@@ -36,7 +40,7 @@
   }
 
   @Override
-  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
+  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
     if (session.isProperType(myT)) {
       return TypeConversionUtil.areTypesAssignmentCompatible(myT, myExpression);
     }
@@ -69,11 +73,59 @@
     }
     
     if (myExpression instanceof PsiCallExpression) {
-      //todo
+      final PsiExpressionList argumentList = ((PsiCallExpression)myExpression).getArgumentList();
+      if (argumentList != null) {
+        final Map<PsiElement,Pair<PsiMethod,PsiSubstitutor>> map = MethodCandidateInfo.CURRENT_CANDIDATE.get();
+        final Pair<PsiMethod,PsiSubstitutor> pair = map != null ? map.get(argumentList) : null;
+        final PsiMethod method = pair != null ? pair.first : ((PsiCallExpression)myExpression).resolveMethod();
+        PsiType returnType = null;
+        InferenceSession callSession = null;
+        if (method != null) {
+          returnType = method.getReturnType();
+          final PsiParameter[] parameters = method.getParameterList().getParameters();
+          if (returnType != null) {
+            callSession = new InferenceSession(method.getTypeParameters(), parameters,
+                                               argumentList.getExpressions(),
+                                               PsiSubstitutor.EMPTY, null, myExpression.getManager());
+            
+          }
+        } else if (myExpression instanceof PsiNewExpression) {  //default constructor
+          final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)myExpression).getClassOrAnonymousClassReference();
+          if (classReference != null) {
+            final PsiElement psiClass = classReference.resolve();
+            if (psiClass instanceof PsiClass) {
+              returnType = JavaPsiFacade.getElementFactory(argumentList.getProject()).createType((PsiClass)psiClass, PsiSubstitutor.EMPTY);
+              callSession = new InferenceSession(((PsiClass)psiClass).getTypeParameters(),
+                                                 PsiParameter.EMPTY_ARRAY,
+                                                 argumentList.getExpressions(),
+                                                 PsiSubstitutor.EMPTY, null, myExpression.getManager());
+            }
+          }
+        }
+
+        if (callSession != null) {
+
+          for (PsiTypeParameter typeParameter : session.getTypeParams()) {
+            callSession.addCapturedVariable(typeParameter);
+          }
+          callSession.addConstraint(new TypeCompatibilityConstraint(myT, returnType));
+          final PsiSubstitutor callSubstitutor = callSession.infer();
+
+          if (myExpression instanceof PsiMethodCallExpression) {
+            returnType = PsiMethodCallExpressionImpl.captureReturnType((PsiMethodCallExpression)myExpression, method, returnType, callSubstitutor);
+          }
+          else {
+            returnType = callSubstitutor.substitute(returnType);
+          }
+          constraints.add(new TypeCompatibilityConstraint(myT, returnType));  //todo primitive types
+        }
+      }
+      return true;
     }
     
     if (myExpression instanceof PsiMethodReferenceExpression) {
-      //todo
+      constraints.add(new PsiMethodReferenceCompatibilityConstraint(((PsiMethodReferenceExpression)myExpression), myT));
+      return true;
     }
     
     if (myExpression instanceof PsiLambdaExpression) {
@@ -104,4 +156,37 @@
     result = 31 * result + myT.hashCode();
     return result;
   }
+
+  @Override
+  public PsiExpression getExpression() {
+    return myExpression;
+  }
+
+  @Override
+  public PsiType getT() {
+    return myT;
+  }
+
+  @Override
+  protected InputOutputConstraintFormula createSelfConstraint(PsiType type, PsiExpression expression) {
+    return new ExpressionCompatibilityConstraint(expression, type);
+  }
+
+  protected void collectReturnTypeVariables(InferenceSession session,
+                                            PsiExpression psiExpression,
+                                            PsiMethod interfaceMethod,
+                                            Set<InferenceVariable> result) {
+    if (psiExpression instanceof PsiLambdaExpression) {
+      final PsiType returnType = interfaceMethod.getReturnType();
+      if (returnType != PsiType.VOID) {
+        final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions((PsiLambdaExpression)psiExpression);
+        for (PsiExpression expression : returnExpressions) {
+          final Set<InferenceVariable> resultInputVars = createSelfConstraint(returnType, expression).getInputVariables(session);
+          if (resultInputVars != null) {
+            result.addAll(resultInputVars);
+          }
+        }
+      }
+    }
+  }
 }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java
new file mode 100644
index 0000000..d06538c
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java
@@ -0,0 +1,112 @@
+/*
+ * 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.psi.impl.source.resolve.graphInference.constraints;
+
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
+import com.intellij.psi.util.PsiUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * User: anna
+ * Date: 9/25/13
+ */
+public abstract class InputOutputConstraintFormula implements ConstraintFormula {
+
+  protected abstract PsiExpression getExpression();
+  protected abstract PsiType getT();
+  protected abstract InputOutputConstraintFormula createSelfConstraint(PsiType type, PsiExpression expression);
+  protected abstract void collectReturnTypeVariables(InferenceSession session,
+                                                     PsiExpression psiExpression,
+                                                     PsiMethod interfaceMethod,
+                                                     Set<InferenceVariable> result);
+
+  public Set<InferenceVariable> getInputVariables(InferenceSession session) {
+    final PsiExpression psiExpression = getExpression();
+    if (PsiPolyExpressionUtil.isPolyExpression(psiExpression)) {
+      final PsiType type = getT();
+      if (psiExpression instanceof PsiLambdaExpression || psiExpression instanceof PsiMethodReferenceExpression) {
+        final InferenceVariable inferenceVariable = session.getInferenceVariable(type);
+        if (inferenceVariable != null) {
+          return Collections.singleton(inferenceVariable);
+        }
+        final PsiType functionalInterfaceType = psiExpression instanceof PsiLambdaExpression 
+                                                ? ((PsiLambdaExpression)psiExpression).getFunctionalInterfaceType() 
+                                                : ((PsiMethodReferenceExpression)psiExpression).getFunctionalInterfaceType();
+        if (functionalInterfaceType != null) {
+          final PsiType functionType =
+            psiExpression instanceof PsiLambdaExpression 
+            ? FunctionalInterfaceParameterizationUtil.getFunctionalType(functionalInterfaceType, (PsiLambdaExpression)psiExpression) 
+            : functionalInterfaceType;
+          final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionType);
+          final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
+          if (interfaceMethod != null) {
+
+            final Set<InferenceVariable> result = new HashSet<InferenceVariable>();
+            final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
+            for (PsiParameter parameter : interfaceMethod.getParameterList().getParameters()) {
+              session.collectDependencies(substitutor.substitute(parameter.getType()), result, true);
+            }
+
+            collectReturnTypeVariables(session, psiExpression, interfaceMethod, result);
+
+            return result;
+          }
+        }
+      }
+
+      if (psiExpression instanceof PsiParenthesizedExpression) {
+        final PsiExpression expression = ((PsiParenthesizedExpression)psiExpression).getExpression();
+        return expression != null ? createSelfConstraint(type, expression).getInputVariables(session) : null;
+      }
+
+      if (psiExpression instanceof PsiConditionalExpression) {
+        final PsiExpression thenExpression = ((PsiConditionalExpression)psiExpression).getThenExpression();
+        final PsiExpression elseExpression = ((PsiConditionalExpression)psiExpression).getElseExpression();
+        final Set<InferenceVariable> thenResult = thenExpression != null ? createSelfConstraint(type, thenExpression).getInputVariables(session) : null;
+        final Set<InferenceVariable> elseResult = elseExpression != null ? createSelfConstraint(type, elseExpression).getInputVariables(session) : null;
+        if (thenResult == null) {
+          return elseResult;
+        } else if (elseResult == null) {
+          return thenResult;
+        } else {
+          thenResult.addAll(elseResult);
+          return thenResult;
+        }
+      }
+    }
+    return null;
+  }
+
+
+  @Nullable
+  public Set<InferenceVariable> getOutputVariables(Set<InferenceVariable> inputVariables, InferenceSession session) {
+    if (!PsiPolyExpressionUtil.isPolyExpression(getExpression())) {
+      final HashSet<InferenceVariable> mentionedVariables = new HashSet<InferenceVariable>();
+      session.collectDependencies(getT(), mentionedVariables, true);
+      mentionedVariables.removeAll(inputVariables);
+      return mentionedVariables;
+    }
+    return null;
+  }
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
index 9d9dad46..d775175 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
@@ -1,8 +1,8 @@
 package com.intellij.psi.impl.source.resolve.graphInference.constraints;
 
 import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
 import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
-import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
 import com.intellij.psi.util.PsiUtil;
 
 import java.util.List;
@@ -20,30 +20,21 @@
   }
 
   @Override
-  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
-    final InferenceVariable inferenceVariable = session.getInferenceVariable(myT);
-    if (inferenceVariable != null) {
-      delayedConstraints.add(this);
-      return true;
-    }
+  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
     if (LambdaHighlightingUtil.checkInterfaceFunctional(myT) != null) {
       return false;
     }
 
     if (myExpression.hasFormalParameterTypes()) {
     }
-    final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(myT);
+    final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(
+      FunctionalInterfaceParameterizationUtil.getFunctionalType(myT, myExpression));
+    final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
     if (interfaceMethod == null) {
       return false;
     }
-    final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, PsiUtil.resolveGenericsClassInType(myT));
+    final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
     final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
-    for (PsiParameter parameter : parameters) {
-      if (!session.isProperType(parameter.getType())) {
-        delayedConstraints.add(this);
-        return true;
-      }
-    }
 
     final PsiParameter[] lambdaParameters = myExpression.getParameterList().getParameters();
     if (lambdaParameters.length != parameters.length) {
@@ -53,20 +44,27 @@
       for (int i = 0; i < lambdaParameters.length; i++) {
         constraints.add(new TypeEqualityConstraint(lambdaParameters[i].getType(), substitutor.substitute(parameters[i].getType())));
       }
+    } else {
+      for (PsiParameter parameter : parameters) {
+        if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
+          return false;
+        }
+      }
     }
 
     final PsiType returnType = interfaceMethod.getReturnType();
     if (returnType != null) {
+      final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions(myExpression);
       if (returnType.equals(PsiType.VOID)) {
-        if (!myExpression.isVoidCompatible() && !(myExpression.getBody() instanceof PsiExpression)) {
+        if (!returnExpressions.isEmpty() && !(myExpression.getBody() instanceof PsiExpression)) {
           return false;
         }
       } else {
-        if (myExpression.isVoidCompatible()) {  //not value-compatible
+        if (returnExpressions.isEmpty()) {  //not value-compatible
           return false;
         }
-        for (PsiExpression returnExpressions : LambdaUtil.getReturnExpressions(myExpression)) {
-          constraints.add(new ExpressionCompatibilityConstraint(returnExpressions, returnType));
+        for (PsiExpression returnExpression : returnExpressions) {
+          constraints.add(new ExpressionCompatibilityConstraint(returnExpression, substitutor.substitute(returnType)));
         }
       }
     }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
new file mode 100644
index 0000000..d1de66e
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
@@ -0,0 +1,100 @@
+/*
+ * 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.psi.impl.source.resolve.graphInference.constraints;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
+import com.intellij.psi.util.PsiUtil;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * User: anna
+ */
+public class PsiMethodReferenceCompatibilityConstraint implements ConstraintFormula {
+  private static final Logger LOG = Logger.getInstance("#" + PsiMethodReferenceCompatibilityConstraint.class.getName());
+  private final PsiMethodReferenceExpression myExpression;
+  private final PsiType myT;
+
+  public PsiMethodReferenceCompatibilityConstraint(PsiMethodReferenceExpression expression, PsiType t) {
+    myExpression = expression;
+    myT = t;
+  }
+
+  @Override
+  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
+    if (LambdaHighlightingUtil.checkInterfaceFunctional(myT) != null) {
+      return false;
+    }
+
+    final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(myT);
+    if (interfaceMethod == null) {
+      return false;
+    }
+    
+    final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, PsiUtil.resolveGenericsClassInType(myT));
+    final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
+    for (PsiParameter parameter : parameters) {
+      if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
+        return false;
+      }
+    }
+
+    final PsiElement resolve = myExpression.resolve();
+    if (resolve == null) {
+      return false;
+    }
+
+    final PsiType returnType = interfaceMethod.getReturnType();
+    LOG.assertTrue(returnType != null, interfaceMethod);
+    if (PsiType.VOID.equals(returnType)) {
+      return true;
+    }
+
+    if (resolve instanceof PsiMethod) {
+      final PsiMethod method = (PsiMethod)resolve;
+      final PsiType referencedMethodReturnType;
+      if (method.isConstructor()) {
+        final PsiClass containingClass = method.getContainingClass();
+        LOG.assertTrue(containingClass != null, method);
+        referencedMethodReturnType = JavaPsiFacade.getElementFactory(method.getProject()).createType(containingClass);
+      }
+      else {
+        referencedMethodReturnType = method.getReturnType();
+      }
+      LOG.assertTrue(referencedMethodReturnType != null, method);
+
+      if (myExpression.getTypeParameters().length == 0 &&
+          ((PsiMethod)resolve).getTypeParameters().length > 0 && 
+          PsiPolyExpressionUtil.mentionsTypeParameters(returnType, new HashSet<PsiTypeParameter>(Arrays.asList(interfaceMethod.getTypeParameters())))) {
+        //todo target type constraint
+        return true;
+      }
+
+      if (PsiType.VOID.equals(referencedMethodReturnType)) {
+        return false;
+      }
+ 
+      constraints.add(new TypeCompatibilityConstraint(substitutor.substitute(returnType), referencedMethodReturnType));
+    }
+    
+    return true;
+  }
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java
index 64c28d1..e2677bf7 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java
@@ -20,7 +20,6 @@
 import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
 import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
 import com.intellij.psi.util.TypeConversionUtil;
-import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
 
@@ -39,7 +38,7 @@
   }
 
   @Override
-  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
+  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
     if (myIsRefTypes) {
       if (session.isProperType(myS) && session.isProperType(myT)) {
         if (myT == null || myS == null) return myS == myT;
@@ -127,6 +126,11 @@
           }
           return false;
         } else {
+
+          if (myS instanceof PsiCapturedWildcardType) {
+            myS = ((PsiCapturedWildcardType)myS).getWildcard();
+          }
+
           if (myS instanceof PsiWildcardType) {
             final PsiType sBound = ((PsiWildcardType)myS).getBound();
             if (sBound != null && ((PsiWildcardType)myS).isSuper()) {
@@ -140,9 +144,19 @@
         }
         return false;
       } else {
+        InferenceVariable inferenceVariable = session.getInferenceVariable(myT);
         if (myS instanceof PsiWildcardType) {
-          return false;
+          return inferenceVariable != null && inferenceVariable.isCaptured();
         } else {
+          if (inferenceVariable != null) {
+            inferenceVariable.addBound(myS, InferenceBound.EQ);
+            return true;
+          }
+          inferenceVariable = session.getInferenceVariable(myS);
+          if (inferenceVariable != null) {
+            inferenceVariable.addBound(myT, InferenceBound.EQ);
+            return true;
+          }
           constraints.add(new SubtypingConstraint(myT, myS, true));
           return true;
         }
@@ -159,6 +173,9 @@
     SubtypingConstraint that = (SubtypingConstraint)o;
 
     if (myIsRefTypes != that.myIsRefTypes) return false;
+
+    if (!myIsRefTypes && myS instanceof PsiCapturedWildcardType && myS != that.myS) return false;
+
     if (myS != null ? !myS.equals(that.myS) : that.myS != null) return false;
     if (myT != null ? !myT.equals(that.myT) : that.myT != null) return false;
 
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java
index 353f03b..cd9ec95 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java
@@ -37,7 +37,7 @@
   }
 
   @Override
-  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
+  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
     if (session.isProperType(myT) && session.isProperType(myS)) {
       return TypeConversionUtil.isAssignable(myS, myT);
     }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java
index a714656..06e7b2b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java
@@ -38,7 +38,7 @@
   }
 
   @Override
-  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
+  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
     if (session.isProperType(myT) && session.isProperType(myS)) {
       return myT.equals(myS);
     }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java
index 4e2300f..80b7e94 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java
@@ -18,24 +18,23 @@
 import com.intellij.lang.ASTNode;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.psi.*;
-import com.intellij.psi.impl.source.Constants;
 import com.intellij.psi.impl.source.tree.*;
-import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.tree.ChildRoleBase;
+import com.intellij.psi.tree.IElementType;
 import com.intellij.util.CharTable;
 import org.jetbrains.annotations.NotNull;
 
-public class PsiArrayInitializerExpressionImpl extends ExpressionPsiElement implements PsiArrayInitializerExpression, Constants {
+public class PsiArrayInitializerExpressionImpl extends ExpressionPsiElement implements PsiArrayInitializerExpression {
   private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiArrayInitializerExpressionImpl");
 
   public PsiArrayInitializerExpressionImpl() {
-    super(ARRAY_INITIALIZER_EXPRESSION);
+    super(JavaElementType.ARRAY_INITIALIZER_EXPRESSION);
   }
 
   @Override
   @NotNull
   public PsiExpression[] getInitializers(){
-    return getChildrenAsPsiElements(EXPRESSION_BIT_SET, PsiExpression.ARRAY_FACTORY);
+    return getChildrenAsPsiElements(ElementType.EXPRESSION_BIT_SET, PsiExpression.ARRAY_FACTORY);
   }
 
   @Override
@@ -69,10 +68,10 @@
         return null;
 
       case ChildRole.LBRACE:
-        return findChildByType(LBRACE);
+        return findChildByType(JavaTokenType.LBRACE);
 
       case ChildRole.RBRACE:
-        return findChildByType(RBRACE);
+        return findChildByType(JavaTokenType.RBRACE);
     }
   }
 
@@ -80,17 +79,17 @@
   public int getChildRole(ASTNode child) {
     LOG.assertTrue(child.getTreeParent() == this);
     IElementType i = child.getElementType();
-    if (i == COMMA) {
+    if (i == JavaTokenType.COMMA) {
       return ChildRole.COMMA;
     }
-    else if (i == LBRACE) {
+    else if (i == JavaTokenType.LBRACE) {
       return ChildRole.LBRACE;
     }
-    else if (i == RBRACE) {
+    else if (i == JavaTokenType.RBRACE) {
       return ChildRole.RBRACE;
     }
     else {
-      if (EXPRESSION_BIT_SET.contains(child.getElementType())) {
+      if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
         return ChildRole.EXPRESSION_IN_LIST;
       }
       return ChildRoleBase.NONE;
@@ -129,17 +128,17 @@
     if (ElementType.EXPRESSION_BIT_SET.contains(first.getElementType())) {
      final CharTable charTab = SharedImplUtil.findCharTableByTree(this);
       for (ASTNode child = first.getTreeNext(); child != null; child = child.getTreeNext()) {
-        if (child.getElementType() == COMMA) break;
+        if (child.getElementType() == JavaTokenType.COMMA) break;
         if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
-          TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, charTab, getManager());
+          TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, charTab, getManager());
           super.addInternal(comma, comma, first, Boolean.FALSE);
           break;
         }
       }
       for (ASTNode child = first.getTreePrev(); child != null; child = child.getTreePrev()) {
-        if (child.getElementType() == COMMA) break;
+        if (child.getElementType() == JavaTokenType.COMMA) break;
         if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
-          TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, charTab, getManager());
+          TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, charTab, getManager());
           super.addInternal(comma, comma, child, Boolean.FALSE);
           break;
         }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java
index 3093099..5091ea0 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java
@@ -19,6 +19,7 @@
 import com.intellij.psi.*;
 import com.intellij.psi.controlFlow.*;
 import com.intellij.psi.impl.PsiImplUtil;
+import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
 import com.intellij.psi.impl.source.tree.ChildRole;
 import com.intellij.psi.impl.source.tree.JavaElementType;
 import com.intellij.psi.scope.PsiScopeProcessor;
@@ -63,7 +64,7 @@
   @Nullable
   @Override
   public PsiType getFunctionalInterfaceType() {
-    return LambdaUtil.getFunctionalInterfaceType(this, true);
+    return FunctionalInterfaceParameterizationUtil.getFunctionalType(LambdaUtil.getFunctionalInterfaceType(this, true), this);
   }
 
   @Override
@@ -118,6 +119,6 @@
     for (PsiParameter parameter : parameters) {
       if (parameter.getTypeElement() == null) return false;
     }
-    return parameters.length > 0;
+    return true;
   }
 }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
index 1dd74f1..36013c36 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
@@ -170,7 +170,7 @@
     }
 
     @Nullable
-    private static PsiType getResultType(PsiExpression call,
+    private static PsiType getResultType(PsiMethodCallExpression call,
                                          PsiReferenceExpression methodExpression,
                                          JavaResolveResult result,
                                          @NotNull final LanguageLevel languageLevel) {
@@ -196,40 +196,46 @@
         ret = ((PsiClassType)ret).setLanguageLevel(languageLevel);
       }
       if (is15OrHigher) {
-        final PsiSubstitutor substitutor = result.getSubstitutor();
-        PsiType substitutedReturnType = substitutor.substitute(ret);
-        if (substitutedReturnType == null) return TypeConversionUtil.erasure(ret);
-        if (PsiUtil.isRawSubstitutor(method, substitutor)) {
-          final PsiType returnTypeErasure = TypeConversionUtil.erasure(ret);
-          if (Comparing.equal(TypeConversionUtil.erasure(substitutedReturnType), returnTypeErasure)) {
-            return returnTypeErasure;
-          }
-        }
-        PsiType lowerBound = PsiType.NULL;
-        if (substitutedReturnType instanceof PsiCapturedWildcardType) {
-          lowerBound = ((PsiCapturedWildcardType)substitutedReturnType).getLowerBound();
-        } else if (substitutedReturnType instanceof PsiWildcardType) {
-          lowerBound = ((PsiWildcardType)substitutedReturnType).getSuperBound();
-        }
-        if (lowerBound != PsiType.NULL) { //? super
-          final PsiClass containingClass = method.getContainingClass();
-          final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
-          final PsiClass childClass = qualifierExpression != null ? PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType()) : null;
-          if (containingClass != null && childClass != null) {
-            final PsiType typeInChildClassTypeParams = TypeConversionUtil.getSuperClassSubstitutor(containingClass, childClass, PsiSubstitutor.EMPTY).substitute(ret);
-            final PsiClass substituted = PsiUtil.resolveClassInClassTypeOnly(typeInChildClassTypeParams);
-            if (substituted instanceof PsiTypeParameter) {
-              final PsiClassType[] extendsListTypes = substituted.getExtendsListTypes();
-              if (extendsListTypes.length == 1) {
-                return extendsListTypes[0];
-              }
-            }
-          }
-        }
-        return PsiImplUtil.normalizeWildcardTypeByPosition(substitutedReturnType, call);
+        return captureReturnType(call, method, ret, result.getSubstitutor());
       }
       return TypeConversionUtil.erasure(ret);
     }
   }
+
+  public static PsiType captureReturnType(PsiMethodCallExpression call,
+                                          PsiMethod method,
+                                          PsiType ret,
+                                          PsiSubstitutor substitutor) {
+    PsiType substitutedReturnType = substitutor.substitute(ret);
+    if (substitutedReturnType == null) return TypeConversionUtil.erasure(ret);
+    if (PsiUtil.isRawSubstitutor(method, substitutor)) {
+      final PsiType returnTypeErasure = TypeConversionUtil.erasure(ret);
+      if (Comparing.equal(TypeConversionUtil.erasure(substitutedReturnType), returnTypeErasure)) {
+        return returnTypeErasure;
+      }
+    }
+    PsiType lowerBound = PsiType.NULL;
+    if (substitutedReturnType instanceof PsiCapturedWildcardType) {
+      lowerBound = ((PsiCapturedWildcardType)substitutedReturnType).getLowerBound();
+    } else if (substitutedReturnType instanceof PsiWildcardType) {
+      lowerBound = ((PsiWildcardType)substitutedReturnType).getSuperBound();
+    }
+    if (lowerBound != PsiType.NULL) { //? super
+      final PsiClass containingClass = method.getContainingClass();
+      final PsiExpression qualifierExpression = call.getMethodExpression().getQualifierExpression();
+      final PsiClass childClass = qualifierExpression != null ? PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType()) : null;
+      if (containingClass != null && childClass != null) {
+        final PsiType typeInChildClassTypeParams = TypeConversionUtil.getSuperClassSubstitutor(containingClass, childClass, PsiSubstitutor.EMPTY).substitute(ret);
+        final PsiClass substituted = PsiUtil.resolveClassInClassTypeOnly(typeInChildClassTypeParams);
+        if (substituted instanceof PsiTypeParameter) {
+          final PsiClassType[] extendsListTypes = substituted.getExtendsListTypes();
+          if (extendsListTypes.length == 1) {
+            return extendsListTypes[0];
+          }
+        }
+      }
+    }
+    return PsiImplUtil.normalizeWildcardTypeByPosition(substitutedReturnType, call);
+  }
 }
 
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
index 4678857..537ce23 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
@@ -72,6 +72,15 @@
   }
 
   @Override
+  public boolean isExact() {
+    PsiElement resolve = resolve();
+    if (resolve instanceof PsiMethod) {
+      return !((PsiMethod)resolve).isVarArgs();
+    }
+    return true;
+  }
+
+  @Override
   public PsiExpression getQualifierExpression() {
     final PsiElement qualifier = getQualifier();
     return qualifier instanceof PsiExpression ? (PsiExpression)qualifier : null;
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
index 27e4227..6992e9f 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
@@ -51,15 +51,15 @@
   private static final Logger LOG = Logger.getInstance("#com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver");
 
   private final PsiElement myArgumentsList;
-  private final PsiType[] myActualParameterTypes;
+  private PsiType[] myActualParameterTypes;
   protected LanguageLevel myLanguageLevel;
 
   public JavaMethodsConflictResolver(@NotNull PsiExpressionList list, @NotNull LanguageLevel languageLevel) {
-    this(list, list.getExpressionTypes(), languageLevel);
+    this(list, null, languageLevel);
   }
 
   public JavaMethodsConflictResolver(@NotNull PsiElement argumentsList,
-                                     @NotNull PsiType[] actualParameterTypes,
+                                     PsiType[] actualParameterTypes,
                                      @NotNull LanguageLevel languageLevel) {
     myArgumentsList = argumentsList;
     myActualParameterTypes = actualParameterTypes;
@@ -71,7 +71,7 @@
     if (conflicts.isEmpty()) return null;
     if (conflicts.size() == 1) return conflicts.get(0);
 
-    boolean atLeastOneMatch = checkParametersNumber(conflicts, myActualParameterTypes.length, true);
+    boolean atLeastOneMatch = checkParametersNumber(conflicts, getActualParameterTypes().length, true);
     if (conflicts.size() == 1) return conflicts.get(0);
 
     checkSameSignatures(conflicts);
@@ -80,7 +80,7 @@
     checkAccessStaticLevels(conflicts, true);
     if (conflicts.size() == 1) return conflicts.get(0);
 
-    checkParametersNumber(conflicts, myActualParameterTypes.length, false);
+    checkParametersNumber(conflicts, getActualParameterTypes().length, false);
     if (conflicts.size() == 1) return conflicts.get(0);
 
     final int applicabilityLevel = checkApplicability(conflicts);
@@ -96,7 +96,7 @@
     checkSpecifics(conflicts, applicabilityLevel, myLanguageLevel);
     if (conflicts.size() == 1) return conflicts.get(0);
 
-    checkPrimitiveVarargs(conflicts, myActualParameterTypes.length);
+    checkPrimitiveVarargs(conflicts, getActualParameterTypes().length);
     if (conflicts.size() == 1) return conflicts.get(0);
 
     checkAccessStaticLevels(conflicts, false);
@@ -109,8 +109,8 @@
 
   private void checkLambdaApplicable(@NotNull List<CandidateInfo> conflicts, @NotNull LanguageLevel languageLevel) {
     if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) return;
-    for (int i = 0; i < myActualParameterTypes.length; i++) {
-      PsiType parameterType = myActualParameterTypes[i];
+    for (int i = 0; i < getActualParameterTypes().length; i++) {
+      PsiType parameterType = getActualParameterTypes()[i];
       if (parameterType instanceof PsiLambdaExpressionType) {
         final PsiLambdaExpression lambdaExpression = ((PsiLambdaExpressionType)parameterType).getExpression();
         for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
@@ -122,7 +122,7 @@
             if (methodParameters.length == 0) continue;
             final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1];
             final PsiType paramType = param.getType();
-            if (!LambdaUtil.isAcceptable(lambdaExpression, conflict.getSubstitutor().substitute(paramType), true)) {
+            if (!LambdaUtil.isAcceptable(lambdaExpression, conflict.getSubstitutor().substitute(paramType), lambdaExpression.hasFormalParameterTypes())) {
               iterator.remove();
             } else {
               /*todo
@@ -141,7 +141,7 @@
         }
       }
     }
-    checkMoreSpecificReturnType(conflicts, myActualParameterTypes, languageLevel);
+    checkMoreSpecificReturnType(conflicts, getActualParameterTypes(), languageLevel);
   }
 
   public void checkSpecifics(@NotNull List<CandidateInfo> conflicts,
@@ -426,6 +426,14 @@
            (method.getCurrentFileResolveScope() instanceof PsiImportStaticStatement ? 0 : 1);
   }
 
+  private PsiType[] getActualParameterTypes() {
+    if (myActualParameterTypes == null) {
+      LOG.assertTrue(myArgumentsList instanceof PsiExpressionList, myArgumentsList);
+      myActualParameterTypes = ((PsiExpressionList)myArgumentsList).getExpressionTypes();
+    }
+    return myActualParameterTypes;
+  }
+
   private enum Specifics {
     FIRST,
     SECOND,
@@ -489,7 +497,7 @@
       ProgressManager.checkCanceled();
       PsiType type1 = classSubstitutor1.substitute(types1[i]);
       PsiType type2 = classSubstitutor2.substitute(types2[i]);
-      PsiType argType = i < myActualParameterTypes.length ? myActualParameterTypes[i] : null;
+      PsiType argType = i < getActualParameterTypes().length ? getActualParameterTypes()[i] : null;
 
       boolean boxingInFirst = false;
       if (isBoxingHappened(argType, type1, languageLevel)) {
@@ -691,6 +699,12 @@
       for (int functionalInterfaceIdx = 0; functionalInterfaceIdx < actualParameterTypes.length; functionalInterfaceIdx++) {
         final PsiType interfaceReturnType = getReturnType(functionalInterfaceIdx, method);
         final PsiType interfaceReturnType1 = getReturnType(functionalInterfaceIdx, conflict);
+        if (actualParameterTypes[functionalInterfaceIdx] instanceof PsiLambdaExpressionType) {
+          final PsiLambdaExpression lambdaExpression = ((PsiLambdaExpressionType)actualParameterTypes[functionalInterfaceIdx]).getExpression();
+          if (!lambdaExpression.hasFormalParameterTypes()) {
+            return Specifics.NEITHER;
+          }
+        }
         if (actualParameterTypes[functionalInterfaceIdx] instanceof PsiLambdaExpressionType || actualParameterTypes[functionalInterfaceIdx] instanceof PsiMethodReferenceType) {
           if (interfaceReturnType != null && interfaceReturnType1 != null && !Comparing.equal(interfaceReturnType, interfaceReturnType1)) {
             Specifics moreSpecific1 = comparePrimitives(actualParameterTypes[functionalInterfaceIdx], interfaceReturnType, interfaceReturnType1);
diff --git a/java/java-tests/testData/codeInsight/completion/normal/NoFieldsInImplements.java b/java/java-tests/testData/codeInsight/completion/normal/NoFieldsInImplements.java
new file mode 100644
index 0000000..bb4a834
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/NoFieldsInImplements.java
@@ -0,0 +1,9 @@
+public class Doo implements Intf.I<caret> {
+}
+
+
+
+interface Intf {
+  int INT_FIELD = 2;
+  interface Inner {}
+}
diff --git a/java/java-tests/testData/codeInsight/completion/normal/NoFieldsInImplements_after.java b/java/java-tests/testData/codeInsight/completion/normal/NoFieldsInImplements_after.java
new file mode 100644
index 0000000..ea272a1
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/NoFieldsInImplements_after.java
@@ -0,0 +1,9 @@
+public class Doo implements Intf.Inner<caret> {
+}
+
+
+
+interface Intf {
+  int INT_FIELD = 2;
+  interface Inner {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AmbiguousTypeParamVsConcrete.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AmbiguousTypeParamVsConcrete.java
new file mode 100644
index 0000000..272fb29
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AmbiguousTypeParamVsConcrete.java
@@ -0,0 +1,22 @@
+public class CssPropertyValueImpl extends CssTableValueBase<CssPropertyValue, Object> implements CssPropertyValue {
+  public CssPropertyValueImpl(final Type type) {
+    super(type);
+  }
+}
+
+public abstract class CssTableValueBase<V extends CssTableValue, T> implements CssTableValue<V, T> {
+
+  protected CssTableValueBase(final Type type) {
+  }
+
+  protected CssTableValueBase(final T value) {
+  }
+}
+
+enum Type {}
+
+interface CssTableValue<A, B> {
+}
+
+interface CssPropertyValue extends CssTableValue<CssPropertyValue, Object> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AnnotationsAsPartOfModifierList.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AnnotationsAsPartOfModifierList.java
new file mode 100644
index 0000000..3fca0c0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AnnotationsAsPartOfModifierList.java
@@ -0,0 +1,9 @@
+@Deprecated @SuppressWarnings("")
+<error descr="Class 'Foo' must either be declared abstract or implement abstract method 'run()' in 'Runnable'">public class Foo implements Runnable</error> {
+
+}
+
+class F {
+  @Deprecated @SuppressWarnings("") <error descr="'f()' is already defined in 'F'">void f()</error> {}
+  @Deprecated @SuppressWarnings("") <error descr="'f()' is already defined in 'F'">void f()</error> {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Autoboxing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Autoboxing.java
new file mode 100644
index 0000000..9815668
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Autoboxing.java
@@ -0,0 +1,69 @@
+public class Autoboxing {
+    public boolean compare(short s, Integer i) {
+         return i == s; //OK, i is unboxed
+    }
+
+    public boolean compare(Short s, Integer i) {
+         return <error descr="Operator '==' cannot be applied to 'java.lang.Integer', 'java.lang.Short'">i == s</error>; //comparing as references
+    }
+
+    void f(Integer i) {
+      switch(i) {
+       default:
+      }
+    }
+
+    {
+      Object data = 1;
+      boolean is1 = <error descr="Operator '==' cannot be applied to 'java.lang.Object', 'int'">data == 1</error>;
+    }
+
+    //IDEADEV-5549: Short and double are convertible
+    public static double f () {
+      Short s = 0;
+      return (double)s;
+    }
+
+    //IDEADEV-5613
+    class DumbTest {
+      private long eventId;
+
+      public int hashCode() {
+        return ((Long) eventId).hashCode();
+      }
+    }
+
+    public static void main(String[] args) {
+        Long l = 0L;
+        Short s = 0;
+
+        int d = <error descr="Inconvertible types; cannot cast 'java.lang.Long' to 'int'">(int)l</error>;
+        d = (int)s;
+
+        short t = 0;
+        Integer d1 = <error descr="Inconvertible types; cannot cast 'short' to 'java.lang.Integer'">(Integer) t</error>;
+        Byte b = <error descr="Inconvertible types; cannot cast 'short' to 'java.lang.Byte'">(Byte) t</error>;
+
+    }
+
+  {
+    {
+      boolean cond = true;
+      // test for JLS3 bug, see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6888770
+      Byte B = 0;
+      byte b = 0;
+      byte value = cond ? B : b;  /////////
+
+      short s = 0;
+      Short S = 0;
+      short rs = cond ? S : s;
+
+      char c = 0;
+      Character C = 0;
+      char rc = cond ? C : c;
+
+      boolean bb = cond ? Boolean.FALSE : true;
+    }
+    
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AutoboxingConstructors.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AutoboxingConstructors.java
new file mode 100644
index 0000000..12c5332
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AutoboxingConstructors.java
@@ -0,0 +1,13 @@
+public class Test {
+
+    public Test(Object a) {
+    }
+
+    public Test(int i) {
+        this(new Integer(i));
+    }
+
+    public Test(long l) {
+        this(new Long(l));
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AutoboxingMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AutoboxingMethods.java
new file mode 100644
index 0000000..d020997
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AutoboxingMethods.java
@@ -0,0 +1,44 @@
+public class Autoboxing {
+    void method(int i) {
+        System.out.println("i = " + i);
+    }
+
+    void method(Integer integer) {
+        System.out.println("integer = " + integer);
+    }
+
+    void m1(Integer integer) { }
+    void m2(int i) { }
+
+    {
+        method(10);
+        method(new Integer(10));
+        m1(10);
+        m1(new Integer(10));
+        m2(10);
+        m2(new Integer(10));
+    }
+}
+public class Autoboxing1 {
+    void method(String s, int i) {
+        System.out.println("i = " + i);
+    }
+
+    void method(String s, Object o) {
+        System.out.println("integer = " + o);
+    }
+
+    {
+        method("abc", new Integer(10));
+        method("abc", 10);
+    }
+}
+
+class BoxingConflict {
+    public static void main(String[] args) {
+        add<error descr="Ambiguous method call: both 'BoxingConflict.add(long, Long)' and 'BoxingConflict.add(Long, Long)' match">(0L, 0L)</error>;
+    }
+
+    public static void add(long k, Long v) { }
+    public static void add(Long k, Long v) { }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/BooleanInferenceFromIfCondition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/BooleanInferenceFromIfCondition.java
new file mode 100644
index 0000000..44fbeef
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/BooleanInferenceFromIfCondition.java
@@ -0,0 +1,12 @@
+public class Main {
+    public <T> T getAttribute() {return null;}
+    public <T> T getAttribute(T def) {return null;}
+
+    {
+        if (getAttribute()) {}
+
+        while (getAttribute()) {}
+        do {} while (getAttribute());
+        for(int i = 0; getAttribute(); i++);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/BoxingSpecific.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/BoxingSpecific.java
new file mode 100644
index 0000000..382f4e7
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/BoxingSpecific.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+abstract class A {
+    void computeCostIfNeeded(Map<Object, Integer> costMap) {
+        Math.min(costMap.get(null), 1);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CaptureTopLevelWildcardsForConditionalExpression.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CaptureTopLevelWildcardsForConditionalExpression.java
new file mode 100644
index 0000000..86c2e40
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CaptureTopLevelWildcardsForConditionalExpression.java
@@ -0,0 +1,6 @@
+import java.util.*;
+class Bug {
+    void foo(Double d) {
+       List<Class<?>> list = Arrays.asList(d == null ? Object.class : d.getClass());
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CaptureWildcardsInTypeCasts.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CaptureWildcardsInTypeCasts.java
new file mode 100644
index 0000000..9bd704b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CaptureWildcardsInTypeCasts.java
@@ -0,0 +1,8 @@
+import java.util.Collection;
+
+class Foo {
+  private void test() {
+    Object x = null;
+    ((java.util.Collection<?>)x).add<error descr="'add(capture<?>)' in 'java.util.Collection' cannot be applied to '(java.lang.String)'">("")</error>;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CapturedWildcardAssignments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CapturedWildcardAssignments.java
new file mode 100644
index 0000000..08761a6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CapturedWildcardAssignments.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.*;
+
+public class Test {
+    public static void bar() {
+      <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends java.util.Iterator>>', required: 'java.lang.Class<? extends java.util.Iterator<?>>'">Class<? extends Iterator<?>> c = foo();</error>
+    }
+  
+    public static Class<? extends Iterator> foo() {
+      return null;
+    }
+}
+
+class Example {
+    static List<? extends AbstractTreeNode> treeNodes = null;
+
+    public static void main(String[] args) {
+        for (AbstractTreeNode<String> treeNode : treeNodes) {
+
+        }
+    }
+
+}
+class AbstractTreeNode<T> {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ClassInheritance.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ClassInheritance.java
new file mode 100644
index 0000000..1a4e80f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ClassInheritance.java
@@ -0,0 +1,122 @@
+class D implements I<I>{
+}
+class DT<T> implements I<T>{
+}
+
+interface I <T> {
+}
+
+<error descr="'I' cannot be inherited with different type arguments: 'I' and 'D'">class CCC extends D implements I<D></error> {
+}
+abstract class CCC2<T> extends DT<T> implements I<T> {
+}
+
+class a extends b<d, c> implements c<d, c<c,c>>, d<b<c<c,c>,d>> {}
+public class b<K,V> implements c<K, c<V,V>> { }
+interface c<K,V> extends d<b<V,K>> {}
+interface d<K> {}
+
+// extending final classes in bounds
+class C<T extends String> {
+ <E extends Integer> void f() {}
+}
+
+class GenericExtendItself<T, U extends T>
+{
+    GenericExtendItself<Object,Object> foo;
+}
+
+
+////////////////////
+public abstract class ZZZZ<E> {
+    public abstract E getElement();
+}
+abstract class Z<E> extends ZZZZ<E> {}
+class Z2 extends Z<Integer> {
+    public Integer getElement() {
+        return null;  
+    }
+}
+/////////////////
+class BaseC <E> {
+    E remove(){
+        return null;
+    }
+}
+
+class DerivedC extends BaseC<String> {
+    public String remove() {
+        String s = super.remove();
+        return null;
+    }
+}
+
+/// raw in the multiple supers
+interface Int<T> {
+    AClass<T> f();
+}
+abstract class AClass<T> implements Int<T> {
+    public abstract AClass<T> f();
+}
+
+class MyClass extends AClass implements Int{
+    public AClass f() {
+        return null;
+    }
+}
+
+class A<T>{
+  A(){}
+  A(T t){}
+
+  {
+   new A<A>(new A()){};
+  }
+}
+
+//IDEADEV-4733: this overriding is OK
+class Outer<T>
+{
+    public class Inner
+    {
+        private final T t;
+
+        public Inner(T t) { this.t = t; }
+
+        public T getT() { return t; }
+
+        public String toString() { return t.toString(); }
+    }
+}
+
+class Other extends Outer<String>
+{
+    public class Ither extends Outer<String>.Inner
+    {
+        public Ither()
+        {
+            super("hello"); //valid super constructor call
+        }
+    }
+}
+
+//end of //IDEADEV-4733
+interface AI {
+}
+interface BI {
+}
+abstract class AbstractClass<T> {
+    AbstractClass(Class<T> clazz) {
+    }
+}
+class ConcreteClass extends AbstractClass<AI> {
+    ConcreteClass() {
+        super(AI.class);
+    }
+    class InnerClass extends AbstractClass<BI> {
+        InnerClass() {
+            super(BI.class); //
+        }
+    }
+}
+///////////////////////
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ConditionalExpression.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ConditionalExpression.java
new file mode 100644
index 0000000..88c1d57
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ConditionalExpression.java
@@ -0,0 +1,21 @@
+import java.util.TreeMap;
+import java.util.HashMap;
+import java.util.Map;
+
+class Test {
+  boolean f () {
+    return false;
+  }
+
+  Boolean g (int i) {
+    //This is OK thanks to boxing f()
+    return i > 0 ? f () : null;
+  }
+
+  {
+    Object values = new Object();
+    //IDEADEV-1756: this should be OK
+    final Map<Object,Object> newValues = true ? new TreeMap<Object,Object>() : new HashMap<Object,Object>();
+    newValues.get(values);
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ContinueInferenceAfterFirstRawResult.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ContinueInferenceAfterFirstRawResult.java
new file mode 100644
index 0000000..eeab573
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ContinueInferenceAfterFirstRawResult.java
@@ -0,0 +1,23 @@
+import java.util.*;
+
+class Test {
+
+  List<String> getList(Function<Object, String> function) {
+        /*
+         * When the first argument below is a raw type it turns red because IDEA thinks the return
+         * type is Collection<>.  javac and Eclipse don't care
+         */
+    return  transform(new ArrayList(), new ArrayList<String>(), function);
+  }
+
+  <R, S, T extends Collection<S>> T transform(Iterable<? extends R> oldCollection, T newCollection, Function<R, S> function) {
+    for (R r : oldCollection) {
+      newCollection.add(function.apply(r));
+    }
+    return newCollection;
+  }
+
+  interface Function<X, Y> {
+    Y apply(X input);
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ConvertibleTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ConvertibleTypes.java
new file mode 100644
index 0000000..572ef4a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ConvertibleTypes.java
@@ -0,0 +1,90 @@
+import java.util.Collection;
+import java.util.ArrayList;
+
+interface YO<<warning descr="Type parameter 'T' is never used">T</warning>> {}
+interface YO1 extends YO<String> {}
+interface YO2 extends YO<Integer> {}
+
+public class ConvertibleTest {
+
+    YO2 bar (YO1 s) {
+          return <error descr="Inconvertible types; cannot cast 'YO1' to 'YO2'">(YO2) s</error>;
+    }
+}
+
+
+//IDEA-1097
+interface Interface1 {}
+interface Interface2 {}
+
+class Implementation implements Interface1 {}
+
+public class InconvertibleTypesTest <E extends Interface2>
+{
+    E thing;
+
+    public E getThing() {
+         return thing;
+    }
+
+    Implementation foo(InconvertibleTypesTest<? extends Interface1> i2) {
+       //This is a valid cast from intersection type
+       return (Implementation) i2.getThing();
+    }
+}
+
+class MyCollection extends ArrayList<Integer> {}
+class Tester {
+    Collection<String> x(MyCollection l) {
+        return <error descr="Inconvertible types; cannot cast 'MyCollection' to 'java.util.Collection<java.lang.String>'">(Collection<String>) l</error>;
+    }
+}
+
+
+class IDEADEV3978 {
+    class Constructor<T> {
+        Class<T> getDeclaringClass() {
+            return null;
+        }
+    }
+    public static void foo(Constructor<?> constructor) {
+        if(constructor.getDeclaringClass() == String.class) { //captured wildcard is convertible
+            System.out.println("yep");
+        }
+    }
+}
+
+class C2<T> {
+   void f(T t) {
+     if (t instanceof Object[]) return;
+   }
+}
+
+class Casting {
+ void f(Object o)
+ {
+         if (o instanceof int[]) return;
+
+         Object obj1 = (Object)true;   f(obj1);
+         Object ob = (Number)1;        f(ob);
+         Object ob2 = (Object)1;       f(ob2);
+
+ }
+
+ public static <T> T convert(Class<T> clazz, Object obj) {
+     if (obj == null) return null;
+     if (String[].class == clazz)
+        return <warning descr="Unchecked cast: 'java.lang.String[]' to 'T'">(T) parseArray(obj)</warning>;
+     return null;
+ }
+
+ private static String[] parseArray(Object obj) {
+    return obj.toString().split(",");
+ }
+}
+
+class CastPrimitiveToTypeParam<T> {
+  T foo() {
+    return <error descr="Inconvertible types; cannot cast 'int' to 'T'">(T)1</error>;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DeepConflictingReturnTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DeepConflictingReturnTypes.java
new file mode 100644
index 0000000..0477aee
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DeepConflictingReturnTypes.java
@@ -0,0 +1,21 @@
+class W {
+    Object f() {
+        return 0;
+    }
+}
+
+class WW extends W {
+    String f() {
+        return null;
+    }
+}
+
+interface IQ {
+    void f();
+}
+
+
+<error descr="'f()' in 'WW' clashes with 'f()' in 'IQ'; attempting to use incompatible return type">class WWW extends WW implements IQ</error> {
+
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DifferentTypeParamsInOverloadedMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DifferentTypeParamsInOverloadedMethods.java
new file mode 100644
index 0000000..4feabc9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DifferentTypeParamsInOverloadedMethods.java
@@ -0,0 +1,28 @@
+import java.util.*;
+class Nav {
+    interface Sized {}
+    interface Stream<<warning descr="Type parameter 'T' is never used">T</warning>> { }
+
+    private static<U, T extends Sized & Iterable<U>> Stream<U> stream(T entity, int flags) {
+        System.out.println(entity);
+        System.out.println(flags);
+        return null;
+    }
+
+    private static<U, T extends Iterable<U>> Stream<U> <warning descr="Private method 'stream(T, int)' is never used">stream</warning>(T entity, int flags) {
+        System.out.println(entity);
+        System.out.println(flags);
+        return null;
+    }
+
+    static class A<T> implements Iterable<T>, Sized {
+        public Iterator<T> iterator() {
+            return null;
+        }
+    }
+
+    public static void main(String[] args) {
+        Stream<String> aStream = stream(new A<String>(), 0);
+        System.out.println(aStream);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DisableCastingToNestedWildcards.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DisableCastingToNestedWildcards.java
new file mode 100644
index 0000000..9c076ab
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DisableCastingToNestedWildcards.java
@@ -0,0 +1,32 @@
+import java.util.List;
+
+public class Test {
+
+    interface P {
+
+    }
+
+    public abstract class AP implements P {
+
+    }
+
+    public class AP1 extends AP {
+
+    }
+
+    public class AP2 extends AP {
+
+    }
+
+    private static final List<Class<AP1>> AP_LIST = listOf(AP1.class);
+
+
+    private static <T> List<T> listOf(T... ts) {
+        return null;
+    }
+
+    public static void test() {
+        List<Class<? extends AP>> apList1 = <error descr="Inconvertible types; cannot cast 'java.util.List<java.lang.Class<Test.AP1>>' to 'java.util.List<java.lang.Class<? extends Test.AP>>'">(List<Class<? extends AP>>) AP_LIST</error>;
+        List<Class<? super AP1>> apList2 = <error descr="Inconvertible types; cannot cast 'java.util.List<java.lang.Class<Test.AP1>>' to 'java.util.List<java.lang.Class<? super Test.AP1>>'">(List<Class<? super AP1>>) AP_LIST</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DisableWithinBoundsCheckForSuperWildcards.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DisableWithinBoundsCheckForSuperWildcards.java
new file mode 100644
index 0000000..703c377
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DisableWithinBoundsCheckForSuperWildcards.java
@@ -0,0 +1,15 @@
+import java.util.Comparator;
+
+public class Main2 {
+    static class OfRef<T> {
+        public OfRef() {
+             this((Comparator<? super T>)  naturalOrder());
+        }
+
+        public OfRef(Comparator<? super T> comparator) {
+        }
+        static <K extends Comparable<? super K>> Comparator<K> naturalOrder() {
+            return null;
+        }
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DoNotAcceptLowerBoundIfRaw.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DoNotAcceptLowerBoundIfRaw.java
new file mode 100644
index 0000000..b132d74
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DoNotAcceptLowerBoundIfRaw.java
@@ -0,0 +1,17 @@
+import java.util.*;
+
+class Test {
+  interface Condition<K> {}
+  class IOC<M> implements Condition {}
+
+  static <T> List<T> filter(T[] c, Condition<? super T> con) {
+    return null;
+  }
+
+  interface OE {}
+  interface LOE extends OE {}
+
+  void foo(OE[] es, IOC<LOE> con) {
+    List<LOE> l = filter(es, con);
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Enum.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Enum.java
new file mode 100644
index 0000000..027ada4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Enum.java
@@ -0,0 +1,205 @@
+enum Operation {
+  X;
+  static int s = 0;
+  public static final String constS = "";
+  Operation() {
+    int i = <error descr="It is illegal to access static member 's' from enum constructor or instance initializer">Operation.s</error>;
+    i = <error descr="It is illegal to access static member 's' from enum constructor or instance initializer">s</error>;
+    <error descr="It is illegal to access static member 's' from enum constructor or instance initializer">s</error> = 0;
+    final int x = Integer.MAX_VALUE;
+    String co = constS;
+    // TODO: unclear
+    //Operation o = X;
+  }
+  static {
+    int i = Operation.s;
+    i = s;
+    s = 0;
+    final int x = Integer.MAX_VALUE;
+    String co = constS;
+    // TODO: unclear
+    //Operation o = X;
+  }
+  {
+    int i = <error descr="It is illegal to access static member 's' from enum constructor or instance initializer">Operation.s</error>;
+    i = <error descr="It is illegal to access static member 's' from enum constructor or instance initializer">s</error>;
+    <error descr="It is illegal to access static member 's' from enum constructor or instance initializer">s</error> = 0;
+    final int x = Integer.MAX_VALUE;
+    String co = constS;
+    // TODO: unclear
+    //Operation o = X;
+
+    Operation ooo = <error descr="Enum types cannot be instantiated">new Operation()</error>;
+  }
+
+  <error descr="'values()' is already defined in 'Operation'">void values()</error> {}
+  void values(int i) {}
+  void valueOf() {}
+  <error descr="'valueOf(String)' is already defined in 'Operation'">void valueOf(String s)</error> {}
+}
+
+class exte extends <error descr="Cannot inherit from final 'Operation'">Operation</error> {
+}
+
+class use {
+  void f(Operation op) {
+   switch(op) {
+    case <error descr="An enum switch case label must be the unqualified name of an enumeration constant">Operation.X</error>: break;
+   }
+   switch(op) {
+    case X: break;
+   }
+   switch(op) {
+    case <error descr="Duplicate label 'X'">X</error>: break;
+    case <error descr="Duplicate label 'X'">X</error>: break;
+   }
+  }
+}
+
+enum pubCtr {
+  X(1);
+  <error descr="Modifier 'public' not allowed here">public</error> pubCtr(int i) {}
+}
+enum protCtr {
+  X(1);
+  <error descr="Modifier 'protected' not allowed here">protected</error> protCtr(int i) {}
+}
+<error descr="Modifier 'final' not allowed here">final</error> enum Fin { Y }
+<error descr="Modifier 'abstract' not allowed here">abstract</error> enum Abstr {  }
+
+enum params<error descr="Enum may not have type parameters"><T></error> {
+}
+
+enum OurEnum {
+  A, B, C;
+
+  OurEnum() {
+  }
+
+  {
+    Enum<OurEnum> a = <error descr="It is illegal to access static member 'A' from enum constructor or instance initializer">A</error>;
+    OurEnum enumValue = <error descr="It is illegal to access static member 'B' from enum constructor or instance initializer">B</error>;
+    switch (enumValue) {
+    }
+
+    switch (enumValue) {
+      case A:
+        break;
+    }
+  }
+}
+
+enum TestEnum
+{
+    A(<error descr="Illegal forward reference">B</error>), B(A);
+    TestEnum(TestEnum other) {
+      <error descr="Call to super is not allowed in enum constructor">super(null, 0)</error>;
+    }
+}
+
+<error descr="Class 'abstr' must either be declared abstract or implement abstract method 'run()' in 'Runnable'">enum abstr implements Runnable</error> {
+}
+
+//this one is OK, enum constants are checked instead of enum itself
+enum abstr1 implements Runnable {
+    A {
+        public void run() {}
+    };
+}
+
+class X extends <error descr="Classes cannot directly extend 'java.lang.Enum'">Enum</error> {
+    public X(String name, int ordinal) {
+        super(name, ordinal);
+    }
+}
+
+enum StaticInEnumConstantInitializer {
+    AN {
+        <error descr="Inner classes cannot have static declarations"><error descr="Modifier 'static' not allowed here">static</error></error> class s { }
+        private <error descr="Inner classes cannot have static declarations">static</error> final String t = String.valueOf(1);
+    };
+}
+
+interface Barz {
+    void baz();
+}
+
+enum Fooz implements Barz {
+    <error descr="Class 'Fooz' must implement abstract method 'baz()' in 'Barz'">FOO</error>;
+}
+
+///////////////////////
+class sss {
+ void f() {
+   <error descr="Enum must not be local">enum EEEE</error> { EE, YY };
+ }
+}
+
+//////////////////////
+//This code is OK
+enum PowerOfTen {
+    ONE(1),TEN(10),
+    HUNDRED(100) {
+        public String toString() {
+            return Integer.toString(super.val);
+        }
+    };
+
+    private final int val;
+
+    PowerOfTen(int val) {
+        this.val = val;
+    }
+
+    public String toString() {
+        return name().toLowerCase();
+    }
+
+    public static void main(String[] args) {
+        System.out.println(ONE + " " + TEN + " " + HUNDRED);
+    }
+}
+
+//IDEADEV-8192
+enum MyEnum {
+    X1, X2;
+
+    private static MyEnum[] values = values();
+
+    public static void test() {
+
+        for (MyEnum e : values) { // values is colored red
+            e.toString();
+        }
+    }
+}
+//end of IDEADEV-8192
+
+class EnumBugIDEADEV15333  {
+  public enum Type { one, to }
+  Type type = Type.one;
+  public void main() {
+    switch(type){
+      case one:
+      Object one = new Object();
+    }
+  }
+}
+
+class NestedEnums {
+  enum E1 { }
+
+  class C2 {
+    <error descr="Inner classes cannot have static declarations">enum E2</error> { }
+  }
+
+  static class C3 {
+    enum E3 { }
+  }
+
+  {
+    new C3() {
+      <error descr="Inner classes cannot have static declarations">enum E2</error> { }
+    };
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Enum56239.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Enum56239.java
new file mode 100644
index 0000000..28e844a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Enum56239.java
@@ -0,0 +1,34 @@
+enum IDEA56239 {
+  A, B() {
+    {
+      System.out.println(<error descr="It is illegal to access static member 'A' from enum constructor or instance initializer">A</error>);
+      System.out.println(<error descr="It is illegal to access static member 'FOO' from enum constructor or instance initializer">FOO</error>);
+      System.out.println(FOO1);
+      System.out.println(<error descr="It is illegal to access static member 'C' from enum constructor or instance initializer">C</error>);
+    }
+  }, C(<error descr="Illegal forward reference">D</error>), D;
+
+  public static String FOO = "";
+  public static final String FOO1 = "";
+
+  IDEA56239() {
+  }
+
+  IDEA56239(IDEA56239 t) {
+    System.out.println(<error descr="It is illegal to access static member 'A' from enum constructor or instance initializer">A</error>);
+    System.out.println(<error descr="It is illegal to access static member 'FOO' from enum constructor or instance initializer">FOO</error>);
+    System.out.println(FOO1);
+  }
+
+  {
+    System.out.println(<error descr="It is illegal to access static member 'A' from enum constructor or instance initializer">A</error>);
+    System.out.println(<error descr="It is illegal to access static member 'FOO' from enum constructor or instance initializer">FOO</error>);
+    System.out.println(FOO1);
+  }
+
+  void foo() {
+    System.out.println(A);
+    System.out.println(FOO);
+    System.out.println(FOO1);
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/EnumWithAbstractMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/EnumWithAbstractMethods.java
new file mode 100644
index 0000000..1abae6b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/EnumWithAbstractMethods.java
@@ -0,0 +1,24 @@
+<error descr="Modifier 'abstract' not allowed here">abstract</error> enum OurEnum {
+  <error descr="Class 'Anonymous class derived from OurEnum' must implement abstract method 'foo()' in 'OurEnum'">A</error> {
+  },
+  <error descr="'OurEnum' is abstract; cannot be instantiated">B</error>,
+  C {
+    void foo() {}
+  }
+  ;
+
+  abstract void foo();
+}
+
+enum xxx {
+  <error descr="'xxx' is abstract; cannot be instantiated">X</error>,
+  <error descr="Class 'Anonymous class derived from xxx' must implement abstract method 'f()' in 'xxx'">Y</error> {
+  };
+
+  abstract void f();
+}
+
+enum ok {
+  X { void f() {} };
+  abstract void f();
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ErasureTypeParameterBound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ErasureTypeParameterBound.java
new file mode 100644
index 0000000..ffa8897
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ErasureTypeParameterBound.java
@@ -0,0 +1,9 @@
+interface Foo<T> {
+    public <A extends T, B extends A> void bar(Class<A> key, B value);
+}
+
+class FooImpl implements Foo<String>{
+     public <A extends String,  B extends A> void bar(Class<A> key, B value) {
+
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Exceptions.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Exceptions.java
new file mode 100644
index 0000000..039cfe6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Exceptions.java
@@ -0,0 +1,23 @@
+class C <T extends Exception> {
+    void foo () throws T {}
+    void bar () {
+        <error descr="Unhandled exception: T">foo ();</error>
+    }
+
+    <T extends Error> void goo() {
+        try {
+            int i = 12;
+        } catch (<error descr="Cannot catch type parameters">T</error> ex) {
+        }
+    }
+}
+
+//IDEADEV-4169: no problem here
+interface Blub {
+    public <E extends Throwable> void Switch() throws E;
+}
+
+class Blib implements Blub {
+    public <E extends Throwable> void Switch() throws E {
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ExplicitMethodParameters.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ExplicitMethodParameters.java
new file mode 100644
index 0000000..22c3b7e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ExplicitMethodParameters.java
@@ -0,0 +1,20 @@
+import java.util.*;
+
+class Foo {
+  <T> void foo() {}
+  <T1 extends List, T2> void foo1() {}
+  void bar() {}
+  <T> void xyz(T l) {}
+
+  {
+    foo();
+    this.<String>foo();
+    this.<error descr="Wrong number of type arguments: 2; required: 1"><String, Integer></error>foo();
+    this.<String>bar();
+    this.<String, Integer>bar();
+    this.<<error descr="Type parameter 'java.lang.String' is not within its bound; should implement 'java.util.List'">String</error>, Integer>foo1();
+    this.<String>xyz<error descr="'xyz(java.lang.String)' in 'Foo' cannot be applied to '(java.lang.Integer)'">(Integer.valueOf("27"))</error>;
+    ArrayList list = new <String>ArrayList<String>();
+  }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FailedInferenceWithBoxing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FailedInferenceWithBoxing.java
new file mode 100644
index 0000000..7e690fd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FailedInferenceWithBoxing.java
@@ -0,0 +1,12 @@
+class Test {
+        public <T> T doStuff() {
+                return null;
+        }
+        public boolean test() {
+                return doStuff();
+        }
+        
+        public Boolean test1() {
+                return doStuff();
+        }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Fields.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Fields.java
new file mode 100644
index 0000000..4b9dffc
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Fields.java
@@ -0,0 +1,10 @@
+import java.util.*;
+
+class C {
+  static final List EMPTY = new ArrayList(0);
+
+  void m() {
+    List<String> list = C.<error descr="Reference parameters are not allowed here"><String></error>EMPTY;
+    System.out.println(list);
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FixedFailedInferenceWithBoxing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FixedFailedInferenceWithBoxing.java
new file mode 100644
index 0000000..7e690fd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FixedFailedInferenceWithBoxing.java
@@ -0,0 +1,12 @@
+class Test {
+        public <T> T doStuff() {
+                return null;
+        }
+        public boolean test() {
+                return doStuff();
+        }
+        
+        public Boolean test1() {
+                return doStuff();
+        }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FlattenIntersectionType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FlattenIntersectionType.java
new file mode 100644
index 0000000..7fa937d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FlattenIntersectionType.java
@@ -0,0 +1,16 @@
+interface BusinessEntity<E extends BusinessEntity<E>> {
+}
+
+interface EntityId<E extends BusinessEntity> {
+    E getEntity();
+}
+
+public class MyTest {
+    <T extends BusinessEntity<T>> T getEntity(EntityId<T> defaultValue) {
+        return getEntityID(defaultValue).getEntity();
+    }
+
+    public <P extends EntityId<?>> P getEntityID(P defaultValue) {
+        return null;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ForeachTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ForeachTypes.java
new file mode 100644
index 0000000..bd06d92
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ForeachTypes.java
@@ -0,0 +1,29 @@
+class a {
+  void f(int[] c) {
+    for (int i:c) {}
+    for (<error descr="Incompatible types. Found: 'int', required: 'char'">char i:c</error>) {}
+    for (double i:c) {}
+    double[] db = null;
+    for (<error descr="Incompatible types. Found: 'double', required: 'int'">int i:db</error>) {}
+    for (double i:db) {}
+
+    java.util.List list = null;
+    for (<error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.String'">String i:list</error>) {}
+    for (Object o:list) {}
+
+    java.util.List<Integer> ct = null;
+    for (Number n:ct) {}
+    for (Object n:ct) {}
+    for (Integer n:ct) {}
+    for (<error descr="Incompatible types. Found: 'java.lang.Integer', required: 'java.lang.String'">String i:ct</error>) {}
+    for (<error descr="Incompatible types. Found: 'java.lang.Integer', required: 'java.util.List<java.lang.Integer>'">java.util.List<Integer> i:ct</error>) {}
+
+    Object o = null;
+    for (Object oi: (Iterable)o) {}
+
+
+    for (<error descr="Incompatible types. Found: 'double', required: 'int'">int i:db</error>) {
+      for (<error descr="Incompatible types. Found: 'java.lang.Object', required: 'int'">int p: list</error>) {}
+    }
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/GenericExtendException.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/GenericExtendException.java
new file mode 100644
index 0000000..b9c5d5a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/GenericExtendException.java
@@ -0,0 +1,4 @@
+class T extends Exception {}
+class E<T> extends <error descr="Generic class may not extend 'java.lang.Throwable'">Error</error> {}
+class M<T2 extends Exception> extends <error descr="Generic class may not extend 'java.lang.Throwable'">T</error> {}
+class Ex<X,Y> extends <error descr="Generic class may not extend 'java.lang.Throwable'">Throwable</error> {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/GenericsOverrideMethodInRawInheritor.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/GenericsOverrideMethodInRawInheritor.java
new file mode 100644
index 0000000..b0a6f18
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/GenericsOverrideMethodInRawInheritor.java
@@ -0,0 +1,9 @@
+import java.util.List;
+
+<error descr="'method(List<String>)' in 'Implementation' clashes with 'method(List<String>)' in 'IfcWithGenericMethod'; both methods have same erasure, yet neither overrides the other">class Implementation implements IfcWithGenericMethod</error> {
+    public void method(final List<String> strings) {}
+}
+
+interface IfcWithGenericMethod<T> {
+    void method(List<String> strings);
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA103760.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA103760.java
new file mode 100644
index 0000000..e4d05f0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA103760.java
@@ -0,0 +1,9 @@
+import java.util.*;
+public class MyList extends ArrayList {}
+
+public class Test {
+    public void test() {
+        List<? super List> list = new ArrayList<List>();
+        list.add(new MyList());
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104100.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104100.java
new file mode 100644
index 0000000..e854f4a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104100.java
@@ -0,0 +1,7 @@
+public class TestGenericMap<A extends Comparable<A>, B extends Comparable<B>>
+{
+  public TestGenericMap<B, A> inverse()
+  {
+    return new TestGenericMap<>();
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104160.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104160.java
new file mode 100644
index 0000000..92e5b57
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104160.java
@@ -0,0 +1,13 @@
+import java.util.*;
+class Test<T> {
+  public static void foo(<error descr="'Test.this' cannot be referenced from a static context">T</error> t) {}
+  public void bar(T t) {}
+  
+  static class A extends ArrayList<<error descr="'Test.this' cannot be referenced from a static context">T</error>> {
+      static void boo(<error descr="'Test.this' cannot be referenced from a static context">T</error> t){}
+  }
+
+  class B extends ArrayList<T> {
+      void foo(T r){}
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104992.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104992.java
new file mode 100644
index 0000000..5e46842
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104992.java
@@ -0,0 +1,17 @@
+import java.util.Collection;
+import java.util.Set;
+
+class FooObject<T> {}
+class FooId<T extends FooObject> {}
+
+interface Bar {
+    <T extends FooObject, I extends FooId<? extends T>> T get(I key);
+    <T extends FooObject, I extends FooId<? extends T>> Collection<T> get(Collection<I> keys);
+}
+
+public class Target {
+    void foo(Bar bar) {
+        final Set<FooId<?>> keys = null;
+        final Collection<FooObject> values = bar.get(keys);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA105695.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA105695.java
new file mode 100644
index 0000000..8b1a962
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA105695.java
@@ -0,0 +1,10 @@
+import java.util.Map;
+
+public class Test {
+    void bar(Prop p) {
+         Map<? extends String, ? extends String> map = <error descr="Inconvertible types; cannot cast 'Prop' to 'java.util.Map<? extends java.lang.String,? extends java.lang.String>'">(Map<? extends String, ?  extends String>)p</error>;
+    }
+}
+
+abstract class Hashtble<K,V> implements Map<K,V> {}
+abstract class Prop extends Hashtble<Object, Object>{}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA105846.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA105846.java
new file mode 100644
index 0000000..04d39bd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA105846.java
@@ -0,0 +1,6 @@
+class MyClass {
+    public static void main(Class<? extends MyClass> clazz){
+        clazz = (Class<? extends MyClass>) clazz.getSuperclass();
+        <error descr="Incompatible types. Found: 'java.lang.Class<capture<? super capture<? extends MyClass>>>', required: 'java.lang.Class<? extends MyClass>'">clazz = clazz.getSuperclass()</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA106964.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA106964.java
new file mode 100644
index 0000000..5745a60
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA106964.java
@@ -0,0 +1,12 @@
+import java.io.Serializable;
+
+public abstract class Test {
+
+    abstract <T> T test(Class<T> cls);
+
+    abstract <T> T test(Serializable type);
+
+    private void call(){
+        <error descr="Incompatible types. Found: 'java.lang.String[]', required: 'java.lang.String'">String s = test(String[].class);</error>
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107440.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107440.java
new file mode 100644
index 0000000..21073ff
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107440.java
@@ -0,0 +1,18 @@
+class GoodCodeRed {
+    static class ClassA {
+    }
+
+    static class Pair<T, N> {
+    }
+
+    <T extends ClassA, M extends T, N extends Number> void max(final M object, Pair<T, N> attribute, final N cnt) {
+    }
+
+    <T extends ClassA, M extends T, N extends String> void max(final M object, Pair<T, N> attribute, final N str) {
+    }
+
+
+    {
+        max(new ClassA(), new Pair<ClassA, Integer>(), 1);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107654.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107654.java
new file mode 100644
index 0000000..7af6110
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107654.java
@@ -0,0 +1,3 @@
+class X<A extends X<A>> {
+    static class Y<B extends  Y> extends X<<error descr="Type parameter 'B' is not within its bound; should extend 'X<B>'">B</error>> {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107782.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107782.java
new file mode 100644
index 0000000..4beb3ff
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107782.java
@@ -0,0 +1,15 @@
+public class Test {
+  {
+    final MyResult hello = parseXML(new Parser());
+  }
+  public <R, P extends AbstractParser & Result<R>> R parseXML(P parser) {
+    R result = null;
+    return result;
+  }
+}
+class MyResult {}
+
+class AbstractParser {}
+interface Result<T> {}
+class Parser extends AbstractParser implements Result {}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107957.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107957.java
new file mode 100644
index 0000000..1228be1
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107957.java
@@ -0,0 +1,37 @@
+class Test1 {
+
+  private static final Foo<Boolean> test = new Foo().method(Boolean.TRUE);
+
+  public static void main(String[] args) {
+    System.out.println(test);
+  }
+
+  public static class Foo<T> {
+    public Foo<Boolean> method(boolean arg) {
+      return null;
+    }
+
+    public <T extends Enum<T>> Foo<T> method(T arg) {
+      return null;
+    }
+  }
+}
+
+class Test2 {
+
+  private static final Foo<Boolean> test = Foo.method(Boolean.TRUE);
+
+  public static void main(String[] args) {
+    System.out.println(test);
+  }
+
+  public static class Foo<T> {
+    public static Foo<Boolean> method(boolean arg) {
+      return null;
+    }
+
+    public static <T extends Enum<T>> Foo<T> method(T arg) {
+      return null;
+    }
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA108287.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA108287.java
new file mode 100644
index 0000000..e717d2d2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA108287.java
@@ -0,0 +1,9 @@
+class Foo<T> {
+    static class Nested {};
+}
+class Bar extends Foo<<error descr="Nested is not accessible in current context">Bar.Nested</error>> {}
+
+interface FooI<T> {
+    interface Nested {};
+}
+interface BarI extends FooI<<error descr="Nested is not accessible in current context">BarI.Nested</error>> {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA109556.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA109556.java
new file mode 100644
index 0000000..4701229
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA109556.java
@@ -0,0 +1,9 @@
+class Base { }
+class Extended extends Base {}
+
+class Test<T extends Base> {
+    <T extends Base, U extends T> void test(T x, Class<U> test) {}
+    {
+        test(new Extended(), Base.class);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA109875.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA109875.java
new file mode 100644
index 0000000..d799ba2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA109875.java
@@ -0,0 +1,13 @@
+import java.util.Collections;
+import java.util.Set;
+
+public class Test<Y> {
+
+    public static <K> Test<K> doTest(K k){
+        return null;
+    }
+
+    public static void main(String[] args) {
+        Test.<Set<String>>doTest(Collections.emptySet());
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110568.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110568.java
new file mode 100644
index 0000000..ed9eedd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110568.java
@@ -0,0 +1,20 @@
+import java.util.Collection;
+
+public class IncorrectError extends NarrowClass {
+    public Collection<String> bar() {
+        return super.doStuff();
+    }
+}
+
+interface Interface {
+    Collection<String> doStuff();
+}
+
+class NarrowClass extends BaseClass implements Interface {
+}
+
+class BaseClass {
+    public Collection doStuff() {
+        return null;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110869.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110869.java
new file mode 100644
index 0000000..acc0272
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110869.java
@@ -0,0 +1,12 @@
+class A {
+}
+
+abstract class B {
+  public <T extends A> T getA(Class<T> aClass) {
+    return null;
+  }
+
+  void foo(Class<?> aClass) {
+    A a = <error descr="Inferred type 'capture<?>' for type parameter 'T' is not within its bound; should extend 'A'">getA(aClass)</error>;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java
new file mode 100644
index 0000000..5f7ac80
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java
@@ -0,0 +1,17 @@
+interface Result {}
+
+interface Command<R extends Result> {}
+
+interface Procedure<C extends Command<Result>> {
+}
+
+abstract class ProcedureService {
+    abstract <C extends Command<Result>> Class<? extends Procedure<Command<Result>>> getProcedure(Class<C> cmd);
+
+    public <C extends Command<Result>> void execute(Class<? extends Command> aClass) {
+        Class<Procedure<Command<Result>>> procedureClass = getProcedure(aClass);
+        <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Command>>', required: 'java.lang.Class<Command>'">Class<Command> c = aClass;</error>
+        <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Command>>', required: 'java.lang.Class<C>'">Class<C> c1 = aClass;</error>
+    }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA111085.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA111085.java
new file mode 100644
index 0000000..e67e0d3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA111085.java
@@ -0,0 +1,20 @@
+import java.io.*;
+import java.util.List;
+
+class Main {
+    public <T> T foo(String str, Class<T> classOfT) {
+        return null;
+    }
+
+    public <T> T foo(String str, Serializable typeOfT) {
+        return null;
+    }
+
+    {
+        asList(foo("", String[].class));
+    }
+
+    public static <T> List<T> asList(T... a) {
+        return null;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA112122.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA112122.java
new file mode 100644
index 0000000..bb1e1ab
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA112122.java
@@ -0,0 +1,16 @@
+class Cast<T> implements SemElement {
+
+    {
+        final SemKey<? extends Cast> key = null;
+        final Cast semElement =    getSemElement(key);
+    }
+
+    public <T extends SemElement> T getSemElement(SemKey<T> key) {
+        return null;
+    }
+
+
+    class SemKey<T extends SemElement> {}
+}
+
+interface SemElement {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA113225.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA113225.java
new file mode 100644
index 0000000..7b4bbab
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA113225.java
@@ -0,0 +1,11 @@
+import java.io.Serializable;
+
+public class Test {
+    public <T extends Serializable> void foo(byte[] data) {
+        T foo = (T)  data;
+    }
+
+    public <T extends Serializable & Runnable> void bar(byte[] data) {
+        T bar = <error descr="Inconvertible types; cannot cast 'byte[]' to 'T'">(T)  data</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA18425.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA18425.java
new file mode 100644
index 0000000..7a496b2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA18425.java
@@ -0,0 +1,15 @@
+public abstract class BiFunction<A,B> {
+    public abstract B apply(A a);
+    public abstract A unapply(B b);
+    public BiFunction<B,A> flip() {
+        return new BiFunction<B, A>() {
+            public A apply(B b) {
+                return BiFunction.this.unapply(b);
+            }
+
+            public B unapply(A a) {
+                return BiFunction.this.apply(a);
+            }
+        };
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA20244.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA20244.java
new file mode 100644
index 0000000..ee5235a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA20244.java
@@ -0,0 +1,23 @@
+import java.util.Collection;
+class Test {
+    public static final UnaryFunction<Object, Object, RuntimeException> unaryFunction = new UnaryFunction<Object, Object, RuntimeException>() {
+        public Object execute(Object o) throws RuntimeException {
+            return null;
+        }
+    };
+
+    public static <A, B, X extends Throwable> void someMethod() {
+        transformCollection(null, unaryFunction, null);
+    }
+
+    public static <A, B, X extends Throwable> void transformCollection(Collection<? extends A> input, UnaryFunction<A, B, X> transform, Collection<? super B> output) throws X {
+        for (A a : input) {
+            B b = transform.execute(a);
+            output.add(b);
+        }
+    }
+}
+
+interface UnaryFunction<A, B, X extends Throwable> {
+    public B execute(A a) throws X;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA20573.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA20573.java
new file mode 100644
index 0000000..22bd7a3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA20573.java
@@ -0,0 +1,26 @@
+public class GoodCodeIsRed {
+
+    public void test() {
+        FileIF file = new FileImpl();
+        file.getInputStream();
+    }
+}
+
+class FileImpl implements FileIF {
+
+    public void getInputStream() {
+    }
+
+}
+
+interface FileIF extends BasicFileIF, DataSource {
+}
+
+interface BasicFileIF {
+    void getInputStream();
+}
+
+
+interface DataSource {
+    void getInputStream() throws java.io.IOException;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21597.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21597.java
new file mode 100644
index 0000000..36899243
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21597.java
@@ -0,0 +1,7 @@
+interface Foo<A> {}
+interface Bar extends Foo<Boolean> {}
+class FooFactory {
+    public <A> Foo<A> getFoo() {
+        return (Foo<A>) new Bar() {};
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21602.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21602.java
new file mode 100644
index 0000000..217e1fd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21602.java
@@ -0,0 +1,17 @@
+import java.util.Collection;
+import java.util.Collections;
+
+public class IDEABug {
+
+  static class ClassA {
+    static <T> void sayHello(Collection<? extends T> msg) {}
+  }
+
+  static class ClassB extends ClassA {
+    <error descr="'sayHello(Collection<? extends T>)' in 'IDEABug.ClassB' clashes with 'sayHello(Collection<? extends T>)' in 'IDEABug.ClassA'; both methods have same erasure, yet neither hides the other">static <T extends String> void sayHello(Collection<? extends T> msg)</error> {}
+  }
+
+  public static void main(String[] args) {
+    ClassB.sayHello(Collections.<String>emptyList());
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21602_7.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21602_7.java
new file mode 100644
index 0000000..217e1fd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21602_7.java
@@ -0,0 +1,17 @@
+import java.util.Collection;
+import java.util.Collections;
+
+public class IDEABug {
+
+  static class ClassA {
+    static <T> void sayHello(Collection<? extends T> msg) {}
+  }
+
+  static class ClassB extends ClassA {
+    <error descr="'sayHello(Collection<? extends T>)' in 'IDEABug.ClassB' clashes with 'sayHello(Collection<? extends T>)' in 'IDEABug.ClassA'; both methods have same erasure, yet neither hides the other">static <T extends String> void sayHello(Collection<? extends T> msg)</error> {}
+  }
+
+  public static void main(String[] args) {
+    ClassB.sayHello(Collections.<String>emptyList());
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA22005.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA22005.java
new file mode 100644
index 0000000..78aad3c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA22005.java
@@ -0,0 +1,13 @@
+class Test {
+    interface Foo<T> {
+        void boo(T t);
+    }
+
+    private static void f(Foo<?>... fs) {
+         fs[0].boo<error descr="'boo(capture<?>)' in 'Test.Foo' cannot be applied to '(java.lang.String)'">("hey!")</error>;
+    }
+
+    private static void f1(Foo<? extends String>... fs) {
+         fs[0].boo<error descr="'boo(capture<? extends java.lang.String>)' in 'Test.Foo' cannot be applied to '(java.lang.String)'">("hey!")</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA22079.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA22079.java
new file mode 100644
index 0000000..f3b25c9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA22079.java
@@ -0,0 +1,18 @@
+import java.util.List;
+
+public class SubClass extends BaseClass<String> {
+    public static void main(String[] args) {
+        new SubClass().method(null);
+    }
+
+    @Override
+    public void method(List list) {}
+}
+
+class BaseClass<E> implements EntityListListener<E> {
+    public void method(List list) {}
+}
+
+interface EntityListListener<E> {
+   public void method(List<E> list);
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA27080.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA27080.java
new file mode 100644
index 0000000..c5f2696
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA27080.java
@@ -0,0 +1,9 @@
+abstract class TypeToken<T> {
+    private <T> TypeToken<T> tt(Class<T> t) { return null; }
+    private <T> void checkedTestInexactSupertype(TypeToken<T> expectedSuperclass, TypeToken<? extends T> type) {}
+    TypeToken<? super Integer> ft = null;
+
+    {
+        checkedTestInexactSupertype(ft, tt(Integer.class));
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA27185.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA27185.java
new file mode 100644
index 0000000..73800a6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA27185.java
@@ -0,0 +1,13 @@
+import java.io.Serializable;
+interface A<T extends Serializable>
+{
+    <S extends T> S foo(S s);
+}
+class B implements A<Number>
+{
+    @Override
+    public <S extends Number> S foo(S s)
+    {
+        return s;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA55510.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA55510.java
new file mode 100644
index 0000000..f85901d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA55510.java
@@ -0,0 +1,22 @@
+abstract class IdeaBugTest<M extends IdeaBugTest.Mapping>
+{
+        static class Mapping {}
+}
+
+class BugTestSub extends IdeaBugTest<<error descr="SubMapping is not accessible in current context">BugTestSub.SubMapping</error>>
+{
+        public abstract static class SubMapping extends Mapping {}
+}
+
+class BugTestSub1 extends IdeaBugTest<BugTestSub1.SubMapping>
+{
+        public abstract static class SubMapping extends IdeaBugTest.Mapping {} //fqn here
+}
+
+class AbstractSettings {
+    interface State {}
+}
+interface SomeInterface<T> {}
+class Settings extends AbstractSettings implements SomeInterface<Settings.MyState> {
+    static class MyState implements State {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57259.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57259.java
new file mode 100644
index 0000000..10f9e870
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57259.java
@@ -0,0 +1,8 @@
+class A<T extends A.B> {
+    class B extends A<B> {}
+}
+
+class C<T> {
+    class D extends C<T> {}
+    <T extends C<String>.D> void foo(){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57264.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57264.java
new file mode 100644
index 0000000..485126b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57264.java
@@ -0,0 +1,17 @@
+class A1<T> {}
+class B1<T extends A1<? super A1<? super T>>>{
+    {
+        T a = null;
+        <error descr="Incompatible types. Found: 'T', required: 'A1<? super T>'">A1<? super T> b = a;</error>
+    }
+}
+
+class A<T> {}
+class B<T extends A<? super A<? super T>>> {
+
+    void bar(T x){
+        foo(x);
+    }
+    void foo(A<? super T> x){}
+    void foo(Object x){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57265.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57265.java
new file mode 100644
index 0000000..787606b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57265.java
@@ -0,0 +1,5 @@
+class A<T> {
+  class B<S> {
+    <error descr="Improper formed type; some type parameters are missing">A<T>.B</error> x;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57271.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57271.java
new file mode 100644
index 0000000..25b6c9c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57271.java
@@ -0,0 +1,9 @@
+abstract class A<S> {
+    abstract <T> T foo(T x, T y);
+
+    {
+        A<? extends A<? extends Throwable>> a = null;
+        A<? extends A<?>> b = null;
+        foo(a, b);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57272.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57272.java
new file mode 100644
index 0000000..343d667
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57272.java
@@ -0,0 +1,8 @@
+abstract class A<S> {
+    abstract <T extends A<? extends Throwable>> T foo(T y);
+
+    {
+        A<?> a = null;
+        <error descr="Inferred type 'A<capture<?>>' for type parameter 'T' is not within its bound; should extend 'A<? extends java.lang.Throwable>'">foo(a)</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57275.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57275.java
new file mode 100644
index 0000000..934d107
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57275.java
@@ -0,0 +1,13 @@
+abstract class A {
+    abstract <S, T extends Iterable<S>> void foo();
+
+    {
+        foo();
+    }
+}
+
+class X{
+    <T extends Enum<T>> void foo(){
+        foo();
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57284.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57284.java
new file mode 100644
index 0000000..a9dc4c2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57284.java
@@ -0,0 +1,6 @@
+abstract class A<S> {
+    abstract <T extends S> void foo();
+    void bar(A<? super Exception> x){
+        x.<<error descr="Type parameter 'String[]' is not within its bound; should extend 'capture<? super java.lang.Exception>'">String[]</error>>foo();
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57285.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57285.java
new file mode 100644
index 0000000..c420eb9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57285.java
@@ -0,0 +1,12 @@
+package pck;
+
+abstract class A<S> {
+    S y;
+    void bar(A<? extends int[]> x){
+        Object obj = <error descr="Array type expected; found: 'capture<? extends int[]>'">x.y</error>[0];
+    }
+
+    void baz(A<? super int[]> x){
+        Object obj = <error descr="Array type expected; found: 'capture<? super int[]>'">x.y</error>[0];
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57286.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57286.java
new file mode 100644
index 0000000..7378705
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57286.java
@@ -0,0 +1,6 @@
+class A<T> {
+    <S extends A<? extends T>> void foo(){}
+    void bar(A<?> a){
+        a.<<error descr="Type parameter 'A' is not within its bound; should extend 'A<capture<?>>'">A<?></error>>foo();
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57289.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57289.java
new file mode 100644
index 0000000..eb64128
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57289.java
@@ -0,0 +1,8 @@
+class C<T> {
+    void foo(C<C<?>> x) {
+        C<Object> c = bar(x);
+    }
+    <T> C<T> bar(C<? super C<T>> x){
+        return null;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57307.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57307.java
new file mode 100644
index 0000000..8f9ffe6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57307.java
@@ -0,0 +1,10 @@
+class C<<warning descr="Type parameter 'T' is never used">T</warning>>{}
+class A<<warning descr="Type parameter 'S' is never used">S</warning>,<warning descr="Type parameter 'T' is never used">T</warning>> {}
+class B<S,T extends C<S>> extends A<S,T> {
+    void foo(B<?,?> x){
+        bar(x);
+    }
+    <S, T> void bar(A<S,T> x){
+        System.out.println(x);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57308.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57308.java
new file mode 100644
index 0000000..154c143
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57308.java
@@ -0,0 +1,13 @@
+class A<T> {}
+
+interface IA{
+    <T> void foo(A<? extends T[]> x);
+}
+interface IB{
+    <T> int foo(A<? extends T> x);
+}
+class C {
+    <<error descr="'foo(A<? extends T>)' in 'IB' clashes with 'foo(A<? extends T[]>)' in 'IA'; both methods have same erasure, yet neither overrides the other"></error><error descr="'foo(A<? extends T>)' in 'IB' clashes with 'foo(A<? extends T[]>)' in 'IA'; both methods have same erasure, yet neither overrides the other"></error>T extends IA & IB> void bar(T x, A<String[]> y){
+        <error descr="Incompatible types. Found: 'void', required: 'int'">int z = x.foo(y);</error>
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57309.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57309.java
new file mode 100644
index 0000000..ffb4317
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57309.java
@@ -0,0 +1,9 @@
+class A<S> {
+    void bar(A<? super Exception> x, A<? super Throwable> y){
+        foo(x, y);
+    }
+
+    <T> T foo(A<? super T> x, A<? super T> y){
+        return null;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57310.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57310.java
new file mode 100644
index 0000000..41a80a8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57310.java
@@ -0,0 +1,9 @@
+class A<T> {
+    Exception[] bar(A<? super Exception[]> x, A<? super Throwable[]> y){
+        return this.foo(x, y);
+    }
+
+    <T> T foo(A<? super T> x, A<? super T> y){
+        return null;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57311.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57311.java
new file mode 100644
index 0000000..a566b5b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57311.java
@@ -0,0 +1,11 @@
+class A<T> {
+    A<A<? extends T>> foo(){
+        return null;
+    }
+
+    void bar(A<?> x){
+        baz<error descr="'baz(A<A<?>>)' in 'A' cannot be applied to '(A<A<capture<?>>>)'">(x.foo())</error>;
+    }
+
+    <S> void baz(A<A<? extends S>> x){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57312.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57312.java
new file mode 100644
index 0000000..b60c978
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57312.java
@@ -0,0 +1,11 @@
+class A<T> {
+    A<A<? super A<T>>> foo(){
+        return null;
+    }
+
+    void bar(A<?> x){
+        baz(x.foo());
+    }
+
+    <S> void baz(A<A<? super A<S>>> x){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57315.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57315.java
new file mode 100644
index 0000000..d855872
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57315.java
@@ -0,0 +1,4 @@
+class A<K>{
+    void foo(A<A<A<String>>> b){ bar(b); }
+    <U, S extends A<U>, T extends A<S>> void bar(A<T> a){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57325.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57325.java
new file mode 100644
index 0000000..b4933e8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57325.java
@@ -0,0 +1,12 @@
+interface IA<T> {
+    IA<? extends T> foo();
+}
+
+class A {
+    void baz(IA<? extends Throwable> x) {
+        bar(x.foo());
+    }
+
+    <T extends Throwable> void bar(IA<T> a) {
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57334.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57334.java
new file mode 100644
index 0000000..068f8d9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57334.java
@@ -0,0 +1,41 @@
+abstract class A<T, S> {
+    abstract <T> void foo(A<? extends T, ? extends T> x);
+    void  bar(A<? extends Throwable, ? extends Exception> x){
+        foo(x);
+    }
+}
+
+abstract class A0<T, S> {
+    abstract <T> void foo(A0<? extends T, ? extends T> x);
+    void  bar(A0<? extends Exception, ? extends Throwable> x){
+        foo(x);
+    }
+}
+
+abstract class A1<T, S> {
+    abstract <T> void foo(A1<? extends T, ? extends T> x);
+    void  bar(A1<? extends Throwable, Exception> x){
+        foo(x);
+    }
+}
+
+abstract class A10<T, S> {
+    abstract <T> void foo(A10<? extends T, ? extends T> x);
+    void  bar(A10<Throwable, Exception> x){
+        foo(x);
+    }
+}
+
+abstract class A2<T, S> {
+    abstract <T> void foo(A2<? super T, ? super T> x);
+    void  bar(A2<? super Exception, ? super Throwable> x){
+        foo(x);
+    }
+}
+
+abstract class A20<T, S> {
+    abstract <T> void foo(A20<? super T, ? super T> x);
+    void  bar(A20<? super Throwable, ? super Exception> x){
+        foo(x);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57339.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57339.java
new file mode 100644
index 0000000..01d694a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57339.java
@@ -0,0 +1,7 @@
+abstract class A {
+    abstract <T extends Iterable & Cloneable> void foo();
+}
+
+abstract class B extends A{
+    abstract <T extends Cloneable & Iterable> void foo();
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57340.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57340.java
new file mode 100644
index 0000000..7bbba7b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57340.java
@@ -0,0 +1,26 @@
+class A<T, S> {
+}
+
+class B<L> {
+    A<L, L> foo() {
+        return null;
+    }
+
+    void bar(B<?> b, A<?, ?> foo1) {
+        baz(b.foo());
+        A<?, ?> foo = b.foo();
+        baz<error descr="'baz(A<K,K>)' in 'B' cannot be applied to '(A<capture<?>,capture<?>>)'">(foo)</error>;
+        baz<error descr="'baz(A<K,K>)' in 'B' cannot be applied to '(A<capture<?>,capture<?>>)'">(foo1)</error>;
+    }
+
+    <K> void baz(A<K, K> a) {
+    }
+}
+
+
+
+class C<T,S>{}
+class D<T> extends C<T,T> {
+    void foo(D<?> x){ bar(x); }
+    <T> void bar(C<T,T> x){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57346.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57346.java
new file mode 100644
index 0000000..e4bfd47
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57346.java
@@ -0,0 +1,5 @@
+
+class D<T>  {
+    void foo(D<D<?>> x){ this.bar(x); }
+    <T extends Throwable> void bar(D<? super D<T>> x){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57378.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57378.java
new file mode 100644
index 0000000..31e47fa
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57378.java
@@ -0,0 +1,9 @@
+interface IA {
+    <T extends Cloneable & Iterable> void foo(T x);
+    <T extends Iterable & Cloneable> void foo(T x);
+}
+
+abstract class A<T extends Throwable> {
+    abstract <T extends Comparable<?> & Iterable> void foo(T x, A<?> y);
+    abstract <T extends Iterable & Comparable<?>> void foo(T x, A<? extends Throwable> y);
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57391.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57391.java
new file mode 100644
index 0000000..dfc34f8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57391.java
@@ -0,0 +1,7 @@
+abstract class B<T> {
+    abstract <S extends T> void foo(T x, S y);
+}
+
+class A extends B<String> {
+    void foo(String x, String y) {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57410.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57410.java
new file mode 100644
index 0000000..19e90a3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57410.java
@@ -0,0 +1,10 @@
+
+interface IA {
+    <T> void a(Iterable<String> x);
+}
+
+interface IB {
+    <T> void a(Iterable x);
+}
+
+<error descr="'a(Iterable)' in 'IB' clashes with 'a(Iterable<String>)' in 'IA'; both methods have same erasure, yet neither overrides the other">abstract class C implements IA, IB</error> {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57411.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57411.java
new file mode 100644
index 0000000..89aea4a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57411.java
@@ -0,0 +1,18 @@
+class A<S> {
+    <T> T foo(T x, S y){
+        return x;
+    }
+}
+
+class B<S> extends A<S> {
+    Object foo(Object x, Object y){
+        return x;
+    }
+}
+
+<error descr="'foo(T, S)' in 'A' clashes with 'foo(Object, Object)' in 'B'; both methods have same erasure, yet neither overrides the other">class C extends B<String></error> {
+    @Override
+    <T> T foo(T x, String y) {
+        <error descr="Incompatible types. Found: 'java.lang.Object', required: 'T'">return super.foo(x, y);</error>
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java
new file mode 100644
index 0000000..699a60d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java
@@ -0,0 +1,7 @@
+class A<T> {
+    <T extends A<T>> void foo(T x){}
+
+    void bar(A<?> x){
+        foo<error descr="'foo(T)' in 'A' cannot be applied to '(A<capture<?>>)'">(x)</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57439.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57439.java
new file mode 100644
index 0000000..d0063b5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57439.java
@@ -0,0 +1,43 @@
+class A<T> {}
+
+class B<T> extends A<A<T>> {
+    void bar(B<?> b, B<? extends String> eb, B<? super String> sb, B<String> s) {
+        foo(b);
+        foo(eb);
+        foo(sb);
+        foo(s);
+
+        <error descr="Inferred type 'capture<?>' for type parameter 'T' is not within its bound; should extend 'java.lang.String'">foo1(b)</error>;
+        foo1(eb);
+        <error descr="Inferred type 'capture<? super java.lang.String>' for type parameter 'T' is not within its bound; should extend 'java.lang.String'">foo1(sb)</error>;
+        foo1(s);
+
+        foo2(b);
+        foo2(eb);
+        foo2(sb);
+        foo2(s);
+    
+        foo3<error descr="'foo3(A<A<?>>)' in 'B' cannot be applied to '(B<capture<?>>)'">(b)</error>;
+        foo3<error descr="'foo3(A<A<? extends java.lang.String>>)' in 'B' cannot be applied to '(B<capture<? extends java.lang.String>>)'">(eb)</error>;
+        foo3<error descr="'foo3(A<A<?>>)' in 'B' cannot be applied to '(B<capture<? super java.lang.String>>)'">(sb)</error>;
+        foo3<error descr="'foo3(A<A<? extends java.lang.String>>)' in 'B' cannot be applied to '(B<java.lang.String>)'">(s)</error>;
+
+        foo4<error descr="'foo4(A<A<? super T>>)' in 'B' cannot be applied to '(B<capture<?>>)'">(b)</error>;
+        foo4<error descr="'foo4(A<A<? super T>>)' in 'B' cannot be applied to '(B<capture<? extends java.lang.String>>)'">(eb)</error>;
+        foo4<error descr="'foo4(A<A<? super java.lang.String>>)' in 'B' cannot be applied to '(B<capture<? super java.lang.String>>)'">(sb)</error>;
+        foo4<error descr="'foo4(A<A<? super java.lang.String>>)' in 'B' cannot be applied to '(B<java.lang.String>)'">(s)</error>;
+
+        foo5(b);
+        foo5(eb);
+        foo5(sb);
+        foo5(s);
+    }
+
+
+    <T> void foo(A<A<T>> x) {}
+    <T extends String> void foo1(A<A<T>> x) {}
+    <T> void foo2(A<? extends A<T>> x) {}
+    <T> void foo3(A<A<? extends T>> x) {}
+    <T> void foo4(A<A<? super T>> x) {}
+    <T> void foo5(A<? super A<T>> x) {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57446.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57446.java
new file mode 100644
index 0000000..9cd9f2a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57446.java
@@ -0,0 +1,7 @@
+abstract class A<T>{
+    abstract void foo(T x);
+    class B extends A<B> {
+        @Override
+        void foo(A<T>.B x) {}
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57482.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57482.java
new file mode 100644
index 0000000..0f88cf3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57482.java
@@ -0,0 +1,9 @@
+class C<T>{
+    static class D{
+        class E{
+            <error descr="'C.this' cannot be referenced from a static context">T</error> x;
+        }
+    }
+}
+
+class T{}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57484.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57484.java
new file mode 100644
index 0000000..4e2aff7
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57484.java
@@ -0,0 +1,7 @@
+abstract class C{
+    abstract <T> T foo(T x, T y);
+
+    {
+        Long s = (Long) foo(1,1L);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57485.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57485.java
new file mode 100644
index 0000000..5ab00da
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57485.java
@@ -0,0 +1,9 @@
+abstract class A{
+    abstract <S extends Number & Comparable<?>, T extends Number & Comparable<? extends S>> T foo(
+            Comparable<? extends T> x,
+            Comparable<? extends T> y);
+
+    {
+        foo(1, 1L);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57486.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57486.java
new file mode 100644
index 0000000..a3c16dd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57486.java
@@ -0,0 +1,8 @@
+class B<T,S>{}
+abstract class A<T> {
+    abstract B<T,T> foo();
+    <T> void baz(B<T,T> b){}
+    void bar(A<?> a){
+        baz(a.foo());
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57492.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57492.java
new file mode 100644
index 0000000..62d8138
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57492.java
@@ -0,0 +1,17 @@
+abstract class A<T>{
+    abstract <S> S foo(S x, S y);
+    <S extends Number & Comparable<? extends Number>> void baz(A<S> a){}
+
+    void bar(A<Long> x, A<Integer> y){
+        baz<error descr="'baz(A<S>)' in 'A' cannot be applied to '(A<capture<? extends java.lang.Number & java.lang.Comparable<? extends java.lang.Comparable<?>>>>)'">(foo(x, y))</error>;
+    }
+}
+
+abstract class A1<T>{
+    abstract <S> S foo(S x, S y);
+    <T extends Number & Comparable<?>, S extends Number & Comparable<? extends T>> void baz(A1<S> a){}
+
+    void bar(A1<Long> x, A1<Integer> y){
+        baz<error descr="'baz(A1<S>)' in 'A1' cannot be applied to '(A1<capture<? extends java.lang.Number & java.lang.Comparable<? extends java.lang.Comparable<?>>>>)'">(foo(x, y))</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57493.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57493.java
new file mode 100644
index 0000000..f344fd8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57493.java
@@ -0,0 +1,8 @@
+abstract class A<T>{
+    abstract <S> S foo(S x, S y);
+    <S extends Number & Comparable<?>> void baz(A<S> a){}
+
+    void bar(A<Long> x, A<Integer> y){
+        baz<error descr="'baz(A<S>)' in 'A' cannot be applied to '(A<capture<? extends java.lang.Number & java.lang.Comparable<? extends java.lang.Comparable<?>>>>)'">(foo(x, y))</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57494.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57494.java
new file mode 100644
index 0000000..38bafca
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57494.java
@@ -0,0 +1,16 @@
+import java.util.*;
+abstract class A {
+    abstract <T> T baz(List<? super List<? super T>> a);
+
+    void bar(List<List<?>> x){
+        String s = baz(x);
+    }
+}
+
+abstract class A1{
+    abstract <T> T baz(List<? super T> a);
+
+    void bar(List<?> x){
+        String o = baz<error descr="'baz(java.util.List<? super T>)' in 'A1' cannot be applied to '(java.util.List<capture<?>>)'">(x)</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57495.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57495.java
new file mode 100644
index 0000000..63f8c91
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57495.java
@@ -0,0 +1,9 @@
+import java.util.*;
+interface C<T> extends List<List<T>>{}
+abstract class A {
+    abstract <T> T baz(List<? super List<? super T>> a);
+
+    void bar(C<?> x){
+        baz<error descr="'baz(java.util.List<? super java.util.List<? super T>>)' in 'A' cannot be applied to '(C<capture<?>>)'">(x)</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57496.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57496.java
new file mode 100644
index 0000000..e33bb53
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57496.java
@@ -0,0 +1,11 @@
+interface I<T>{}
+interface A extends I<A[]>{}
+interface B extends I<B[]>{}
+
+abstract class c{
+    abstract <T> T baz(T x, T y);
+
+    void bar(A x, B y){
+        baz(x, y);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57509.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57509.java
new file mode 100644
index 0000000..5925159
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57509.java
@@ -0,0 +1,9 @@
+import java.util.List;
+
+abstract class X {
+    abstract <T> void copy(List<T> dest, List<? extends T> src);
+
+    void foo(List<? super Throwable> x, List<? extends Exception> y){
+        copy(x, y);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57533.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57533.java
new file mode 100644
index 0000000..5d1507f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57533.java
@@ -0,0 +1,6 @@
+class C<T extends C<? extends C<? extends T>>>{
+    void foo(C<?> x){
+        bar<error descr="'bar(C<T>)' in 'C' cannot be applied to '(C<capture<?>>)'">(x)</error>;
+    }
+    <T extends C<? extends T>> void bar(C<T> x){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57534.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57534.java
new file mode 100644
index 0000000..ea3e242
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57534.java
@@ -0,0 +1,15 @@
+abstract class C{
+    abstract <T extends Cloneable> void foo(T x);
+    abstract <T extends Object & Cloneable> void foo(T x);
+    void bar(Cloneable x){
+        foo<error descr="Ambiguous method call: both 'C.foo(Cloneable)' and 'C.foo(Cloneable)' match">(x)</error>;
+    }
+}
+
+abstract class D {
+    abstract <T extends Iterable<? extends Exception>> void foo(T x);
+    abstract <T extends Object & Iterable<? super Exception>> void foo(T x);
+    void bar(Iterable<Exception> x){
+        foo<error descr="Ambiguous method call: both 'D.foo(Iterable<Exception>)' and 'D.foo(Iterable<Exception>)' match">(x)</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57539.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57539.java
new file mode 100644
index 0000000..1969294
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57539.java
@@ -0,0 +1,13 @@
+class E<T> {
+    Class<T[]> o = <error descr="Cannot select from a type variable">T[]</error>.class;
+}
+
+class MyClass<T> {
+    Class<T[]> getTs() {
+        return <error descr="Cannot select from a type variable">T[]</error>.class;
+    }
+
+    public static void main(String[] args) {
+        new MyClass<String>().getTs();
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57557.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57557.java
new file mode 100644
index 0000000..8f482f9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57557.java
@@ -0,0 +1,7 @@
+abstract class A {
+    abstract void foo(Enum<?> x);
+}
+
+class B extends A {
+    void foo(Enum<? extends Enum<?>> x) { }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57563.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57563.java
new file mode 100644
index 0000000..1837362
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57563.java
@@ -0,0 +1,7 @@
+class C {
+    void foo(){}
+}
+
+class D extends C{
+    <error descr="'foo()' in 'D' clashes with 'foo()' in 'C'; both methods have same erasure, yet neither hides the other">static <T> void foo()</error>{}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57650.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57650.java
new file mode 100644
index 0000000..cfbc413
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57650.java
@@ -0,0 +1,7 @@
+abstract class A {
+    abstract <T> T foo();
+
+    {
+        int x = foo();
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57667.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57667.java
new file mode 100644
index 0000000..d56af09
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57667.java
@@ -0,0 +1,7 @@
+class A {
+    <T> A(T x) {}
+
+    {
+        new <<error descr="Actual type argument and inferred type contradict each other">String</error>>A(1);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57668.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57668.java
new file mode 100644
index 0000000..65efaee
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57668.java
@@ -0,0 +1,17 @@
+class A {
+    <T> A() {}
+
+    {
+        new <<error descr="Type argument cannot be of primitive type">int</error>>A();
+    }
+}
+
+class B<T> {
+    {
+        new B<<error descr="Type argument cannot be of primitive type">int</error>>();
+        B.<<error descr="Type argument cannot be of primitive type">int</error>>m();
+    }
+
+    <S> void m(){}
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57877.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57877.java
new file mode 100644
index 0000000..87c94303
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57877.java
@@ -0,0 +1,8 @@
+import java.util.*;
+
+class Test {
+  {
+    Object obj = new Object();
+    Set<Class<?>> types = Collections.singleton(obj.getClass());
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA63291.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA63291.java
new file mode 100644
index 0000000..077eb2d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA63291.java
@@ -0,0 +1,57 @@
+import java.util.Comparator;
+import java.util.Set;
+
+public class CastError {
+    public void foo(Comparator<? super byte[]> comparator) throws Exception {
+        MyComparator comparator1 = (MyComparator) comparator;
+    }
+
+    public void foo1(Comparator<byte[]> comparator) throws Exception {
+        MyComparator comparator1 = (MyComparator) comparator;
+    }
+
+    public void foo2(Comparator<? extends byte[]> comparator) throws Exception {
+        MyComparator comparator1 = (MyComparator) comparator;
+    }
+
+    public void foo3(Comparator<? super String[]> comparator) throws Exception {
+        MyComparator comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Comparator<capture<? super java.lang.String[]>>' to 'MyComparator'">(MyComparator) comparator</error>;
+    }
+
+    public void foo4(Comparator<? extends String[]> comparator) throws Exception {
+        MyComparator comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Comparator<capture<? extends java.lang.String[]>>' to 'MyComparator'">(MyComparator) comparator</error>;
+    }
+
+    public void foo5(Comparator<?> comparator) throws Exception {
+        MyComparator comparator1 = (MyComparator) comparator;
+    }
+
+    //--||--||--||--||--||--||--||--||--||--||--||--||--||--||--||--||--||--||--
+
+    public void sfoo(Set<Comparator<? super byte[]>> comparator) throws Exception {
+        Set<MyComparator> comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Set<java.util.Comparator<? super byte[]>>' to 'java.util.Set<MyComparator>'">(Set<MyComparator>) comparator</error>;
+    }
+
+    public void sfoo1(Set<Comparator<byte[]>> comparator) throws Exception {
+        Set<MyComparator> comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Set<java.util.Comparator<byte[]>>' to 'java.util.Set<MyComparator>'">(Set<MyComparator>) comparator</error>;
+    }
+
+    public void sfoo2(Set<Comparator<? extends byte[]>> comparator) throws Exception {
+        Set<MyComparator> comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Set<java.util.Comparator<? extends byte[]>>' to 'java.util.Set<MyComparator>'">(Set<MyComparator>) comparator</error>;
+    }
+
+    public void sfoo3(Set<Comparator<? super String[]>> comparator) throws Exception {
+        Set<MyComparator> comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Set<java.util.Comparator<? super java.lang.String[]>>' to 'java.util.Set<MyComparator>'">(Set<MyComparator>) comparator</error>;
+    }
+
+    public void sfoo4(Set<Comparator<? extends String[]>> comparator) throws Exception {
+        Set<MyComparator> comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Set<java.util.Comparator<? extends java.lang.String[]>>' to 'java.util.Set<MyComparator>'">(Set<MyComparator>) comparator</error>;
+    }
+
+    public void sfoo5(Set<Comparator<?>> comparator) throws Exception {
+        Set<MyComparator> comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Set<java.util.Comparator<?>>' to 'java.util.Set<MyComparator>'">(Set<MyComparator>) comparator</error>;
+    }
+}
+
+abstract class MyComparator implements Comparator<byte[]> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA65066.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA65066.java
new file mode 100644
index 0000000..3078f60
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA65066.java
@@ -0,0 +1,19 @@
+import java.util.List;
+
+class Generics {
+    public static void main( String[] args ) {
+        Outer<? extends List<? extends Nested<?>>, ?> var = OuterImpl.create(); //marked red
+    }
+
+    private static interface Outer<I, O> {
+    }
+
+    private static class OuterImpl<T> implements Outer<T, T> {
+        public static <T> OuterImpl<T> create() {
+            return new OuterImpl<T>();
+        }
+    }
+
+    private static class Nested<T> {
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA66311.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA66311.java
new file mode 100644
index 0000000..659d8fa
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA66311.java
@@ -0,0 +1,21 @@
+import java.util.*;
+
+class ErasureTest {
+  <error descr="'toArrayDouble(List<? extends Number>)' clashes with 'toArrayDouble(List<double[]>)'; both methods have same erasure">public static double[] toArrayDouble(List<? extends Number> v)</error> {
+    return null;
+  }
+
+  public static double[][] toArrayDouble(List<double[]> v) {
+    return null;
+  }
+}
+
+class ErasureTest1 {
+  <error descr="'toArrayDouble(List<? extends Number>)' clashes with 'toArrayDouble(List)'; both methods have same erasure">public static double[] toArrayDouble(List<? extends Number> v)</error> {
+    return null;
+  }
+
+  public static double[][] toArrayDouble(List v) {
+    return null;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA66311_16.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA66311_16.java
new file mode 100644
index 0000000..f95898a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA66311_16.java
@@ -0,0 +1,31 @@
+import java.util.*;
+
+class ErasureTest {
+  <error descr="'toArrayDouble(List<? extends Number>)' clashes with 'toArrayDouble(List<double[]>)'; both methods have same erasure">public static double[] toArrayDouble(List<? extends Number> v)</error> {
+    return null;
+  }
+
+  public static double[][] toArrayDouble(List<double[]> v) {
+    return null;
+  }
+}
+
+class ErasureTest1 {
+  <error descr="'toArrayDouble(List<? extends Number>)' clashes with 'toArrayDouble(List)'; both methods have same erasure">public static double[] toArrayDouble(List<? extends Number> v)</error> {
+    return null;
+  }
+
+  public static double[][] toArrayDouble(List v) {
+    return null;
+  }
+}
+
+class ErasureTest2 {
+  <error descr="'toArrayDouble(List<? extends Number>)' clashes with 'toArrayDouble(List<String>)'; both methods have same erasure">public static double[] toArrayDouble(List<? extends Number> v)</error> {
+    return null;
+  }
+
+  public static double[] toArrayDouble(List<String> v) {
+    return null;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67570.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67570.java
new file mode 100644
index 0000000..98e7c6b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67570.java
@@ -0,0 +1,21 @@
+interface A1
+{
+    String foo();
+}
+
+interface B1
+{
+    Object foo();
+}
+
+class C1<T extends B1 & A1> {
+    void bar(T x) {
+        String foo = x.foo();
+    }
+}
+
+class C2<T extends A1 & B1> {
+    void bar(T x) {
+        String foo = x.foo();
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67571.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67571.java
new file mode 100644
index 0000000..b0cd45c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67571.java
@@ -0,0 +1,17 @@
+interface A
+{
+    abstract <T> void foo();
+}
+
+interface B
+{
+    abstract <T,S> void foo();
+}
+
+class C<<error descr="'foo()' in 'B' clashes with 'foo()' in 'A'; both methods have same erasure, yet neither overrides the other"></error>T extends A & B>
+{
+    void bar(T x)
+    {
+        x.foo<error descr="Ambiguous method call: both 'A.foo()' and 'B.foo()' match">()</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67577.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67577.java
new file mode 100644
index 0000000..ff1a04f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67577.java
@@ -0,0 +1,7 @@
+class X<T>{}
+
+class A<T,S extends X<T>>  {}
+
+class C {
+    void foo(A<?, <error descr="Type parameter 'X' is not within its bound; should extend 'X<?>'">X</error>> a){  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67584.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67584.java
new file mode 100644
index 0000000..e5c5b45
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67584.java
@@ -0,0 +1,11 @@
+abstract class A
+{
+    abstract void foo();
+}
+
+interface B
+{
+    abstract void foo();
+}
+
+abstract class C extends A implements B { }
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67597.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67597.java
new file mode 100644
index 0000000..26240ad
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67597.java
@@ -0,0 +1,4 @@
+class A<T>
+{
+    T x = <error descr="Inconvertible types; cannot cast 'int' to 'T'">(T) 1</error>;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67599.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67599.java
new file mode 100644
index 0000000..67d49ac
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67599.java
@@ -0,0 +1,8 @@
+abstract class A<T, S extends T>
+{
+      abstract S bar();
+      void foo(A<Cloneable[], ? extends Throwable[]> a)
+      {
+          int x = a.bar().length;
+      }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67667.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67667.java
new file mode 100644
index 0000000..35e4ed2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67667.java
@@ -0,0 +1,8 @@
+import java.util.Collection;
+import java.util.List;
+
+interface A
+{
+    <S extends Cloneable & Comparable<?>> void foo(S x);
+    <S extends Comparable<?> & Cloneable> void foo(S x);
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67672.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67672.java
new file mode 100644
index 0000000..918e550
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67672.java
@@ -0,0 +1,7 @@
+import java.util.Collection;
+import java.util.List;
+
+interface A
+{
+    <<error descr="'add(E)' in 'java.util.List' clashes with 'add(E)' in 'java.util.Collection'; both methods have same erasure, yet neither overrides the other"></error><error descr="'add(E)' in 'java.util.List' clashes with 'add(E)' in 'java.util.Collection'; both methods have same erasure, yet neither overrides the other"></error>T extends List<?> & Collection<? extends Cloneable>> void foo(T x);
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67677.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67677.java
new file mode 100644
index 0000000..7f206bb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67677.java
@@ -0,0 +1,11 @@
+import java.util.List;
+
+interface B<T extends Cloneable> {
+    void foo(List<? super T> x);
+}
+
+class D {
+    void bar(B<?> x, List<?> y) {
+        x.foo<error descr="'foo(java.util.List<? super capture<? extends java.lang.Cloneable>>)' in 'B' cannot be applied to '(java.util.List<capture<?>>)'">(y)</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67681.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67681.java
new file mode 100644
index 0000000..b5abcb6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67681.java
@@ -0,0 +1,33 @@
+
+interface A<T> { }
+
+class B<T> implements A<T> {}
+
+class C {
+    void bar(A<A<?>> x){
+        B<A<String>> y = <error descr="Inconvertible types; cannot cast 'A<A<?>>' to 'B<A<java.lang.String>>'">(B<A<String>>) x</error>;
+    }
+}
+
+//-----------------------
+interface A2<T> { }
+
+class B2<T> implements A2<T> {}
+
+class C2 {
+    void bar(A2<A2> x){
+        B2<A2<?>> y = <error descr="Inconvertible types; cannot cast 'A2<A2>' to 'B2<A2<?>>'">(B2<A2<?>>) x</error>;
+    }
+}
+
+//-----------------------
+interface A3<T> { }
+
+class B3<T> implements A3<T> {}
+
+class C3 {
+    <T> void bar(A3<A3<T>> x){
+        A3<A3<?>> y = <error descr="Inconvertible types; cannot cast 'A3<A3<T>>' to 'A3<A3<?>>'">(A3<A3<?>>) x</error>;
+
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67682.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67682.java
new file mode 100644
index 0000000..4a48242
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67682.java
@@ -0,0 +1,15 @@
+import java.util.List;
+
+abstract class B {
+  <T> void foo(List<List<String>[]> x) {
+      Object y1 = <error descr="Inconvertible types; cannot cast 'java.util.List<java.util.List<java.lang.String>[]>' to 'java.util.List<java.util.List<T>[]>'">(List<List<T>[]>)x</error>;
+  }
+
+  <T> void foo1(List<List<List<String>>[]> x) {
+      Object y1 = <error descr="Inconvertible types; cannot cast 'java.util.List<java.util.List<java.util.List<java.lang.String>>[]>' to 'java.util.List<java.util.List<java.util.List<T>>[]>'">(List<List<List<T>>[]>)x</error>;
+  }
+
+  <T> void foo2(List<String[]> x) {
+      Object y1 = <error descr="Inconvertible types; cannot cast 'java.util.List<java.lang.String[]>' to 'java.util.List<T[]>'">(List<T[]>)x</error>;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67744.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67744.java
new file mode 100644
index 0000000..9914b1f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67744.java
@@ -0,0 +1,16 @@
+import java.util.List;
+
+abstract class B {
+    abstract <T> T[] foo(List<? super List<T>> x);
+    abstract <T> T foo0(List<? super List<T>> x);
+    abstract <T> T[] foo1(List<? extends List<T>> x);
+    abstract <T> T[] foo2(List<List<? super List<T>>> x);
+
+    void bar(List<List<?>> x, List<List<List<?>>> y){
+        foo(x)  [0] = "";
+        foo1<error descr="'foo1(java.util.List<? extends java.util.List<T>>)' in 'B' cannot be applied to '(java.util.List<java.util.List<?>>)'">(x)</error> [0] = "";
+        foo2<error descr="'foo2(java.util.List<java.util.List<? super java.util.List<java.lang.Object>>>)' in 'B' cannot be applied to '(java.util.List<java.util.List<java.util.List<?>>>)'">(y)</error> [0] = "";
+
+        String s = foo0(x);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67798.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67798.java
new file mode 100644
index 0000000..fb420fb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67798.java
@@ -0,0 +1,6 @@
+class A<T> {
+    {
+       class T extends A<T> {}
+    }
+    class T extends A<T> {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67835.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67835.java
new file mode 100644
index 0000000..ce887c6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67835.java
@@ -0,0 +1,10 @@
+import java.util.List;
+
+class B {
+    void bar(List<String> x){
+        foo(x);
+    }
+    <T> T foo(List<? super T> x){
+        return null;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67843.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67843.java
new file mode 100644
index 0000000..c459ab3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67843.java
@@ -0,0 +1,10 @@
+import java.util.List;
+
+class B{
+    public static void bar(){
+       <error descr="Inferred type 'java.util.List<java.lang.Comparable>' for type parameter 'T' is not within its bound; should implement 'java.util.List<java.lang.Comparable<java.util.List<java.lang.Comparable>>>'">foo(null)</error>.get(0).compareTo(null);
+    }
+    static <T extends List<Comparable<T>>> T foo(T x) {
+        return x;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67861.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67861.java
new file mode 100644
index 0000000..1feb516
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67861.java
@@ -0,0 +1,8 @@
+abstract class C {
+        <T> void foo(Object s){ }
+        abstract String foo(String s);
+
+    {
+        this.<String>foo("").toLowerCase();
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67865.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67865.java
new file mode 100644
index 0000000..ab7d8cf
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67865.java
@@ -0,0 +1,11 @@
+import java.util.*;
+
+abstract class A {
+    static <T> void foo(List<T> x) { }
+    static <T extends List<?>> void foo(Collection<T> x) { }
+    public static void main(String[] args){
+        List<List<String>> x = null;
+        foo<error descr="Ambiguous method call: both 'A.foo(List<List<String>>)' and 'A.foo(Collection<List<String>>)' match">(x)</error>;
+        foo<error descr="Ambiguous method call: both 'A.foo(List<Object>)' and 'A.foo(Collection<List<?>>)' match">(null)</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67998.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67998.java
new file mode 100644
index 0000000..4db4fe0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67998.java
@@ -0,0 +1,22 @@
+class TestClass {
+    public final class TestMapper<X>  {
+
+        public <U, T extends Mapping<X, U>> T mapType() {
+            SimpleMapping<X, U> mapping = new SimpleMapping<X, U>();
+            return (T) mapping;   //This is reports "Inconvertible types; cannot cast TestClass.SimpleMapping<X,U> to 'T'"
+        }
+    }
+    private final class SimpleMapping<X, U> implements Mapping<X, U> {}
+    public interface Mapping<F, U> {}
+}
+class TestClass1 {
+    public final class TestMapper<X>  {
+
+        public <U, T extends Mapping<X, U>> T mapType() {
+            Mapping<X, U> mapping = new SimpleMapping<X, U>(); //Changed type to interface
+            return (T) mapping;
+        }
+    }
+    private final class SimpleMapping<X, U> implements Mapping<X, U> {}
+    public interface Mapping<F, U> {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA70370.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA70370.java
new file mode 100644
index 0000000..a1c9331
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA70370.java
@@ -0,0 +1,13 @@
+class Devk1 {
+  public void main(String args[]) {
+    foo();
+  }
+
+  private void <warning descr="Private method 'foo(java.lang.Object...)' is never used">foo</warning>(Object... objects) {
+    System.out.println("OBJECTS" + objects);
+  }
+
+  private void foo(int... ints) {
+    System.out.println("INTS" + ints);
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA72912.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA72912.java
new file mode 100644
index 0000000..c57bbb5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA72912.java
@@ -0,0 +1,16 @@
+import java.util.*;
+
+public class Test<T>
+{
+        List<Collection<T>> getList ()
+        {
+                return new ArrayList<Collection<T>> ();
+        }
+
+        public void test1 (Test<T> arg)
+        {
+                List<Collection<T>> result = arg.getList ();
+                result.add <error descr="'add(java.util.Collection<T>)' in 'java.util.List' cannot be applied to '(java.util.HashMap<java.lang.Integer,java.lang.Integer>)'">(new HashMap<Integer, Integer> ())</error>;
+        }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA74899.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA74899.java
new file mode 100644
index 0000000..8723829
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA74899.java
@@ -0,0 +1,11 @@
+import java.util.Collections;
+import java.util.Map;
+
+public class IDEA74899 {
+    void foo() {
+        Map<String, String> m = Collections.emptyMap();
+        if (<error descr="Operator '==' cannot be applied to 'java.util.Map<java.lang.String,java.lang.String>', 'java.util.Map<java.lang.Object,java.lang.Object>'">m == Collections.emptyMap()</error>) {
+           return;
+        }
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA76283.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA76283.java
new file mode 100644
index 0000000..a221d1b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA76283.java
@@ -0,0 +1,49 @@
+import java.util.*;
+public class IDEA76283 {
+}
+
+interface Parametrized<T extends Number> {
+}
+
+class Bug1<T extends Number> {
+    <I extends Number> Parametrized<I> foo(Parametrized<I> param) {
+        return null;
+    }
+
+    void bug1(Parametrized<? super T> param) {
+        foo(param);
+    }
+
+    void bug2(Set<Parametrized<? extends Number>> parametrizeds) {
+        Set<Parametrized<?>> items = parametrizeds;
+    }
+
+    void bug3(Set<Parametrized<?>> parametrizeds) {
+        Set<Parametrized<?>> items = parametrizeds;
+    }
+
+    void bug4(Set<Parametrized<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>>> parametrizeds) {
+        <error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? extends java.lang.String>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
+    }
+
+    void bug5(Set<Parametrized<? extends Integer>> parametrizeds) {
+        <error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? extends java.lang.Integer>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
+    }
+
+    void bug6(Set<Parametrized<? super Number>> parametrizeds) {
+        <error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? super java.lang.Number>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
+    }
+
+    void bug7(Set<Parametrized<? super Integer>> parametrizeds) {
+        <error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? super java.lang.Integer>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
+    }
+
+    void bug8(Set<Parametrized<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>>> parametrizeds) {
+        <error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? super java.lang.String>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
+    }
+
+    void bug9(Set<Parametrized<<error descr="Type parameter '? super Object' is not within its bound; should extend 'java.lang.Number'">? super Object</error>>> parametrizeds) {
+        <error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? super java.lang.Object>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
+    }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA77128.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA77128.java
new file mode 100644
index 0000000..cc889ab
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA77128.java
@@ -0,0 +1,11 @@
+import java.util.*;
+class A {
+    public static void main(String[] args) {
+        List<String> strings = new ArrayList<>();
+
+        List<? super Integer> list = new ArrayList<>();
+        list.addAll<error descr="'addAll(java.util.Collection<? extends capture<? super java.lang.Integer>>)' in 'java.util.List' cannot be applied to '(java.util.List<java.lang.String>)'">(strings)</error>;
+
+        System.out.println(list.toString());
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA77991.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA77991.java
new file mode 100644
index 0000000..688806bc
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA77991.java
@@ -0,0 +1,26 @@
+class Test {
+    static {
+        Class<Test> testClass = get(Test.class);
+        foo(testClass);
+        Test f = foo(testClass);
+    }
+
+    static <E> Class<E> get(Class<? super E> value) {
+        return null;
+    }
+
+    static <E> E foo(Class<? super E> value) {
+        return null;
+    }
+}
+
+class Comp {
+  public static <T> boolean equal(T arg1, T arg2) {
+    return false;
+  }
+
+  void foo(String s, Object o) {
+    if (equal(s, o)) {
+    }
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA80386.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA80386.java
new file mode 100644
index 0000000..3587f4f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA80386.java
@@ -0,0 +1,33 @@
+import java.util.List;
+
+public class IDEA80386 {
+  void foo(Class<List> listClass) {
+    <error descr="Incompatible types. Found: 'java.lang.Class<java.util.List>', required: 'java.lang.Class<? extends java.util.List<?>>'">Class<? extends List<?>> cls = listClass;</error>
+    Class < ?extends List > cls1 = listClass;
+    <error descr="Incompatible types. Found: 'java.lang.Class<java.util.List>', required: 'java.lang.Class<? extends java.util.List<? extends java.util.List<?>>>'">Class<? extends List<? extends List<?>>> cls2 = listClass;</error>
+    Class<? super List<?>> clsS = listClass;
+    Class<? super List> clsS1 = listClass;
+  }
+
+  void fooE(Class<? extends List> listClass) {
+    <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends java.util.List>>', required: 'java.lang.Class<? extends java.util.List<?>>'">Class<? extends List<?>> cls = listClass;</error>
+    Class<? extends List> cls1 = listClass;
+    <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends java.util.List>>', required: 'java.lang.Class<? extends java.util.List<? extends java.util.List<?>>>'">Class<? extends List<? extends List<?>>> cls2 = listClass;</error>
+    <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends java.util.List>>', required: 'java.lang.Class<? super java.util.List<?>>'">Class<? super List<?>> clsS = listClass;</error>
+    <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends java.util.List>>', required: 'java.lang.Class<? super java.util.List>'">Class<? super List> clsS1 = listClass;</error>
+  }
+
+  void fooS(Class<? super List> listClass) {
+    <error descr="Incompatible types. Found: 'java.lang.Class<capture<? super java.util.List>>', required: 'java.lang.Class<? extends java.util.List<?>>'">Class<? extends List<?>> cls1 = listClass;</error>
+    <error descr="Incompatible types. Found: 'java.lang.Class<capture<? super java.util.List>>', required: 'java.lang.Class<? extends java.util.List<? extends java.util.List<?>>>'">Class<? extends List<? extends List<?>>> cls2 = listClass;</error>
+    Class<? super List<?>> clsS = listClass;
+    Class<? super List> clsS1 = listClass;
+  }
+
+  void fooU(Class<?> listClass) {
+    <error descr="Incompatible types. Found: 'java.lang.Class<capture<?>>', required: 'java.lang.Class<? extends java.util.List<?>>'">Class<? extends List<?>> cls1 = listClass;</error>
+    <error descr="Incompatible types. Found: 'java.lang.Class<capture<?>>', required: 'java.lang.Class<? extends java.util.List<? extends java.util.List<?>>>'">Class<? extends List<? extends List<?>>> cls2 = listClass;</error>
+    <error descr="Incompatible types. Found: 'java.lang.Class<capture<?>>', required: 'java.lang.Class<? super java.util.List<?>>'">Class<? super List<?>> clsS = listClass;</error>
+    <error descr="Incompatible types. Found: 'java.lang.Class<capture<?>>', required: 'java.lang.Class<? super java.util.List>'">Class<? super List> clsS1 = listClass;</error>
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA86875.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA86875.java
new file mode 100644
index 0000000..c5a65df
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA86875.java
@@ -0,0 +1,11 @@
+interface Base<E> {}
+interface Base2<E> {}
+
+class A<E extends Cloneable> {
+  <P, K extends Base<E>&Base2<P>> void m(K k, P p) {
+    E e = null;
+    m(k, e);
+  }
+
+  void m(Base<E> k, E e) {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA87860.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA87860.java
new file mode 100644
index 0000000..540ec4e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA87860.java
@@ -0,0 +1,11 @@
+interface A {
+    <T extends Exception> void foo() throws T;
+    <T extends Exception> void bar() throws Exception;
+    void baz() throws Exception;
+}
+
+interface B<T extends Throwable> extends A {
+    void foo() throws <error descr="'foo()' in 'B' clashes with 'foo()' in 'A'; overridden method does not throw 'T'">T</error>;
+    void bar() throws <error descr="'bar()' in 'B' clashes with 'bar()' in 'A'; overridden method does not throw 'java.lang.Throwable'">Throwable</error>;
+    void baz() throws <error descr="'baz()' in 'B' clashes with 'baz()' in 'A'; overridden method does not throw 'java.lang.Throwable'">Throwable</error>;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA88895.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA88895.java
new file mode 100644
index 0000000..cf59c1d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA88895.java
@@ -0,0 +1,26 @@
+import java.util.Iterator;
+
+public class WildcardGenericAndPrivateField {
+
+    private Object field;
+
+    public Iterator<? extends WildcardGenericAndPrivateField> iterator() {
+        return null;
+    }
+
+    public void methodDoesNotCompile() {
+        Iterator<? extends WildcardGenericAndPrivateField> iterator = iterator();
+        while ( iterator.hasNext() ) {
+            Object o = iterator.next().<error descr="'field' has private access in 'WildcardGenericAndPrivateField'">field</error>;
+        }
+    }
+
+    public void methodCompiles() {
+        Iterator<? extends WildcardGenericAndPrivateField> iterator = iterator();
+        while ( iterator.hasNext() ) {
+            WildcardGenericAndPrivateField next = iterator.next();
+            Object o = next.field;
+        }
+    }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA89771.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA89771.java
new file mode 100644
index 0000000..f3a04de
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA89771.java
@@ -0,0 +1,3 @@
+public @interface MyAnnotation {
+    Class<? extends Enum<?>> enumClass() default <error descr="Incompatible types. Found: 'java.lang.Class<java.lang.Enum>', required: 'java.lang.Class<? extends java.lang.Enum<?>>'">Enum.class</error>;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA89801.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA89801.java
new file mode 100644
index 0000000..aa8ba27
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA89801.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+  {
+    Map<Number, String> map1 = null;
+    Map<Integer, String> map2 = <error descr="Inconvertible types; cannot cast 'java.util.Map<java.lang.Number,java.lang.String>' to 'java.util.Map<java.lang.Integer,java.lang.String>'">(Map<Integer, String>) map1</error>;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA90802.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA90802.java
new file mode 100644
index 0000000..c679ed8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA90802.java
@@ -0,0 +1,24 @@
+import java.util.*;
+
+interface VcsRoot {
+}
+
+interface SVcsRoot extends VcsRoot {
+}
+
+interface A {
+    List<? extends VcsRoot> getVcsRoots();
+}
+
+interface B {
+    List<SVcsRoot> getVcsRoots();
+}
+
+interface F1 extends A, B {
+}
+
+class G {
+    void f(F1 o) {
+        SVcsRoot r = o.getVcsRoots().get(0);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA91626.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA91626.java
new file mode 100644
index 0000000..ff29729
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA91626.java
@@ -0,0 +1,25 @@
+class Test {
+    interface A<T> {
+        void _(T... t);
+    }
+
+    static void foo(final A<?> bar) {
+        bar._("");
+    }
+    static void foo1(final A<? extends String> bar) {
+        bar._("");
+    }
+
+    static void foo2(final A<? extends Integer> bar) {
+        bar._<error descr="'_(capture<? extends java.lang.Integer>...)' in 'Test.A' cannot be applied to '(java.lang.String)'">("")</error>;
+    }
+
+
+    public static void main(String[] args) {
+        foo(new A<Integer>() {
+            public void _(final Integer... t) {
+
+            }
+        });
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA92022.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA92022.java
new file mode 100644
index 0000000..d8d49f9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA92022.java
@@ -0,0 +1,23 @@
+class GetClassClient {
+        public void use() {
+                Class<? extends LocalGeneric> v1 = null;
+                Class<? extends LocalGeneric<Object>> v2 = null;
+                v1 = v2;
+              <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends GetClassClient.LocalGeneric>>', required: 'java.lang.Class<? extends GetClassClient.LocalGeneric<java.lang.Object>>'">v2 = v1</error>;
+        }
+
+        public static class LocalGeneric<T> {
+        }
+}
+
+
+interface Comparable<T extends Comparable<T>> {}
+class List<T> {}
+
+class Foo implements Comparable<Foo> {
+  public static void main(String[] args){
+    List<? extends Foo> list = null;
+    List<? extends Comparable> c = null;
+    c = list;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA94011.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA94011.java
new file mode 100644
index 0000000..6d5cdfa
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA94011.java
@@ -0,0 +1,21 @@
+import java.util.*;
+class Test {
+
+    class Parent { }
+
+    interface Consumer<T> { }
+
+    interface MyConsumer<T extends Parent> extends Consumer<T> { }
+
+
+    public void test(Set<MyConsumer> set) {
+        @SuppressWarnings("unchecked")
+        Map<Parent, MyConsumer<Parent>> map = create<error descr="'create(java.util.Set<T>)' in 'Test' cannot be applied to '(java.util.Set<Test.MyConsumer>)'">(set)</error>;
+
+    }
+
+    public <S, T extends Consumer<S>> Map<S, T> create(Set<T> consumers) {
+        return null;
+    }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA97276.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA97276.java
new file mode 100644
index 0000000..625d706
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA97276.java
@@ -0,0 +1,17 @@
+interface Interf<X extends Interf> {}
+class SomeClass {
+    static <I extends Interf<? super I>> Class<I> someMethod(I i) { return null; }
+}
+
+interface OtherInterf<I1 extends Interf, I2 extends Interf> {}
+interface ImmutableSet<S> {}
+
+class SomeOtherClass {
+  static ImmutableSet<Class<? extends OtherInterf<?, ?>>> someOtherMethod() {
+    return <error descr="Inconvertible types; cannot cast 'ImmutableSet<java.lang.Class<? extends OtherInterf>>' to 'ImmutableSet<java.lang.Class<? extends OtherInterf<?,?>>>'">(ImmutableSet<Class<? extends OtherInterf<?, ?>>>)aux(OtherInterf.class)</error>;
+  }
+
+  static <T> ImmutableSet<Class<? extends T>> aux(Class<T> t) {
+    return null;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA97888.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA97888.java
new file mode 100644
index 0000000..93e1217
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA97888.java
@@ -0,0 +1,23 @@
+import java.util.*;
+import java.io.File;
+class Foo {
+    public Collection<BuildTarget<?>> getDependencies(LayoutElementBuilderService builder, JpsPackagingElement element, TargetOutputIndex outputIndex) {
+        return builder.getDependencies(element, outputIndex);
+    }
+}
+
+class BuildTarget<R extends BuildRootDescriptor> {}
+
+interface TargetOutputIndex {
+    Collection<BuildTarget<?>> getTargetsByOutputFile(File file);
+}
+
+class BuildRootDescriptor {}
+
+class LayoutElementBuilderService<E extends JpsPackagingElement> {
+    public Collection<? extends BuildTarget<?>> getDependencies(E element, TargetOutputIndex outputIndex) {
+        return Collections.emptyList();
+    }
+}
+
+class JpsPackagingElement {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA98421.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA98421.java
new file mode 100644
index 0000000..28ac86b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA98421.java
@@ -0,0 +1,11 @@
+class Outer {
+  class Inner {
+    public <T> Inner(T t) { }
+  }
+
+  class Other extends Outer.Inner {
+    public Other() {
+      new Outer().<Object>super("Hi");
+    }
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA99061.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA99061.java
new file mode 100644
index 0000000..11afc6c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA99061.java
@@ -0,0 +1,11 @@
+class Test {
+    {
+        String a = cast("str");
+        Integer[] b = cast(new Integer[0]);
+        Object[] c = cast(new Object[0]);
+    }
+
+    private <T> T cast(Object obj) {
+        return (T)obj;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA99347.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA99347.java
new file mode 100644
index 0000000..9c49224
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA99347.java
@@ -0,0 +1,12 @@
+interface Errors {
+  java.util.Collection<java.lang.String> getErrorMessages();
+
+}
+
+class Test extends AbstrClass implements Errors {
+}
+
+
+abstract class AbstrClass {
+  public java.util.Collection getErrorMessages() {return null;}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV10459.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV10459.java
new file mode 100644
index 0000000..f3185c8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV10459.java
@@ -0,0 +1,31 @@
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/** @noinspection UnusedDeclaration*/
+public class GenericsTest98 {
+    public static void main(String[] args) throws Exception{
+        List<Movable<? extends Serializable>> list = new ArrayList<Movable<? extends Serializable>> ();
+        Factory factory = Factory.newInstance();
+        // Doesn't compile, but Idea doesn't complain
+        Mover<? extends Serializable> mover  = factory.getNew<error descr="'getNew(java.util.List<? extends Movable<T>>)' in 'Factory' cannot be applied to '(java.util.List<Movable<? extends java.io.Serializable>>)'">(list)</error>;
+    }
+}
+
+abstract class Factory {
+    public static Factory newInstance(){
+        return null;
+    }
+
+    // This should actually be
+    // public abstract <T extends Serializable> Mover<T> getNew (List<? extends Movable<? extends T>> source);
+    public abstract <T extends Serializable> Mover<T> getNew (List<? extends Movable<T>> source);
+}
+
+/** @noinspection UnusedDeclaration*/
+interface Movable<T extends Serializable> extends Serializable {
+}
+
+/** @noinspection UnusedDeclaration*/
+interface Mover<T extends Serializable> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV12951.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV12951.java
new file mode 100644
index 0000000..03cd4b6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV12951.java
@@ -0,0 +1,29 @@
+class ClassExt {
+
+    /** @noinspection UnusedDeclaration*/
+    public static <T, P1, P2> T newInstance(Class<T> clazz,
+                                            Class<? super P1> t1, P1 p1,
+                                            Class<? super P2> t2, P2 p2) {
+        return null;
+    }
+
+
+}
+
+abstract class TKey<T> {
+
+    protected abstract Class<T> getType();
+}
+
+
+class GoodIsRed6 {
+
+
+    public static <TK extends TKey<?>> TK createClone(TK tkey, String key) {
+
+
+        Class<TK> clazz = null;
+
+        return ClassExt.newInstance(clazz, String.class, key, Class.class, tkey.getType());
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV13011.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV13011.java
new file mode 100644
index 0000000..77b1de4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV13011.java
@@ -0,0 +1,29 @@
+/** @noinspection UnusedDeclaration*/
+class LimitedPool<T> {
+  private int capacity;
+  private final ObjectFactory<T> factory;
+  private Object[] storage;
+  private int index = 0;
+
+  public LimitedPool(final int capacity, ObjectFactory<T> factory) {
+    this.capacity = capacity;
+    this.factory = factory;
+    storage = new Object[capacity];
+  }
+
+  interface ObjectFactory<T> {
+    T create();
+    void cleanup(T t);
+  }
+
+  public T alloc() {
+    if (index >= capacity) return factory.create();
+
+    if (storage[index] == null) {
+      storage[index] = factory.create();
+    }
+
+    <error descr="Incompatible types. Found: 'java.lang.Object[]', required: 'T'">return storage;</error>
+  }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV14006.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV14006.java
new file mode 100644
index 0000000..77cf1db
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV14006.java
@@ -0,0 +1,18 @@
+/** @noinspection UnusedDeclaration*/
+interface TestIF2<T> extends TestIF3<T> {}
+
+/** @noinspection UnusedDeclaration*/
+interface TestIF<T extends TestIF2<? extends Test2>> {
+    void run(T o1);
+}
+
+/** @noinspection UnusedDeclaration*/
+interface TestIF3<T> {}
+
+class Test2 {}
+
+class Test {
+    public void test(TestIF<?> testIF) {
+        testIF.run<error descr="'run(capture<? extends TestIF2<? extends Test2>>)' in 'TestIF' cannot be applied to '()'">()</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV14103.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV14103.java
new file mode 100644
index 0000000..77e6bb0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV14103.java
@@ -0,0 +1,52 @@
+class TestGenerics {
+
+    static interface EnumInterface {
+        public String getSomething();
+    }
+
+    static enum Enum1 implements EnumInterface {
+        A("alpha"),
+        B("beta"),
+        G("gamme"),
+        ;
+        private String text;
+
+        Enum1(String text) {
+            this.text = text;
+        }
+
+        public String getSomething() {
+            return text;
+        }
+    }
+
+    static class TestBase<I extends Enum<I> & EnumInterface> {
+
+        protected final void add(Eval eval) {
+            eval.hashCode();
+        }
+
+        abstract class Eval {
+            private I enumI;
+
+            public Eval(I enumI) {
+                this.enumI = enumI;
+            }
+
+            public final void doSomething() {
+                System.out.println(enumI.getSomething());
+            }
+        }
+
+    }
+
+
+
+
+    class Test1 extends TestBase<Enum1> {
+
+        public Test1() {
+            add(new Eval(Enum1.A) {});
+        }
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV15534.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV15534.java
new file mode 100644
index 0000000..774a2ef
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV15534.java
@@ -0,0 +1,29 @@
+import java.util.ArrayList;
+import java.util.Collections;
+
+class SortTest<R extends Comparable<R>> implements Comparable<SortTest<R>> {
+    R r;
+
+    public SortTest(R r) {
+        this.r = r;
+    }
+
+    public int compareTo(SortTest<R> o) {
+        return r.compareTo(o.r);
+    }
+
+    public static void main(String[] args) {
+        ArrayList<SortTest<?>> list = new ArrayList<SortTest<?>>();
+        SortTest<?> t1 = new SortTest<String>("");
+        list.add(t1);
+        SortTest<?> t2 = new SortTest<Integer>(0);
+        list.add(t2);
+        <error descr="Inferred type 'SortTest<?>' for type parameter 'T' is not within its bound; should implement 'java.lang.Comparable<? super SortTest<?>>'">Collections.sort(list)</error>;
+        t1.compareTo<error descr="'compareTo(SortTest<capture<? extends java.lang.Comparable<capture<?>>>>)' in 'SortTest' cannot be applied to '(SortTest<capture<?>>)'">(t2)</error>;
+
+        //this should be OK
+        SortTest<?>[] arr = new SortTest<?>[0];
+        arr[0] = new SortTest<String>("");
+    }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV23157.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV23157.java
new file mode 100644
index 0000000..eef2542
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV23157.java
@@ -0,0 +1,10 @@
+import java.util.List;
+import java.util.Arrays;
+
+public class ZZZ {
+
+    List<Class<?>> f(Class<?>[] exceptionTypes) {
+       List<Class<?>> nd = Arrays.asList(exceptionTypes);
+       return nd;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV24166.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV24166.java
new file mode 100644
index 0000000..c1952d1
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV24166.java
@@ -0,0 +1,49 @@
+import java.util.*;
+
+interface TypesafeMap<BASE> {
+
+  @SuppressWarnings({"UnusedDeclaration"})
+  public interface Key<BASE,VALUE> { }
+
+  public <VALUE, KEY extends Key<BASE,VALUE>>
+    boolean has(Class<KEY> key);
+
+  public <VALUE, KEY extends Key<BASE,VALUE>>
+    VALUE get(Class<KEY> key);
+
+  public <VALUEBASE, VALUE extends VALUEBASE, KEY extends Key<BASE,VALUEBASE>>
+    VALUE set(Class<KEY> key, VALUE value);
+
+  public <VALUE, KEY extends Key<BASE,VALUE>>
+    VALUE remove(Class<KEY> key);
+
+  public Set<Class<?>> keySet();
+
+  public <VALUE, KEY extends Key<CoreMap, VALUE>>
+    boolean containsKey(Class<KEY> key);
+}
+
+
+interface CoreMap extends TypesafeMap<CoreMap> { }
+
+interface CoreAnnotation<V>
+  extends TypesafeMap.Key<CoreMap, V> {
+
+  public Class<V> getType();
+}
+
+
+class CoreMaps {
+
+  public static <K,V> Map<K,V> toMap(Collection<CoreMap> coremaps,
+      Class<CoreAnnotation<K>> keyKey, Class<CoreAnnotation<V>> valueKey) {
+
+    Map<K,V> map = new HashMap<K,V>();
+    for (CoreMap cm : coremaps) {
+      map.put(cm.get(keyKey), cm.get(valueKey));
+    }
+
+    return map;
+  }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV57343.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV57343.java
new file mode 100644
index 0000000..fb7e477
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV57343.java
@@ -0,0 +1,6 @@
+class D<T>  {
+    void foo(D<?> x){
+        bar<error descr="'bar(D<? extends T>, D<? super T>)' in 'D' cannot be applied to '(D<capture<?>>, D<capture<?>>)'">(x,x)</error>;
+    }
+    <T> void bar(D<? extends T> x, D<? super T> y){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV7337.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV7337.java
new file mode 100644
index 0000000..bc89597
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV7337.java
@@ -0,0 +1,74 @@
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Comparator;
+
+
+class TestIDEA
+{
+
+  public static class Test1<Type extends List & Serializable>
+  {
+    public void process(Serializable s)
+    {
+    }
+    public void process(Type t)
+    {
+    }
+  }
+
+  public static class Test2 extends Test1<ArrayList>
+  {
+    public void process(Serializable s)
+    {
+      super.process(s);
+    }
+
+    public void process(ArrayList t)
+    {
+      super.process(t);   // this call is OK resolving to parameterized method in super
+    }
+  }
+
+  public static void main(String[] args)
+  {
+    Test2 test=new Test2();
+    ArrayList list=new ArrayList();
+    test.process(list);
+    test.process((Serializable)list);
+  }
+}
+
+class Key<T> {
+    Object add(T v) {
+        return v;
+    }
+}
+
+class WKey<W, T> extends Key<T> {
+
+    W add(T v) {
+        return null;
+    }
+}
+
+class IBug {
+
+    public static <W, T> void addItem(WKey<W, T> key, T v) {
+        key.add(v); // --> demetra draw this in red, see attachment
+    }
+}
+
+//IDEADEV-7698
+abstract class Collator implements Comparator<Object> {
+  public abstract int compare(String source, String target);
+
+  public int compare(Object o1, Object o2) {
+    return compare((String)o1, (String)o2);
+  }
+
+  public void foo(Collator c) {
+    c.compare("foo", "bar");
+  }
+}
+//end of //IDEADEV-7698
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IllegalForwardReferenceInTypeParameterDefinition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IllegalForwardReferenceInTypeParameterDefinition.java
new file mode 100644
index 0000000..31cdb61
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IllegalForwardReferenceInTypeParameterDefinition.java
@@ -0,0 +1,2 @@
+class A<T extends S, S> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IllegalGenericTypeInInstanceof.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IllegalGenericTypeInInstanceof.java
new file mode 100644
index 0000000..52871e8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IllegalGenericTypeInInstanceof.java
@@ -0,0 +1,53 @@
+class A<T> {
+  public void foo(Object object) {
+    if (object instanceof <error descr="Illegal generic type for instanceof">B</error>) {}
+    if (object instanceof A.B) {}
+    if (object instanceof A<?>.B) {}
+    if (object instanceof A<?>) {}
+    if (object instanceof <error descr="Illegal generic type for instanceof">A<String></error>) {}
+    if (object instanceof A) {}
+    if (object instanceof A[]) {}
+    if (object instanceof <error descr="Illegal generic type for instanceof">B[]</error>) {}
+    if (object instanceof A.B[]) {}
+  }
+
+  private class B {
+  }
+}
+
+class A1 {
+  public void foo(Object object) {
+    if (object instanceof B1) {}
+    if (object instanceof A1.B1) {}
+    if (object instanceof B1[]) {}
+  }
+
+  private class B1 {
+  }
+}
+
+class BreakpointTree<TP> {
+    void foo(Node node) {
+        if (node instanceof BNode<?>) {
+
+        }
+    }
+
+    static class BNode<B extends XBreakpoint<?>> extends Node{}
+}
+class Node {}
+class XBreakpoint<SR>{}
+
+public class GenericInnerClass<E> {
+    private void problem( Base base ) {
+        if ( base instanceof First) {}
+    }
+
+    private class Base {
+    }
+
+    private class First<T> extends Base {
+    }
+
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ImplementAnnotation.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ImplementAnnotation.java
new file mode 100644
index 0000000..bbe1e30
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ImplementAnnotation.java
@@ -0,0 +1,15 @@
+import java.lang.annotation.Annotation;
+
+public @interface Foo {
+    String id();
+}
+
+class Bar implements Foo {
+    public String id() {
+        return null;
+    }
+
+    public Class<? extends Annotation> annotationType() {
+        return null;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InaccessibleThroughWildcard.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InaccessibleThroughWildcard.java
new file mode 100644
index 0000000..cc64719
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InaccessibleThroughWildcard.java
@@ -0,0 +1,13 @@
+class JavacConfiguration {
+  private final String mySettings = "";
+
+  public static void foo(Class<? extends JavacConfiguration> aClass) {
+    Object o = getService(aClass).<error descr="'mySettings' has private access in 'JavacConfiguration'">mySettings</error>;
+    JavacConfiguration configuration = getService(aClass);
+    String string = configuration.mySettings;
+  }
+
+    public static <T> T getService(Class<T> serviceClass) {
+       return null;
+     }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IncompatibleReturnType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IncompatibleReturnType.java
new file mode 100644
index 0000000..3a8d3b0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IncompatibleReturnType.java
@@ -0,0 +1,20 @@
+abstract class F<A, B> {
+  public abstract B f(A a);
+
+  public final F<A, P1<B>> lazy() {
+    return new F<A, P1<B>>() {
+      public P1<B> f(final A a) {
+        return null;
+      }
+    };
+  }
+
+  private class TestClient<A, B> extends F<A, P1<B>> {
+    public P1<B> f(final A a) {
+      return null;
+    }
+  }
+}
+
+class P1<T> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InconvertibleTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InconvertibleTypes.java
new file mode 100644
index 0000000..752453e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InconvertibleTypes.java
@@ -0,0 +1,8 @@
+import java.util.*;
+
+class Test {
+  void foo(){
+    Properties properties = System.getProperties();
+    final Map<String, String> systemProperties = <error descr="Inconvertible types; cannot cast 'java.util.Properties' to 'java.util.Map<java.lang.String,java.lang.String>'">(Map<String, String>) properties</error>;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithBounds.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithBounds.java
new file mode 100644
index 0000000..626821e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithBounds.java
@@ -0,0 +1,61 @@
+import java.util.*;
+
+class CLS {
+    static <V extends String>  void bar (V v) {}
+
+    static void foo () {
+        <error descr="Inferred type 'java.lang.Object' for type parameter 'V' is not within its bound; should extend 'java.lang.String'">bar(new Object())</error>;
+    }
+}
+//////////////////////////////
+public abstract class ZZZ<K> {
+  public abstract <T extends String> ZZZ<T> get();
+}
+class Z2<K> extends ZZZ<K> {
+    public <T extends String> Z2<T> get() {
+        return null;
+    }
+    void f() {
+        Z2 z2 = get();
+    }
+}
+/////////////////
+abstract class LeastRecentlyUsedCache {
+interface Callable<V> {
+    V call() throws Exception;
+}
+
+    <E extends A> Callable<E> e(E e) {
+        return null;
+    }
+    <T extends B> Callable<T> f(boolean b, final T t) {
+        return b ? e(t) : new Callable<T>() {
+            public T call() throws Exception {
+                return t;
+            }
+        };
+    }
+
+    void ff() {
+
+    }
+
+    class A {}
+    class B extends A {}
+}
+//////////////////////////
+public class BadCodeGreen<T, C extends Collection<? extends T>> {
+    public BadCodeGreen(C c, T t) {
+        c.add<error descr="'add(capture<? extends T>)' in 'java.util.Collection' cannot be applied to '(T)'">(t)</error>;
+    }
+}
+////////////////////////////
+abstract class A {
+    public abstract <T extends List<?>> T create();
+}
+class B extends A {
+    public <T extends List<?>> T create() {
+        return null;
+    }
+}
+///////////////////////////
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithBoxingCovariant.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithBoxingCovariant.java
new file mode 100644
index 0000000..453f82b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithBoxingCovariant.java
@@ -0,0 +1,16 @@
+import java.util.*;
+
+class Test {
+  static class Pair<A, B> {
+    Pair(A a, B b) {
+    }
+
+    static <A, B> Pair<A, B> create(A a, B b) {
+      return new Pair<A, B>(a, b);
+    }
+  }
+
+  public static void getWordsWithOffset(String s, int startInd, final List<Pair<String, Integer>> res) {
+    res.add(Pair.create(s, startInd));
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithSuperBounds.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithSuperBounds.java
new file mode 100644
index 0000000..d68f907
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithSuperBounds.java
@@ -0,0 +1,16 @@
+public class ExampleProblem {
+    <T> void asserting(T t, Simple<T> l){
+    }
+
+    <K> Simple<? super K> comp(K k){
+        return null;
+    }
+
+    public void main(String[] args) {
+        asserting(0, comp(0));
+    }
+}
+
+class Simple<SST>{
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithUpperBoundPromotion.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithUpperBoundPromotion.java
new file mode 100644
index 0000000..8b2aabe
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithUpperBoundPromotion.java
@@ -0,0 +1,30 @@
+
+public class NestedGenericGoodCodeIsRed {
+
+    public void main( String[] args ) {
+        satisfiesAllOf(isPositive(), isEqualTo(10.9));
+        satisfiesAllOf(isPositive(), isEqualTo(10));
+
+        Number num = null;
+        satisfiesAllOf(isPositive(), isEqualTo(num));
+
+        this.<Number>satisfiesAllOf(isPositive(), isEqualTo(10));
+    }
+
+
+    public interface Predicate<T> {
+
+    }
+
+    public  <ALL> void satisfiesAllOf( Predicate<? super ALL> first, Predicate<? super ALL> second ) {
+    }
+
+    public  <POSITIVE extends Number> Predicate<POSITIVE> isPositive() {
+        return null;
+    }
+
+    public <EQUALTO extends Number> Predicate<EQUALTO> isEqualTo( EQUALTO target ) {
+        return null;
+    }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InheritFromTypeParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InheritFromTypeParameter.java
new file mode 100644
index 0000000..cfad53e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InheritFromTypeParameter.java
@@ -0,0 +1,2 @@
+class C<T> extends <error descr="Class cannot inherit from its type parameter">T</error>
+{}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InheritedWithDifferentArgsInTypeParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InheritedWithDifferentArgsInTypeParams.java
new file mode 100644
index 0000000..2adff2f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InheritedWithDifferentArgsInTypeParams.java
@@ -0,0 +1,24 @@
+interface IA<T> {}
+interface IB<T> extends IA<T> {}
+
+class A {
+    <<error descr="'IA' cannot be inherited with different type arguments: 'java.lang.Integer' and 'java.lang.String'"></error>T extends IA<Integer> & IB<String>> void foo(){}
+}
+
+
+
+interface IA1<T> {}
+interface IB1<T> extends IA1<T> {}
+
+class A1 {
+    <<error descr="'IA1' cannot be inherited with different type arguments: 'java.lang.Object' and 'capture<?>'"></error>T extends IA1<Object> & IB1<?>> void foo(){}
+}
+
+interface IA2<T> {}
+interface IB2<T> extends IA2<T[]> {}
+
+class A2 {
+    <T extends IA2<Object[]> & IB2<?>> void foo(){}
+}
+
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InnerClassRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InnerClassRef.java
new file mode 100644
index 0000000..f133292
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InnerClassRef.java
@@ -0,0 +1,19 @@
+import java.util.*;
+import Node.Details;
+
+public class Node<E> {
+    public class Details {
+        public E data;
+    }
+    public Details addNode(Node<E> child) {
+        return new Details();
+    }
+}
+
+class Test {
+  public static void main(String[] args) {
+     Map<String, Details> m = null;
+     Map<String, Node.Details> sorted1;
+     sorted1 = m;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InstanceClassInStaticContextAccess.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InstanceClassInStaticContextAccess.java
new file mode 100644
index 0000000..dcfad56b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InstanceClassInStaticContextAccess.java
@@ -0,0 +1,62 @@
+class MyTest<K> {
+
+    class A<T> {
+    }
+
+    //not an error in java 8?!
+    static class C<T extends <error descr="'MyTest.this' cannot be referenced from a static context">A<String></error>> {
+    }
+
+    static <T extends <error descr="'MyTest.this' cannot be referenced from a static context">A<String></error>> void bar() {
+    }
+
+    static class B {
+        {
+            B.<<error descr="'MyTest.this' cannot be referenced from a static context">A</error>>bar();
+            <error descr="'MyTest.this' cannot be referenced from a static context">A</error> a;
+        }
+
+        static <T extends <error descr="'MyTest.this' cannot be referenced from a static context">A<String></error>> void bar() {
+        }
+
+        void v(C<<error descr="'MyTest.this' cannot be referenced from a static context">A<String></error>> c) {
+        }
+    }
+}
+
+class MyTest1 {
+
+    class A<T> {
+    }
+
+    static class C<T extends A<String>> {
+    }
+
+    static <T extends A<String>> void bar() {
+    }
+
+    static class B {
+        {
+            B.<A>bar();
+            A a = <error descr="'MyTest1.this' cannot be referenced from a static context">new A()</error>;
+        }
+
+        static <T extends A<String>> void bar() {
+        }
+
+        void v(C<A<String>> c) {
+        }
+    }
+}
+
+class MyTest2<T> {
+    static class A {
+      private MyTest2 myTest;
+  
+      public Object foo() {
+        return myTest.new Bar();
+      }
+    }
+
+    class Bar {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IntersectionTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IntersectionTypes.java
new file mode 100644
index 0000000..48bb90c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IntersectionTypes.java
@@ -0,0 +1,221 @@
+import java.io.*;
+import java.util.*;
+
+class Test {
+    <T> List<T> asList (T... ts) {
+      ts.hashCode();
+      return null;
+    }
+
+    void foo() {
+        List<Class<? extends Serializable>> l = <warning descr="Unchecked generics array creation for varargs parameter">this.asList</warning>(String.class, Integer.class);
+        l.size();
+        List<? extends Object> objects = this.asList(new String(), new Integer(0));
+        objects.size();
+    }
+}
+
+//SUN BUG ID 5034571
+interface I1 {
+    void i1();
+}
+
+class G1 <T extends I1> {
+    T get() { return null; }
+}
+
+interface I2 {
+    void i2();
+}
+
+class Main {
+    void f2(G1<? extends I2> g1) {
+        g1.get().i1(); // this should be OK
+        g1.get().i2(); // this should also be OK
+    }
+}
+
+//IDEADEV4200: this code is OK
+interface I11 {
+    String i1();
+}
+
+interface I21 {
+    String i2();
+}
+
+interface A<T> {
+    T some();
+}
+
+interface B<T extends I11 & I21> extends A<T> {
+
+}
+
+class User {
+
+    public static void main(B<?> test) {
+        System.out.println(test.some().i1());
+        System.out.println(test.some().i2());
+    }
+}
+/*
+ * Copyright 2000-2011 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.
+ */
+
+//end of IDEADEV4200
+
+//IDEADEV-4214
+interface Keyable<K> {
+    /**
+     * @return the key for the instance.
+     */
+    public K getKey();
+}
+
+abstract class Date implements java.io.Serializable, Cloneable, Comparable<Date> {
+
+}
+
+class Maps {
+    public static class MapEntry<K, V> implements Map.Entry<K, V> {
+        K k;
+        V v;
+
+        public K getKey() {
+            return k;
+        }
+
+        public V getValue() {
+            return v;
+        }
+
+        public V setValue(V value) {
+            return v = value;
+        }
+
+        public MapEntry(K k, V v) {
+            this.k = k;
+            this.v = v;
+        }
+    }
+
+    public static <K, V> Map.Entry<K, V> entry(K key, V value) {
+        return new MapEntry<K, V>(key, value);
+    }
+
+    public static <K, V> Map<K, V> asMap(Map.Entry<? extends K, ? extends V> ... <warning descr="Parameter 'entries' is never used">entries</warning>) {
+        return null;
+    }
+
+    public static <K, V extends Keyable<K>> Map<K, V> asMap(V ... <warning descr="Parameter 'entries' is never used">entries</warning>) {
+        return null;
+    }
+}
+
+class Client {
+    void f(Date d) {
+        //this call should be OK
+        <warning descr="Unchecked generics array creation for varargs parameter">Maps.asMap</warning>(Maps.entry(fieldName(), "Test"),
+                   Maps.entry(fieldName(), 1),
+                   Maps.entry(fieldName(), d));
+    }
+
+    String fieldName() {
+        return null;
+    }
+}
+//end of IDEADEV-4214
+
+class IDEADEV25515 {
+    static <T> List<T> asList (T... ts) {
+      ts.hashCode();
+      return null;
+    }
+
+    public static final
+    List<Class<? extends Serializable>> SIMPLE_TYPES =
+<warning descr="Unchecked generics array creation for varargs parameter">asList</warning>(String.class, Integer.class ,Long.class, Double.class, /*Date.class,*/
+Boolean.class, Boolean.TYPE /*,String[].class */ /*,BigDecimal.class*/);
+
+
+      public static final List<Class<? extends Serializable>> SIMPLE_TYPES_INFERRED =
+  <warning descr="Unchecked generics array creation for varargs parameter">asList</warning>(String.class, Integer.class ,Long.class, Double.class, /*Date.class,*/
+  Boolean.class, Boolean.TYPE ,String[].class  /*,BigDecimal.class*/);
+
+
+}
+///////////////////////
+class Axx {
+  <T extends Runnable> T a() {
+    String s = a();
+    s.hashCode();
+    return null;
+  }
+}
+///////////////
+interface L {}
+public class MaximalType  {
+    public static <T> T getParentOfType(Class<? extends T>... classes) {
+       classes.hashCode();
+       return null;
+    }
+    {
+        <warning descr="Unchecked generics array creation for varargs parameter">getParentOfType</warning>(M2.class, M.class);
+    }
+}
+class M extends MaximalType implements L{}
+class M2 extends MaximalType implements L{}
+/////////////
+
+
+class IDEA67676 {
+  interface I<<warning descr="Type parameter 'T' is never used">T</warning>> {}
+  interface A<T> extends I<A<T>>{}
+  interface Com2<T, U> {
+    void foo(T t, U u);
+  }
+  interface Com1<T> {
+    void foo(T t);
+  }
+
+  abstract class X {
+      abstract <T> T foo(T x, T y);
+
+      void bar(A<A2> x, A<B2> y) {
+          A<? extends Com2<? extends Com2<?, ?>, ? extends Com2<?, ?>>> f = foo(x, y);
+          f.hashCode();
+      }
+
+      void boo(A<A3> x, A<B3> y) {
+          A<? extends Com2<? extends Com2<?, ?>, ? extends Com2<?, ?>>> f = foo(x, y);
+          f.hashCode();
+      }
+
+      void baz(A<A1> x, A<B1> y) {
+          A<? extends Com1<? extends Com1<?>>> f = foo(x, y);
+          f.hashCode();
+      }
+  }
+
+  abstract class A1 implements Com1<A1> {}
+  abstract class B1 implements Com1<B1> {}
+
+  abstract class A2 implements Com2<A2, A2> {}
+  abstract class B2 implements Com2<B2, B2> {}
+
+  abstract class A3 implements Com2<A3, B3> {}
+  abstract class B3 implements Com2<B3, A3> {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodCallOnRawTypesExtended.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodCallOnRawTypesExtended.java
new file mode 100644
index 0000000..42e1c42
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodCallOnRawTypesExtended.java
@@ -0,0 +1,17 @@
+import java.util.Collections;
+import java.util.List;
+
+class Bar {
+    private List<Property> getChildren(Property property, PropertiesContainer c) {
+         return property.getChildren(c);
+    }
+
+    static class PropertiesContainer<M extends Property> {}
+
+}
+
+class Property<K> {
+    public List<? extends Property<K>> getChildren(K container) {
+        return Collections.emptyList();
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodCallParamsOnRawType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodCallParamsOnRawType.java
new file mode 100644
index 0000000..e399e5a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodCallParamsOnRawType.java
@@ -0,0 +1,32 @@
+class TestOnRawType {
+  public static void main(String[] args) {
+    new FooGenerator().process(TestOnRawType.class);
+    new FooGenerator().process(AFoo.class);
+    new FooGenerator().process(MFoo.class);
+    new FooGenerator<String>().process<error descr="'process(java.lang.Class<TestOnRawType.AFoo>)' in 'TestOnRawType.FooGenerator' cannot be applied to '(java.lang.Class<TestOnRawType>)'">(TestOnRawType.class)</error>;
+    new FooGenerator<String>().process(AFoo.class);
+    new FooGenerator<String>().process<error descr="'process(java.lang.Class<TestOnRawType.AFoo>)' in 'TestOnRawType.FooGenerator' cannot be applied to '(java.lang.Class<TestOnRawType.MFoo>)'">(MFoo.class)</error>;
+  }
+
+  static class AFoo {}
+  static class MFoo extends AFoo {}
+  static class FooGenerator<T> {
+    public void process(Class<AFoo> cls) {
+    }
+  }
+}
+
+class TestNonGenericType {
+  public static void main(String[] args) {
+    new FooGenerator().process<error descr="'process(java.lang.Class<TestNonGenericType.AFoo>)' in 'TestNonGenericType.FooGenerator' cannot be applied to '(java.lang.Class<TestNonGenericType>)'">(TestNonGenericType.class)</error>;
+    new FooGenerator().process(AFoo.class);
+    new FooGenerator().process<error descr="'process(java.lang.Class<TestNonGenericType.AFoo>)' in 'TestNonGenericType.FooGenerator' cannot be applied to '(java.lang.Class<TestNonGenericType.MFoo>)'">(MFoo.class)</error>;
+  }
+
+  static class AFoo {}
+  static class MFoo extends AFoo {}
+  static class FooGenerator {
+    public void process(Class<AFoo> cls) {
+    }
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodSignatureEquality.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodSignatureEquality.java
new file mode 100644
index 0000000..cabf948
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodSignatureEquality.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2010 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 java.io.*;
+class Test {
+  interface InterfA {
+    <T extends Cloneable & Iterable> void foo(T x);
+
+    <T extends Iterable & Cloneable> void foo(T x);
+  }
+
+  class ANotSame {
+    <T extends Cloneable & Iterable> void foo(T x){}
+
+    <T extends Iterable & Cloneable> void foo(T x){}
+  }
+
+  class BNotSame extends ANotSame {
+      @Override
+      <T extends Cloneable & Iterable> void foo(T x){}
+  }
+
+  abstract class A<T extends Throwable> {
+    abstract <T extends Comparable<?> & Serializable> void foo(T x, A<?> y);
+
+    abstract <T extends Serializable & Comparable<?>> void foo(T x, A<? extends Cloneable> y);
+  }
+
+ /* abstract class B<T extends Throwable> {
+    abstract <T extends Comparable<?> & Serializable> void foo(T x, B<?> y);
+
+    abstract <T extends Serializable & Comparable<?>> void foo(T x, B<? extends Throwable> y);
+  }
+
+
+  abstract class C<T extends Throwable & Serializable> {
+    abstract <T extends Comparable<?> & Serializable> void foo(T x, C<? extends Serializable> y);
+
+    abstract <T extends Serializable & Comparable<?>> void foo(T x, C<? extends Throwable> y);
+  }*/
+
+  abstract class D<T extends Throwable & Runnable> {
+    <error descr="'foo(T, D<? extends Runnable>)' clashes with 'foo(T, D<? extends Throwable>)'; both methods have same erasure">abstract <T extends Serializable & Comparable<?>> void foo(T x, D<? extends Runnable> y)</error>;
+
+    abstract <T extends Serializable & Comparable<?>> void foo(T x, D<? extends Throwable> y);
+  }
+
+
+  interface IA {}
+  interface IB {}
+  void testExtendsOrder() {
+    class E<T extends IA & IB> {
+      <error descr="'foo(E<? extends IA>)' clashes with 'foo(E<? extends IB>)'; both methods have same erasure">void foo(E<? extends IA> x)</error> {}
+      void foo(E<? extends IB> x) {}
+    }
+  }
+
+  abstract class F<T extends Throwable> {
+    <error descr="'foo(F<?>)' is already defined in 'Test.F'">abstract void foo(F<?> y)</error>;
+
+    <error descr="'foo(F<? extends Throwable>)' is already defined in 'Test.F'">abstract void foo(F<? extends Throwable> y)</error>;
+  }
+}
+
+class Ao {}
+
+class Bo extends Ao {}
+
+class SettingsEditor<T> {
+}
+
+abstract class RunConfigurationExtension<T extends Ao> {
+    protected abstract <P extends T> SettingsEditor<P> createEditor(final P configuration);
+}
+
+class F extends RunConfigurationExtension<Bo> {
+
+    @Override
+    protected <P extends Bo> SettingsEditor<P> createEditor(P configuration) {
+        return null;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Methods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Methods.java
new file mode 100644
index 0000000..d0f994e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Methods.java
@@ -0,0 +1,38 @@
+import java.util.*;
+
+interface Base {
+}
+
+class Derived implements Base {
+}
+
+class X {
+    void method(int i, Base b) { }
+    void method(int i, Derived b) { }
+
+    {
+        Derived d = new Derived();
+        method(10, d);
+    }
+}
+
+class Temp<T> {}
+
+class A {
+   <error descr="'A(T)' clashes with 'A(T)'; both methods have same erasure">public <T extends Temp<String>> A(T list)</error> {}
+   public <T extends Temp<Integer>> A(T list) {}
+}
+class B {
+   public <T extends A> B(T list) {}
+   public <T extends Temp<Integer>> B(T list) {}
+}
+
+
+
+//////////////////////////////////////////
+class IdeaBug {
+
+    static <T> T cloneMe(T arg) throws CloneNotSupportedException {
+        return (T) arg.<error descr="'clone()' has protected access in 'java.lang.Object'">clone</error>();
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/NoInferenceFromTypeCast.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/NoInferenceFromTypeCast.java
new file mode 100644
index 0000000..636556d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/NoInferenceFromTypeCast.java
@@ -0,0 +1,23 @@
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+
+interface A {}
+
+interface B extends A {}
+
+class Foo {
+    public <TA extends A> List<TA> getAs() {
+        return (List<TA>) getBs();
+    }
+
+    public <T extends B> List<T> getBs() {
+        return null;
+    }
+
+    void foo(Set<String> s) {}
+    {
+        foo(<error descr="Inconvertible types; cannot cast 'java.util.Set<java.lang.Object>' to 'java.util.Set<java.lang.String>'">(Set<String>)Collections.emptySet()</error>);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/OverrideAtLanguageLevel6.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/OverrideAtLanguageLevel6.java
new file mode 100644
index 0000000..d83cf65
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/OverrideAtLanguageLevel6.java
@@ -0,0 +1,13 @@
+interface I {
+	void f();
+}
+interface II extends I {
+    @Override
+    void f();
+}
+class C implements I {
+    @Override
+    public void f() {
+
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/OverrideWithMoreSpecificReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/OverrideWithMoreSpecificReturn.java
new file mode 100644
index 0000000..c2f6877
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/OverrideWithMoreSpecificReturn.java
@@ -0,0 +1,15 @@
+import java.util.List;
+
+interface ExampleInterface {
+    public List exampleMethod();
+}
+
+class ExampleSuperClass {
+    public List<String> exampleMethod() {
+        return null;
+    }
+}
+
+
+public class  ExampleSubClass extends ExampleSuperClass implements ExampleInterface {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ParameterizedParameterBound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ParameterizedParameterBound.java
new file mode 100644
index 0000000..50e117b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ParameterizedParameterBound.java
@@ -0,0 +1,6 @@
+import java.util.*;
+class ParamHolder<T extends List<String>> {}
+class HolderUsage {
+        public void fail(ParamHolder<<error descr="Type parameter 'java.util.List' is not within its bound; should extend 'java.util.List<java.lang.String>'">List</error>> p) { }
+        public void success(ParamHolder<ArrayList<String>> p) { }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/PrivateInnerClassRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/PrivateInnerClassRef.java
new file mode 100644
index 0000000..5647b1d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/PrivateInnerClassRef.java
@@ -0,0 +1,30 @@
+import java.util.Comparator;
+
+public abstract class A implements <error descr="'A.B' has private access in 'A'">Comparator<A.B></error> {
+
+  private static class B {
+  }
+
+  private interface I extends Comparator<I>{}
+  private interface I1 extends Comparator<I>{}
+}
+
+//abstract class C implements error descr="'C.D' has private access in 'C'">C.D error {
+//  private static class D {}
+//}
+
+class JSReferenceSet {
+    static class MyResolver implements JSResolveUtil.Resolver<M> {}
+    class M extends JSResolveUtil.F {}
+}
+class JSResolveUtil {
+    static interface Resolver<T extends F> {}
+    static class F {}
+}
+
+
+class TestIDEA62515 {
+  public static interface Model<T> {}
+  public class Inner {}
+  public static class Foo implements Model<Inner> {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Raw.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Raw.java
new file mode 100644
index 0000000..25ef682
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Raw.java
@@ -0,0 +1,177 @@
+import java.util.ArrayList;
+
+class Reference<<warning descr="Type parameter 'T' is never used">T</warning>> {
+}
+class WeakReference<T> extends Reference<T> {
+}
+class Item<<warning descr="Type parameter 'Key' is never used">Key</warning>, T> extends WeakReference<T> {
+ {
+   Reference<T> ref = null;
+   Item item = (Item) ref;
+   equals(item);
+ }
+}
+
+// assign raw to generic are allowed
+class a<E> {
+ void f(a<E> t){
+    t.hashCode();
+ }
+}
+class b  {
+  a<b> f(a raw) {
+   a<?> unbound = raw;
+   raw = unbound;
+
+   a<Integer> generic = <warning descr="Unchecked assignment: 'a' to 'a<java.lang.Integer>'">raw</warning>;
+   <warning descr="Unchecked call to 'f(a<E>)' as a member of raw type 'a'">raw.f</warning>(raw);
+   <warning descr="Unchecked call to 'f(a<E>)' as a member of raw type 'a'">raw.f</warning>(generic);
+   generic.f(<warning descr="Unchecked assignment: 'a' to 'a<java.lang.Integer>'">raw</warning>);
+   generic.f(generic);
+   generic.f<error descr="'f(a<java.lang.Integer>)' in 'a' cannot be applied to '(a<java.lang.String>)'">(new a<String>())</error>;
+   generic = <warning descr="Unchecked assignment: 'a' to 'a<java.lang.Integer>'">raw</warning>;
+
+
+   return <warning descr="Unchecked assignment: 'a' to 'a<b>'">raw</warning>;
+  }
+}
+
+class List<T> {
+   <V> V[] toArray (V[] vs) { return vs; }
+   void add(T t) {
+     t.hashCode();
+   }
+}
+
+class c {
+  /*String[] f () {
+    List l = new List();
+    error descr="Incompatible types. Found: 'java.lang.Object[]', required: 'java.lang.String[]'">return l.toArray (new String[0]);</error
+  }*/
+  
+  String[] g () {
+    List<String> l = new List<String>();
+    return l.toArray (new String[0]);
+  }
+}
+
+class d {
+    class Y <<warning descr="Type parameter 'T' is never used">T</warning>> {
+    }
+
+    class Z <<warning descr="Type parameter 'T' is never used">T</warning>> extends Y<Y> {
+    }
+
+    class Pair <X> {
+        void foo(Y<? extends X> y) {
+          y.hashCode();
+        }
+    }
+
+    Pair<Z> pair;
+
+    void bar(Y<? extends Y> y) {
+        pair.foo<error descr="'foo(d.Y<? extends d.Z>)' in 'd.Pair' cannot be applied to '(d.Y<capture<? extends d.Y>>)'">(y)</error>;
+    }
+}
+
+class e {
+    String foo () {
+        MyList myList = new MyList();
+        <error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.String'">return myList.get(0);</error>
+    }
+
+    static class MyList<<warning descr="Type parameter 'T' is never used">T</warning>> extends ArrayList<String>{
+    }
+}
+
+class ccc {
+    static Comparable<? super ccc> f() {
+        return <warning descr="Unchecked assignment: 'java.lang.Comparable' to 'java.lang.Comparable<? super ccc>'">new Comparable () {
+            public int compareTo(final Object o) {
+                return 0;
+            }
+        }</warning>;
+    }
+}
+
+class ddd<COMP extends ddd> {
+    COMP comp;
+    ddd foo() {
+        return comp; //no unchecked warning is signalled here
+    }
+}
+
+class G1<T> {
+  T t;
+}
+class G2<T> {
+    T t;
+    
+    static ArrayList<G1> f() {
+        return null;
+    }
+}
+
+class Inst {
+    static void f () {
+        G2<G1<String>> g2 = new G2<G1<String>>();
+        for (<warning descr="Unchecked assignment: 'G1' to 'G1<java.lang.String>'">G1<String> g1</warning> : g2.f()) {
+          g1.toString();
+        }
+    }
+}
+
+class A111<T> {
+  T t;
+  <V> V f(V v) {
+    return v;
+  }
+
+  String g(A111 a) {
+    //noinspection unchecked
+    <error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.String'">return a.f("");</error>
+  }
+}
+
+class A1 {
+  <V> V f(V v) {
+    return v;
+  }
+}
+
+class A11<T> extends A1 {
+    T t;
+
+    //this is OK, type parameters of base class are not raw
+    String s = new A11().f("");
+}
+
+//IDEADEV-26163
+class Test1<X> {
+  X x;
+  java.util.ArrayList<Number> foo = new java.util.ArrayList<Number>();
+  public static Number foo() {
+    <error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.Number'">return new Test1().foo.get(0);</error>
+  }
+}
+//end of IDEADEV-26163
+
+
+///////////////  signatures in non-parameterized class are not erased
+public class C3  {
+    public int get(Class<?> c) {
+        return 0;
+    }
+}
+
+class Cp<T> extends C3 {
+  public T i;
+}
+class C extends Cp/*<C>*/ {
+    @Override
+    public int get(Class<?> c) {
+        return 0;
+    }
+}
+//////////////
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawAssignments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawAssignments.java
new file mode 100644
index 0000000..bd2af72
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawAssignments.java
@@ -0,0 +1,18 @@
+import java.io.*;
+import java.util.*;
+
+interface Foo {
+    String getText(Map attributes) throws IOException;
+    String getText(Properties attributes) throws IOException;
+}
+
+class Bar {
+    void foo(Foo foo, Properties prop) throws IOException {
+        foo.getText(prop);
+    }
+}
+public abstract class Hashtable<K,V> implements Map<K,V>, Cloneable {
+}
+
+public abstract class Properties extends Hashtable<Object,Object> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawOnParameterized.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawOnParameterized.java
new file mode 100644
index 0000000..ebdeca9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawOnParameterized.java
@@ -0,0 +1,29 @@
+class GenericOuter<T> {
+    public class GenericInner<U> {
+    }
+
+    public static class StaticGenericInner<U> {
+    }
+
+    public class SimpleInner {
+    }
+}
+
+class OuterClient {
+    public void context() {
+        <error descr="Improper formed type; some type parameters are missing">GenericOuter<String>.GenericInner</error> v1 = null;
+        GenericOuter.GenericInner<error descr="Type arguments given on a raw type"><String></error> v2 = null;
+        GenericOuter.GenericInner v3 = null; 
+        GenericOuter<String>.GenericInner<String> v4 = null;
+
+        GenericOuter<error descr="Cannot select static class 'GenericOuter.StaticGenericInner' from parameterized type"><String></error>.StaticGenericInner sv1 = null;
+        GenericOuter.StaticGenericInner<String> sv2 = null;
+        GenericOuter.StaticGenericInner sv3 = null;
+        GenericOuter<error descr="Cannot select static class 'GenericOuter.StaticGenericInner' from parameterized type"><String></error>.StaticGenericInner<String> sv4 = null;
+
+        GenericOuter<String>.SimpleInner iv1 = null;
+        GenericOuter.SimpleInner<error descr="Type arguments given on a raw type"><String></error> iv2 = null;
+        GenericOuter.SimpleInner iv3 = null;
+        GenericOuter<String>.SimpleInner<error descr="Type 'GenericOuter.SimpleInner' does not have type parameters"><String></error> iv4 = null;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawOverridingMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawOverridingMethods.java
new file mode 100644
index 0000000..1934012
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawOverridingMethods.java
@@ -0,0 +1,271 @@
+import java.util.*;
+
+class Base<T> {
+    public void method(Base<?> base) { }
+    public void method1(Base<Base<?>> base) { }
+    public <V> Base<V> foo() { return null; }
+    public Base<?> bar() { return null; }
+    public Base<Base<?>> far() { return null; }
+}
+
+class Derived extends Base {
+    public void method(Base base) { }
+    public Base foo() { return null; }
+    public Base bar() { return null; }
+}
+
+class Derived1 extends Base {
+    <error descr="'method1(Base<String>)' in 'Derived1' clashes with 'method1(Base<Base<?>>)' in 'Base'; both methods have same erasure, yet neither overrides the other">public void method1(Base<String> base)</error> { }
+    public Base<String> far() { return null; } // Acceptable construct as of JDK 1.5 beta 2 may 2004
+}
+
+class X <T> {
+    public <V> void foo () {}
+}
+
+class YY extends X {
+    <error descr="'foo()' in 'YY' clashes with 'foo()' in 'X'; both methods have same erasure, yet neither overrides the other">public <V> void foo()</error> {}
+}
+
+interface List<Y> {
+    public <T> T[] toArray(T[] ts);
+}
+class AbstractList<Y> {
+    public <T> T[] toArray(T[] ts) {return null;}
+}
+//Signatures from List and AbstractList are equal
+class ArrayList extends AbstractList implements List {}
+
+//SCR 39485: the following overriding is OK
+abstract class Doer {
+    abstract <X> void go(X x);
+}
+
+class MyList <X>
+   extends Doer {
+   X x; 
+   <Y> void go(Y y) {}
+}
+
+class MyListRaw
+       extends MyList {
+}
+
+//See IDEADEV-1125
+//The following two classes are OK
+class A1 {
+    <T> void foo(T t) {}
+}
+
+class A2 extends A1 {
+    void foo(Object o) {}
+}
+
+//While these are not
+class A3 {
+    void foo(Object o) {}
+}
+
+class A4 extends A3 {
+    <error descr="'foo(T)' in 'A4' clashes with 'foo(Object)' in 'A3'; both methods have same erasure, yet neither overrides the other"><T> void foo(T t)</error> {}
+}
+
+//This sibling override is OK
+class A5 {
+    public void foo(Object o) {}
+}
+
+interface I1 {
+    <T> void foo(T t);
+}
+
+class A6 extends A5 implements I1 {}
+
+//While this is not
+class A7 {
+    public <T> void foo(T t) {}
+}
+
+interface I2 {
+    public void foo(Object o);
+}
+
+<error descr="Class 'A8' must either be declared abstract or implement abstract method 'foo(Object)' in 'I2'">class A8 extends A7 implements I2</error> {}
+
+//IDEA-9321
+abstract class MyMap<K, V> implements java.util.Map<K, V> {
+    public  <error descr="'put(K, V)' in 'MyMap' clashes with 'put(K, V)' in 'java.util.Map'; attempting to use incompatible return type">Object</error> put(K key, V value) {
+        return null;
+    }
+}
+//end of IDEA-9321
+
+abstract class AA <T> {
+    abstract void foo(T t);
+}
+
+abstract class BB<T> extends AA<BB> {
+    void foo(BB b) {}
+}
+
+class CC extends BB {
+  //foo is correctly seen from BB
+}
+
+class QQQ {}
+
+abstract class GrandParent<T> {
+    public abstract void paint(T object);
+}
+
+class Parent<T extends QQQ> extends GrandParent<T> {
+    public void paint(T component) {
+    }
+}
+
+// this overriding should be OK
+class Child2 extends Parent {
+
+}
+
+class IDEA16494  {
+    class Base<B> {
+        public List<B> elements() {
+            return null;
+        }
+    }
+
+    class Derived<T> extends Base<T[]> {
+    }
+
+    class MostDerived extends Derived {
+
+        public List<MostDerived[]> elements() {
+            return null;
+        }
+    }
+}
+class IDEA16494Original  {
+    class Base<B> {
+        public List<B> elements() {
+            return null;
+        }
+    }
+
+    class Derived<T> extends Base<T> {
+    }
+
+    class MostDerived extends Derived {
+
+        public List<MostDerived> elements() {
+            return null;
+        }
+    }
+}
+class IDEADEV23176Example {
+  public abstract class AbstractBase<E> extends AbstractParent<E> implements Interface<E> {
+  }
+  public abstract class AbstractParent<E> {
+    public void Implemented(Collection<?> c) {
+    }
+    public abstract void mustImplement();
+  }
+  public class Baseclass extends AbstractBase implements Interface {
+    public void mustImplement() {
+    }
+  }
+  public interface Interface<E> {
+    void Implemented(Collection<?> c);
+  }
+}
+
+/** @noinspection UnusedDeclaration*/
+class IDEADEV26185
+{
+    public static abstract class SuperAbstract<Owner, Type>
+    {
+        public abstract Object foo(Type other);
+    }
+
+    public static abstract class HalfGenericSuper<Owner> extends SuperAbstract<Owner, String>
+    {
+        public abstract Object foo(String other);
+    }
+
+    public static abstract class AbstractImpl<Owner> extends HalfGenericSuper<Owner>
+    {
+        public Object foo(String other)
+        {
+            return null;
+        }
+    }
+
+    public static class Concrete extends AbstractImpl
+    {
+    }
+}
+
+class ideadev30090 {
+  abstract class MyBeanContext
+        implements MyListInterface/*<MyListMember>*/ {
+    public Object get(int index) {
+        return null;
+    }
+  }
+
+  interface MyListInterface<E extends MyListMember>
+        extends List<E> {
+  }
+  interface MyListMember {
+     void f();
+  }
+}
+//////////////////////////////////////////
+class IDEADEV32421 {
+ interface InterfaceWithFoo {
+    Class<?> foo();
+ }
+
+ class ParentWithFoo implements InterfaceWithFoo {
+    public Class foo() {
+        return null;
+    }
+ }
+
+ class TestII extends ParentWithFoo implements InterfaceWithFoo {
+ }
+}
+
+class IDEADEV32421_TheOtherWay {
+ interface InterfaceWithFoo {
+    Class foo();
+ }
+
+ class ParentWithFoo implements InterfaceWithFoo {
+    public Class<?> foo() {
+        return null;
+    }
+ }
+
+ class TestII extends ParentWithFoo implements InterfaceWithFoo {
+ }
+}
+//////////////////////////////////////
+class SBBug {
+  abstract class A<T> implements Comparable<A<T>> {}
+
+  class B extends A {
+      public int compareTo(Object o) {
+          return 0;
+      }
+  }
+}
+class SBBug2 {
+    abstract class A<T> implements Comparable<A<T>> {}
+
+    <error descr="Class 'B' must either be declared abstract or implement abstract method 'compareTo(T)' in 'Comparable'">class B extends A</error> {
+        public int compareTo(A o) {
+            return 0; 
+        }
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ReferenceTypeParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ReferenceTypeParams.java
new file mode 100644
index 0000000..2d64d7c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ReferenceTypeParams.java
@@ -0,0 +1,152 @@
+import java.lang.Object;
+import java.util.*;
+
+class C<T,U> {
+
+  C c1 = new C<error descr="Wrong number of type arguments: 1; required: 2"><Integer></error>();
+  C c2 = new C<error descr="Wrong number of type arguments: 3; required: 2"><Integer, Float, Object></error>();
+  Object o = new Object<error descr="Type 'java.lang.Object' does not have type parameters"><C></error>();
+
+  C c3 = new C();
+  C c4 = new C<Object, C>();
+  C<Integer, Float> c5 = new C<Integer, Float>(); 
+}
+
+class D<T extends C> {
+  {
+    new D<<error descr="Type parameter 'java.lang.Integer' is not within its bound; should extend 'C'">Integer</error>>();
+    new D<C>();
+    class CC extends C {};
+    new D<CC>();
+    new D<T>();
+  }
+
+  T field = new <error descr="Type parameter 'T' cannot be instantiated directly">T</error>();
+  T field2 = new <error descr="Type parameter 'T' cannot be instantiated directly">T</error>() { };
+  T[] array = new <error descr="Type parameter 'T' cannot be instantiated directly">T</error>[10];
+}
+
+class Primitives<T> {
+  Object a = new Primitives<<error descr="Type argument cannot be of primitive type">? extends int</error>>();
+  Object o = new Primitives<<error descr="Type argument cannot be of primitive type">int</error>>();
+  void f(Primitives<<error descr="Type argument cannot be of primitive type">boolean</error>> param) {
+    if (this instanceof Primitives<<error descr="Type argument cannot be of primitive type">double</error>>) {
+      return;
+    }
+  }
+}
+
+
+/////// calling super on generic bound class
+public class Generic<T> {
+    Generic(T t){}
+}
+public class Bound extends Generic<String>{
+    public Bound(String s) {
+        super(s);
+    }
+}
+
+////
+class Generic2<T1,T2> {
+  class A {}
+  class B {}
+  private <error descr="Incompatible types. Found: 'Generic2<java.lang.String,Generic2.B>', required: 'Generic2<java.lang.String,Generic2.A>'">Generic2<String, A> map = new Generic2<String,B>();</error>
+  {
+    <error descr="Incompatible types. Found: 'Generic2<java.lang.String,java.lang.String>', required: 'Generic2<java.lang.String,Generic2.A>'">map = new Generic2<String,String>()</error>;
+    map = new Generic2<String,A>();
+  }
+}
+
+class DummyList<T> {}
+abstract class GenericTest3 implements DummyList<<error descr="No wildcard expected">? extends String</error>> {
+    DummyList<DummyList<? extends DummyList>> l;
+    <T> void foo () {}
+    void bar () {
+         this.<DummyList<? extends DummyList>>foo();
+         DummyList<DummyList<? super String>>[] l = <error descr="Generic array creation">new DummyList<DummyList<? super String>>[0]</error>;
+         DummyList<String>[] l1 = <error descr="Generic array creation">{}</error>;
+    }
+
+    public <T> T[] getComponents (Class<T> baseInterfaceClass) {
+        T[] ts = <error descr="Generic array creation">{}</error>;
+
+        return ts;
+    }
+}
+
+class mylist<T> {}
+class myAList<T> extends mylist<T> {
+  {
+        mylist<String> l = <error descr="Inconvertible types; cannot cast 'myAList<java.lang.Integer>' to 'mylist<java.lang.String>'">(mylist<String>) new myAList<Integer>()</error>;
+        boolean b = <error descr="Operator '==' cannot be applied to 'myAList<java.lang.Integer>', 'myAList<java.lang.String>'">new myAList<Integer>() == new myAList<String>()</error>;
+
+        if (l instanceof <error descr="Illegal generic type for instanceof">myAList<String></error>);
+        Object o = new Object();
+        if (o instanceof <error descr="Class or array expected">T</error>);
+  }
+
+  Class<T> foo (Class<T> clazz) {
+        Class<String> clazz1 = (Class<String>)clazz;  //Should be unchecked warning
+        return <error descr="Cannot select from a type variable">T</error>.class;
+  }
+}
+
+class testDup<T, <error descr="Duplicate type parameter: 'T'">T</error>> { // CAN IT BE HIGHLIGHTED? b
+    public <T, <error descr="Duplicate type parameter: 'T'">T</error>> void foo() { // CAN IT BE HIGHLIGHTED?
+    }
+}
+
+class aaaa {
+    {
+        <error descr="Incompatible types. Found: 'java.lang.Class<java.lang.String>', required: 'java.lang.Class<? super java.lang.Object>'">Class<? super Object> c = String.class;</error>
+    }
+}
+
+//IDEADEV-6103: this code is OK
+class Foo {
+    mylist<Test> foo;
+
+    public Foo(mylist<Test> foo) {
+        this.foo = foo;
+    }
+
+    public Foo() {
+          this(new mylist<Test>());
+    }
+
+    private class Test {
+    }
+}
+//end of IDEADEV-6103
+
+class IDontCompile {
+   Map<error descr="Cannot select static class 'java.util.Map.Entry' from parameterized type"><?, ?></error>.Entry map;
+}
+
+abstract class GenericTest99<E extends Enum<E>> {
+    GenericTest99<<error descr="Type parameter 'java.lang.Enum' is not within its bound; should extend 'java.lang.Enum<java.lang.Enum>'">Enum</error>> local;
+}
+
+class ClassLiteral<T> {
+  {
+    Object c1 = <error descr="Cannot select from a type variable">T</error>.class;
+    Object c2 = <error descr="Cannot select from a type variable">T[]</error>.class;
+    
+    Object c3 = <error descr="Cannot select from parameterized type">List<String></error>.class;
+    Object c4 = <error descr="Cannot select from parameterized type">List<String>[]</error>.class;
+    Object c5 = List[].class;
+    Object c6 = List.class;
+  }
+}
+
+class Outer<E> {
+    final Inner[] i = <error descr="Generic array creation">new Inner[10]</error>;
+    class Inner {
+    }
+}
+class Outer1<E> {
+    final Inner[] i = new Inner[10];
+    static class Inner {
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SOE.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SOE.java
new file mode 100644
index 0000000..85aeee7
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SOE.java
@@ -0,0 +1,24 @@
+public class SOE {
+}
+abstract class VersionEntity<V extends Version<V, R>, R extends Ref<V, R>>
+    implements Version<V, R>{}
+
+interface Version<V extends Version<V, R>, R extends Ref<V, R>>{}
+
+abstract class RefEntity<V extends Version<V, R>, R extends Ref<V, R>>
+    implements Ref<V, R> {}
+
+interface Ref<V extends Version<V, R>, R extends Ref<V, R>>{}
+
+
+abstract class Node<G extends Node<G, GR>,
+               GR extends NodeRef<G, GR>> extends VersionEntity<G, GR> {}
+
+abstract class NodeRef<G extends Node<G, GR>, GR extends NodeRef<G, GR>> extends RefEntity<G, GR> {}
+
+
+class D {
+    void f() {
+        Version v = new Node<<error descr="Wildcard type '?' cannot be instantiated directly">?</error>, <error descr="Wildcard type '?' cannot be instantiated directly">?</error>>(){}<EOLError descr="';' expected"></EOLError>
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SOEInLeastUpperClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SOEInLeastUpperClass.java
new file mode 100644
index 0000000..70ad266
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SOEInLeastUpperClass.java
@@ -0,0 +1,12 @@
+<error descr="Cyclic inheritance involving 'A'">interface A extends A</error> {}
+interface B {}
+
+<error descr="Cyclic inheritance involving 'A'">class T implements A, B</error>{
+    <T1> T1 foo(A a, B b) {
+        return null;
+    }
+
+    void bar (boolean a, A a1, B b1){
+        <error descr="Incompatible types. Found: 'java.lang.Object', required: 'T'">T t = a ? a1 : b1;</error>
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SameErasure.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SameErasure.java
new file mode 100644
index 0000000..9bb49b2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SameErasure.java
@@ -0,0 +1,34 @@
+import java.util.*;
+
+class SameSignatureTest {
+    <error descr="'sameErasure(List<String>)' clashes with 'sameErasure(List<Integer>)'; both methods have same erasure">public static void sameErasure(List<String> strings)</error> {
+    }
+
+    public static void sameErasure(List<Integer> integers) {
+    }
+}
+
+ class CCC {
+    <error descr="'f(Object)' clashes with 'f(Object)'; both methods have same erasure"><T> void f(Object o)</error> {}
+
+    void f(Object o) {}
+}
+
+public class Test1 {
+    <error descr="'bug(String)' clashes with 'bug(String)'; both methods have same erasure">public void bug(String s)</error> {
+    }
+
+    public static <T> T bug(String s) {
+        return null;
+    }
+}
+////////////////////////////////
+class Test {
+    <error descr="'test()' clashes with 'test()'; both methods have same erasure">public static <K, V> HashMap<K, V> test()</error> {
+        return new HashMap<K, V>();
+    }
+
+    public static String test() {
+        return "";
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SameErasureDifferentReturnTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SameErasureDifferentReturnTypes.java
new file mode 100644
index 0000000..8bbd7b6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SameErasureDifferentReturnTypes.java
@@ -0,0 +1,53 @@
+/** @noinspection UnusedDeclaration*/
+interface Matcher<T> {
+
+    boolean matches(java.lang.Object object);
+
+    void _dont_implement_Matcher___instead_extend_BaseMatcher_();
+}
+
+interface ArgumentConstraintPhrases {
+    <error descr="'with(Matcher<T>)' clashes with 'with(Matcher<Boolean>)'; both methods have same erasure"><T> T with(Matcher<T> matcher)</error>;
+    boolean with(Matcher<Boolean> matcher);
+    byte with(Matcher<Byte> matcher);
+    short with(Matcher<Short> matcher);
+    int with(Matcher<Integer> matcher);
+    long with(Matcher<Long> matcher);
+    float with(Matcher<Float> matcher);
+    double with(Matcher<Double> matcher);
+}
+
+class ExpectationGroupBuilder implements ArgumentConstraintPhrases {
+
+    <error descr="'with(Matcher<T>)' clashes with 'with(Matcher<Boolean>)'; both methods have same erasure">public <T> T with(final Matcher<T> matcher)</error> {
+        return null;
+    }
+
+    public boolean with(final Matcher<Boolean> matcher) {
+        return false;
+    }
+
+    public byte with(final Matcher<Byte> matcher) {
+        return 0;
+    }
+
+    public short with(final Matcher<Short> matcher) {
+        return 0;
+    }
+
+    public int with(final Matcher<Integer> matcher) {
+        return 0;
+    }
+
+    public long with(final Matcher<Long> matcher) {
+        return 0;
+    }
+
+    public float with(final Matcher<Float> matcher) {
+        return 0;
+    }
+
+    public double with(final Matcher<Double> matcher) {
+        return 0;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SelectFromTypeParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SelectFromTypeParameter.java
new file mode 100644
index 0000000..79229dd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SelectFromTypeParameter.java
@@ -0,0 +1,16 @@
+import java.util.List;
+interface Builder<T> {
+    T build();
+}
+
+interface Test<D extends Test<D, X>, X> {
+    static interface TestBuilder<D extends Test<D, X>, X> extends Builder<D> {}
+}
+
+interface Algorithm<T, B extends Builder<T>> {}
+
+class SelectFromVariableType<X, T extends Test<T, X>>
+        implements Algorithm<T,<error descr="Cannot select from a type parameter">T</error>.TestBuilder<T, X>> {
+    List<T.TestBuilder<T, X>> b;
+    T.TestBuilder<T, X> b1;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SelfRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SelfRef.java
new file mode 100644
index 0000000..e1f415c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SelfRef.java
@@ -0,0 +1,13 @@
+import java.util.*;
+class Node<K> {
+    List<Node<K>> getNodes() {
+        return null;
+    }
+
+    private static <T> int strongConnect(Node<T> currentNode) {
+        for (Node<T> dependantNode : currentNode.getNodes()) {
+            strongConnect(dependantNode);
+        }
+        return 0;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SpecificReturnType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SpecificReturnType.java
new file mode 100644
index 0000000..2edfece
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SpecificReturnType.java
@@ -0,0 +1,13 @@
+abstract class Field<D> {
+    public D getValue(){return null;}
+}
+
+class LabelField extends Field<Object> {
+    public Object getValue() { return null; }
+}
+interface MyInterface<D> {
+    D getValue();
+}
+
+class MyLabelField extends LabelField implements MyInterface<Object> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/StaticImports.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/StaticImports.java
new file mode 100644
index 0000000..047391d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/StaticImports.java
@@ -0,0 +1,16 @@
+
+import static java.util.Arrays.asList;
+import static java.util.Arrays.sort;
+<warning descr="Unused import statement">import static java.util.Arrays.binarySearch;</warning>
+
+public class StaticImports {
+    {
+        asList(new Object[]{});
+    }
+
+    void method() {
+        sort(new long[0]);
+//        sort< error descr="Cannot resolve method 'sort()'">()< /error>;
+    }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/StaticOverride.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/StaticOverride.java
new file mode 100644
index 0000000..d020968
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/StaticOverride.java
@@ -0,0 +1,8 @@
+import java.util.*;
+
+public class MyClass implements Comparator<String> {
+
+    <error descr="Static method 'compare(String, String)' in 'MyClass' cannot override instance method 'compare(T, T)' in 'java.util.Comparator'">public static int compare(String a, String b)</error> {
+      return 42;
+    }
+} 
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperMethodCallWithErasure.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperMethodCallWithErasure.java
new file mode 100644
index 0000000..4bd51c0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperMethodCallWithErasure.java
@@ -0,0 +1,18 @@
+import java.util.Set;
+
+interface Interface {
+    void method(Set<?> s);
+}
+
+class SuperClass implements Interface {
+    public void method(Set s) {
+        // do nothing
+    }
+}
+
+class SubClass extends SuperClass {
+    public void method(Set s) {
+        super.method(s);  //ERROR: Abstract method 'method(Set<?>)' cannot be accessed directly
+    }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardIsNotWithinItsBound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardIsNotWithinItsBound.java
new file mode 100644
index 0000000..8035e37
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardIsNotWithinItsBound.java
@@ -0,0 +1,20 @@
+
+class TopGene<T> {
+}
+
+class MidRaw extends TopGene {
+}
+
+class BottomGene<T> extends MidRaw {
+}
+
+class GeneType<T extends TopGene<String>> {
+}
+
+class GeneUser {
+  public void success(GeneType<? extends BottomGene<String>> p) {
+  }
+
+  public void fail(GeneType<<error descr="Type parameter '? super BottomGene<String>' is not within its bound; should extend 'TopGene<java.lang.String>'">? super BottomGene<String></error>> p) {
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ThisAsAccessObject.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ThisAsAccessObject.java
new file mode 100644
index 0000000..ea3ecf0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ThisAsAccessObject.java
@@ -0,0 +1,9 @@
+class Outer {
+    private void foo() {}
+    class Inner extends Outer {
+        {
+           this.<error descr="'foo()' has private access in 'Outer'">foo</error>();
+           foo();
+        }
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgsOnRaw.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgsOnRaw.java
new file mode 100644
index 0000000..f8e48b2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgsOnRaw.java
@@ -0,0 +1,21 @@
+class GenericsTest {
+
+    static class SomeClass<U> {
+        public <T> T getX() {
+            return null;
+        }
+        public String f() {
+            return this.<String>getX();
+        }
+    }
+
+
+
+    public static void main(String[] args) {
+
+        String v1 = new SomeClass().<error descr="Type arguments given on a raw method"><String></error>getX();
+        String v2 = new SomeClass().f();  //
+
+    }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsGivenOnAnonymousClassCreation.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsGivenOnAnonymousClassCreation.java
new file mode 100644
index 0000000..249c3ae
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsGivenOnAnonymousClassCreation.java
@@ -0,0 +1,12 @@
+class C
+{
+    Object x = new <error descr="Anonymous class implements interface; cannot have type arguments"><Integer></error> D() { };
+    Object x1 = new <Integer> P() { };
+    Object x2 = new <Integer> U() { };
+    Object x3 = new <error descr="Anonymous class implements interface; cannot have type arguments"><Integer></error> I() { };
+    interface D{}
+    abstract class P {}
+}
+
+interface I {}
+class U {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsGivenOnRawType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsGivenOnRawType.java
new file mode 100644
index 0000000..09ff35b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsGivenOnRawType.java
@@ -0,0 +1,49 @@
+import java.util.List;
+class A<D> {
+  abstract class C<S> {
+    <T extends A> void foo(T.C<Integer> x) {
+      Integer bar = x.bar();
+    }
+
+    <T extends A> void foo1(A.C<error descr="Type arguments given on a raw type"><Integer></error> x) {
+      Integer bar = x.bar();
+    }
+
+    <T extends A> void foo2(A<String>.C<Integer> x) {
+      Integer bar = x.bar();
+    }
+
+    abstract S bar();
+  }
+}
+
+class A1 {
+  abstract class C<S> {
+    <T extends A1> void foo(T.C<Integer> x) {
+      Integer bar = x.bar();
+    }
+
+    <T extends A1> void foo1(A1.C<Integer> x) {
+      Integer bar = x.bar();
+    }
+
+    abstract S bar();
+  }
+}
+
+interface Builder<T> {
+    T build();
+}
+
+interface Test<D extends Test<D, X>, X> {
+    static interface TestBuilder<D extends Test<D, X>, X> extends Builder<D> {}
+}
+
+interface Algorithm<T, B extends Builder<T>> {}
+
+class SelectFromVariableType<X, T extends Test<T, X>>
+        implements Algorithm<T, <error descr="Cannot select from a type parameter">T</error>.TestBuilder<T, X>> {
+
+    List<T.TestBuilder<T, X>> b;
+    T.TestBuilder<T, X> b1;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsOnRawType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsOnRawType.java
new file mode 100644
index 0000000..7f38140
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsOnRawType.java
@@ -0,0 +1,43 @@
+interface I{
+    <T extends Iterable<String>> void foo();
+}
+
+abstract class A<S> implements I {
+    public abstract <T extends Iterable<String>> void foo();
+    <T extends A> void bar(T x){
+        A a = null;
+        a.<Iterable<String>> foo();
+        x.<Iterable<String>> foo();
+    }
+}
+
+abstract class B<S> {
+    public abstract <T extends Iterable<String>> void foo();
+    <T extends B> void bar(T x){
+        B a = null;
+        a.<Iterable<String>>foo();
+        x.<Iterable<String>> foo();
+    }
+}
+
+abstract class C<S> {
+    public abstract <T extends Iterable<String>> void foo();
+    <T extends C & I> void bar(T x){
+        x.<Iterable<String>> foo();
+    }
+}
+
+//---------------------------------------------------------------
+interface I1 {
+    void foo();
+}
+
+
+abstract class B1<S> {
+    public abstract <T extends Iterable<String>> void foo();
+    <T extends B1 & I1> void bar(T x){
+        B1 a = null;
+        a.<Iterable<String>>foo();
+        x.<Iterable<String>>foo();
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsOnRawType17.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsOnRawType17.java
new file mode 100644
index 0000000..f586b18
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsOnRawType17.java
@@ -0,0 +1,43 @@
+interface I{
+    <T extends Iterable<String>> void foo();
+}
+
+abstract class A<S> implements I {
+    public abstract <T extends Iterable<String>> void foo();
+    <T extends A> void bar(T x){
+        A a = null;
+        a.<Iterable<String>> foo();
+        x.<Iterable<String>> foo();
+    }
+}
+
+abstract class B<S> {
+    public abstract <T extends Iterable<String>> void foo();
+    <T extends B> void bar(T x){
+        B a = null;
+        a.<error descr="Type arguments given on a raw method"><Iterable<String>></error> foo();
+        x.<Iterable<String>> foo();
+    }
+}
+
+abstract class C<S> {
+    public abstract <T extends Iterable<String>> void foo();
+    <T extends C & I> void bar(T x){
+        x.<Iterable<String>> foo();
+    }
+}
+
+//---------------------------------------------------------------
+interface I1 {
+    void foo();
+}
+
+
+abstract class B1<S> {
+    public abstract <T extends Iterable<String>> void foo();
+    <T extends B1 & I1> void bar(T x){
+        B1 a = null;
+        a.<error descr="Type arguments given on a raw method"><Iterable<String>></error> foo();
+        x.<Iterable<String>> foo();
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeInference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeInference.java
new file mode 100644
index 0000000..0156c75
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeInference.java
@@ -0,0 +1,95 @@
+import java.io.FileNotFoundException;
+import java.util.*;
+
+interface PrivilegedExceptionAction <E extends Exception> {
+    void run() throws E;
+}
+
+class AccessController {
+    public static <E extends Exception> Object doPrivileged(PrivilegedExceptionAction<E> action) throws E {
+        return null;
+    }
+}
+class Test {
+    public static void main(String[] args) {
+        try {
+            AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<FileNotFoundException>() {
+                        public void run() throws FileNotFoundException {
+                        }
+                    });
+        } catch (FileNotFoundException f) {
+        }
+    }
+
+// @#@! mock JDK Class does not take params
+//    static <T> T create(Class<T> t) throws InstantiationException, IllegalAccessException {
+//        return t.newInstance();
+//    }
+}
+
+//IDEADEV-6390
+class Printer<T> {
+    private final List<T> _elements;
+
+    private Printer(final Collection<? extends T> col) {
+        _elements = new ArrayList<T>(col);
+    }
+
+    public static <T> Printer<T> build(final Collection<? extends T> col) {
+        return new Printer<T>(col);
+    }
+
+    public static <T, S extends T> Printer<T> build(final S... elements) {
+        return new Printer<T>(Arrays.asList(elements));
+    }
+
+    public void print() {
+        for (final T element : _elements) {
+            System.out.println(element);
+        }
+
+    }
+
+    public static void main(final String[] args) {
+        final Printer<?> objects =  build(Integer.valueOf(5), Boolean.TRUE, "A String!"); //this is OK
+         objects.print();
+    }
+
+}
+//end of IDEADEV-6390
+
+//IDEADEV-6738
+interface I1<P1 extends I1<P1,P2>, P2 extends I2<P1,P2>>{}
+interface I2<P1 extends I1<P1,P2>, P2 extends I2<P1,P2>>{}
+
+class C1 implements I1<C1,C2>{}
+class C2 implements I2<C1,C2>{}
+
+class U {
+    public static <P1 extends I1<P1,P2>, P2 extends I2<P1,P2>> P1 test(P1 p1) {
+        return null;
+    }
+    {
+        C1 c = new C1();
+        U.test(c); //this should be OK
+    }
+}
+//end of IDEADEV-6738
+
+///////////////////////////////////
+public class Err {
+    void f() {
+        Decl[] extensions = getExtensions(Decl.EXTENSION_POINT_NAME);
+    }
+
+    static <T> T[] getExtensions(List<T> tExtensionPointName) {
+        return null;
+    }
+
+    public static class Decl<K,V> {
+        public static List<Decl> EXTENSION_POINT_NAME = null;
+    }
+
+}
+/////////////////////////////////////
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParameterBoundVisibility.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParameterBoundVisibility.java
new file mode 100644
index 0000000..68c2337
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParameterBoundVisibility.java
@@ -0,0 +1,50 @@
+class A {
+   private int value = 1;
+
+   static class B<T extends A> {
+      void print(T t) {
+         System.out.println(t.<error descr="'value' has private access in 'A'">value</error>);
+      }
+   }
+}
+
+abstract class Foo<T extends Foo<T>> {
+    private int field;
+
+    public int bar(T t){
+        return t.<error descr="'field' has private access in 'Foo'">field</error>;
+    }
+}
+
+public class Bug {
+  // Idea incorrectly analyses this code with JDK 7
+  public <T extends Bug> void doit(T other) {
+    // Oops, was legal with JDK 6, no longer legal with JDK 7
+    other.<error descr="'mPrivate()' has private access in 'Bug'">mPrivate</error>();
+    // Redundant with JDK 6, not a redundant cast with JDK 7
+    ((Bug)other).mPrivate();
+  }
+
+  // Idea correctly analyses this code
+  public void doit2(SubClass other) {
+    // Not legal with JDK 6 or 7
+    other.<error descr="'mPrivate()' has private access in 'Bug'">mPrivate</error>();
+    // Not redundant with JDK 6 or 7
+    ((Bug)other).mPrivate();
+  }
+
+  private void mPrivate() {
+  }
+}
+
+class SubClass extends Bug {
+}
+
+class A67678
+{
+      private void foo(){}
+      <T extends A67678 & Cloneable> void bar(T x)
+      {
+          x.<error descr="'foo()' has private access in 'A67678'">foo</error>();
+      }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParameterBoundsList.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParameterBoundsList.java
new file mode 100644
index 0000000..506add0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParameterBoundsList.java
@@ -0,0 +1,33 @@
+class C<T extends Runnable&<error descr="Interface expected here">Exception</error>,U> {
+
+}
+
+class Stuff<X extends Stuff & Runnable> {
+    <T, V extends T & <error descr="Type parameter cannot be followed by other bounds">Runnable</error>> T method(V v) {
+        return null;
+    }
+
+    <T extends X & <error descr="Type parameter cannot be followed by other bounds">Runnable</error> & <error descr="Type parameter cannot be followed by other bounds">Comparable</error>> void f(T t) {
+
+    }
+
+    <T extends Stuff & Runnable & Comparable> void f2(T t) {
+
+    }
+    <T extends Runnable & Comparable> void f3(T t) {
+
+    }
+}
+
+////////////////
+public class TypeParameters {
+    class X {}
+    static <T extends X> void f(Class<T> t){}
+
+    static {
+        f(X.class);
+    }
+}
+class Typr {
+  <T extends TypeParameters.X> void f() {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParamsCyclicInference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParamsCyclicInference.java
new file mode 100644
index 0000000..a560911
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParamsCyclicInference.java
@@ -0,0 +1,2 @@
+class Test<<error descr="Cyclic inheritance involving 'T'"></error>T extends T> {}
+class Test1<<error descr="Cyclic inheritance involving 'T'"></error>T extends S, S extends T> {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeWithinItsWildcardBound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeWithinItsWildcardBound.java
new file mode 100644
index 0000000..47ecb3b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeWithinItsWildcardBound.java
@@ -0,0 +1,317 @@
+public class WithingBounds {
+    interface I {
+    }
+    interface I1 {
+    }
+
+    void testE1() {
+        class A {
+        }
+        class B extends A {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<? extends B> pr;
+    }
+
+    void testERec1() {
+        class A {
+        }
+        class B<K> extends A {
+        }
+        class C<Y>{}
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<<error descr="Type parameter '? extends C<? extends C>' is not within its bound; should extend 'A'">?  extends C<? extends C></error>> pr;
+        ToCheckExtends<? extends B<? extends C>> pr1;
+    }
+
+
+    void testE2() {
+        class A {
+        }
+        class B {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<<error descr="Type parameter '? extends B' is not within its bound; should extend 'A'">? extends B</error>> pr;
+    }
+
+    void testE22() {
+        class B {
+        }
+        class A extends B {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<? extends B> pr;
+    }
+
+
+    void testE23() {
+        class A {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<? extends I> pr;
+    }
+
+    void testE24() {
+        final class A {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<<error descr="Type parameter '? extends I' is not within its bound; should extend 'A'">? extends I</error>> pr;
+    }
+
+
+    void testE25() {
+      class B {
+        void foo() {
+          this.<Iterable>bar();
+        }
+
+        <T extends Iterable<String>> void bar() {
+        }
+      }
+    }
+
+    void testE26() {
+      class A<T>{}
+      class B {
+        void foo() {
+          this.<A>bar();
+        }
+
+        <T extends A<String>> void bar() {
+        }
+      }
+    }
+
+  //---------------------------------
+
+    void testE3() {
+        class A {
+        }
+        class ToCheckExtends<TTT extends I> {
+        }
+
+        ToCheckExtends<? extends A> pr;
+    }
+
+    void testE4() {
+        final class A {
+        }
+        class ToCheckExtends<TTT extends I> {
+        }
+
+        ToCheckExtends<<error descr="Type parameter '? extends A' is not within its bound; should extend 'WithingBounds.I'">? extends A</error>> pr;
+    }
+
+    void testE5() {
+        final class A implements I {
+        }
+        class ToCheckExtends<TTT extends I> {
+        }
+
+        ToCheckExtends<? extends A> pr;
+    }
+
+
+    interface AInterface {
+    }
+    void testE6() {
+
+        class ToCheckExtends<TTT extends I> {
+        }
+
+        ToCheckExtends<? extends AInterface> pr;
+    }
+
+    //-----------------------------
+
+    void testS1() {
+        class A {
+        }
+        class B extends A {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<? super B> pr;
+    }
+
+    void testS2() {
+        class A {
+        }
+        class B {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<<error descr="Type parameter '? super B' is not within its bound; should extend 'A'">? super B</error>> pr;
+    }
+
+    void testS3() {
+        class A {
+        }
+        class B extends A {
+        }
+        class ToCheckExtends<TTT extends B> {
+        }
+
+        ToCheckExtends<<error descr="Type parameter '? super A' is not within its bound; should extend 'B'">? super A</error>> pr;
+    }
+
+  void testMisc() {
+     class A<T, S extends T> {}
+     class i {}
+     final class ii extends i {}
+
+     A<String, String> pr4;
+     A<Integer, <error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Integer'">String</error>> pr5;
+     A<String, ? extends String> pr51;
+     A<Integer, <error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Integer'">? extends String</error>> pr52;
+     A<String, ? super String> pr53;
+     A<ii, <error descr="Type parameter 'i' is not within its bound; should extend 'ii'">i</error>> pr54;
+     A<i, ii> pr55;
+     A<i, ? extends ii> pr56;
+     A<ii, ? extends i> pr57;
+     A<i, ? super ii> pr58;
+     A<ii, <error descr="Type parameter '? super i' is not within its bound; should extend 'ii'">? super i</error>> pr59;
+     A<i, <error descr="Type parameter '? extends A<i, i>' is not within its bound; should extend 'i'">? extends A<i, i></error>> pr510;
+     A<i, <error descr="Type parameter 'ii[]' is not within its bound; should extend 'i'">ii[]</error>> pr511;
+     A<i, ?> pr512;
+
+     A<?, ?> pr30;
+     A<?, <error descr="Type parameter 'i' is not within its bound; should extend '?'">i</error>> pr3;
+     A<? extends Object, i> pr330;
+     A<?, ? extends ii> pr2;
+     A<?, <error descr="Type parameter '? super String' is not within its bound; should extend '?'">? super String</error>> pr10;
+     A<?, <error descr="Type parameter 'A' is not within its bound; should extend '?'">A<?, ?></error>> pr31;
+     A<?, <error descr="Type parameter 'ii[]' is not within its bound; should extend '?'">ii[]</error>> pr32;
+     A<?, <error descr="Type parameter 'A' is not within its bound; should extend '?'">A<i, i></error>> pr33;
+
+     A<? extends i, i> pr6;
+     A<? extends ii, <error descr="Type parameter 'i' is not within its bound; should extend '? extends ii'">i</error>> pr6x1;
+     A<? extends i, ii> pr6x2;
+     A<? extends ii, ii> pr6x3;
+     A<? extends i, <error descr="Type parameter 'java.lang.Integer' is not within its bound; should extend '? extends i'">Integer</error>> pr8;
+
+     A<? extends i, <error descr="Type parameter '? extends String' is not within its bound; should extend '? extends i'">? extends String</error>> pr12;
+     A<? extends i, ? extends i> pr13;
+     A<? extends i, ? extends ii> pr14;
+     A<? extends ii, ? extends i> pr13x3;
+     A<? extends ii, ? extends ii> pr13x4;
+
+
+     A<? extends i, ? super i> pr19;
+     A<? extends i, ? super ii> pr110;
+     A<? extends ii, ? super ii> pr11x0;
+     A<? extends ii, <error descr="Type parameter '? super i' is not within its bound; should extend '? extends ii'">? super i</error>> pr111;
+
+     A<? extends i, ?> pr15;
+     A<? extends i, <error descr="Type parameter 'ii[]' is not within its bound; should extend '? extends i'">ii[]</error>> pr16;
+     A<? extends i, <error descr="Type parameter 'A' is not within its bound; should extend '? extends i'">A<?, ?></error>> pr17;
+     A<? extends i, <error descr="Type parameter 'A' is not within its bound; should extend '? extends i'">A<ii, ii></error>> pr18;
+     A<? extends ii, <error descr="Type parameter '? super String' is not within its bound; should extend '? extends ii'">? super String</error>> pr112;
+     A<? extends ii, <error descr="Type parameter '? super A<i, i>' is not within its bound; should extend '? extends ii'">? super A<i, i></error>> pr113;
+
+     A<? super i, i> pr701;
+     A<? super i, <error descr="Type parameter 'java.lang.String' is not within its bound; should extend '? super i'">String</error>> pr72;
+     A<? super i, ?> pr73;
+     A<? super i, <error descr="Type parameter 'ii[]' is not within its bound; should extend '? super i'">ii[]</error>> pr74;
+     A<? super i, <error descr="Type parameter '? extends String' is not within its bound; should extend '? super i'">? extends String</error>> pr75;
+     A<? super i, ? extends i> pr76;
+     A<? super ii, ? extends i> pr77;
+     A<? super ii, ? extends ii> pr78;
+     A<? super i, ? super i> pr79;
+     A<? super i, ? super ii> pr791;
+     A<? super ii, ? super ii> pr713;
+     A<? super i, <error descr="Type parameter '? super String' is not within its bound; should extend '? super i'">? super String</error>> pr712;
+     A<? super ii, <error descr="Type parameter '? super i' is not within its bound; should extend '? super ii'">? super i</error>> pr710;
+     A<? super  ii, <error descr="Type parameter 'i' is not within its bound; should extend '? super ii'">i</error>> pr70;
+     A<? super i, ii> pr71;
+     A<? super i, ? extends ii> pr711;
+
+     A<i[], i[]> a1;
+     A<i[], <error descr="Type parameter 'java.lang.Object' is not within its bound; should extend 'i[]'">Object</error>> a2;
+     A<i[], ii[]> a3;
+     A<ii[], <error descr="Type parameter 'i[]' is not within its bound; should extend 'ii[]'">i[]</error>> a4;
+
+     A<i[], <error descr="Type parameter 'int[]' is not within its bound; should extend 'i[]'">int[]</error>> a5;
+     A<Object, int[]> a6;
+     A<Cloneable, int[]> a7;
+     A<java.io.Serializable, int[]> a8;
+     A<Cloneable[], <error descr="Type parameter 'int[]' is not within its bound; should extend 'java.lang.Cloneable[]'">int[]</error>> a9;
+     A<Cloneable[], int[][]> a10;
+     A<Cloneable[][], int[][][]> a11;
+     A<Cloneable[], <error descr="Type parameter 'i[]' is not within its bound; should extend 'java.lang.Cloneable[]'">i[]</error>> a12;
+     A<Cloneable[], i[][]> a13;
+
+     A<? super i[], ii[]> a14;
+     A<? super i[], i[]> a140;
+     A<? super ii[], <error descr="Type parameter 'i[]' is not within its bound; should extend '? super ii[]'">i[]</error>> a141;
+     A<? super i[], <error descr="Type parameter 'i' is not within its bound; should extend '? super i[]'">i</error>> a142;
+     A<? super i[], <error descr="Type parameter 'java.lang.String' is not within its bound; should extend '? super i[]'">String</error>> a143;
+     A<? super i[], <error descr="Type parameter 'i[][]' is not within its bound; should extend '? super i[]'">i[][]</error>> a144;
+     A<? super i[], ? extends i[]> a145;
+     A<? super i[], ? extends ii[]> a146;
+     A<? super ii[], ? extends i[]> a147;
+     A<? super i[], <error descr="Type parameter '? extends i' is not within its bound; should extend '? super i[]'">? extends i</error>> a148;
+     A<? super i[], <error descr="Type parameter '? extends String' is not within its bound; should extend '? super i[]'">? extends String</error>> a149;
+     A<? super i[], ?> a1410;
+     A<? super i[], <error descr="Type parameter '? extends i[][]' is not within its bound; should extend '? super i[]'">? extends i[][]</error>> a1411;
+     A<? super i[], ? super i[]> a1412;
+     A<? super i[], ? super ii[]> a1413;
+     A<? super ii[], <error descr="Type parameter '? super i[]' is not within its bound; should extend '? super ii[]'">? super i[]</error>> a1414;
+     A<? super i[], <error descr="Type parameter '? super i' is not within its bound; should extend '? super i[]'">? super i</error>> a1415;
+     A<? super i[], <error descr="Type parameter '? super String' is not within its bound; should extend '? super i[]'">? super String</error>> a1416;
+     A<? super i[], <error descr="Type parameter '? super i[][]' is not within its bound; should extend '? super i[]'">? super i[][]</error>> a1417;
+
+      A<? extends i[], ii[]> a15;
+      A<? extends i[], i[]> a150;
+      A<? extends ii[],<error descr="Type parameter 'i[]' is not within its bound; should extend '? extends ii[]'">i[]</error>> a151;
+      A<? extends i[], <error descr="Type parameter 'i' is not within its bound; should extend '? extends i[]'">i</error>> a152;
+      A<? extends i[], <error descr="Type parameter 'java.lang.String' is not within its bound; should extend '? extends i[]'">String</error>> a153;
+      A<? extends i[], <error descr="Type parameter 'i[][]' is not within its bound; should extend '? extends i[]'">i[][]</error>> a154;
+      A<? extends i[], ? extends i[]> a155;
+      A<? extends i[], ? extends ii[]> a156;
+      A<? extends ii[], ? extends i[]> a157;
+      A<? extends i[], <error descr="Type parameter '? extends i' is not within its bound; should extend '? extends i[]'">? extends i</error>> a158;
+      A<? extends i[], <error descr="Type parameter '? extends String' is not within its bound; should extend '? extends i[]'">? extends String</error>> a159;
+      A<? extends i[], ?> a1510;
+      A<? extends i[], <error descr="Type parameter '? extends i[][]' is not within its bound; should extend '? extends i[]'">? extends i[][]</error>> a1511;
+      A<? extends i[], ? super i[]> a1512;
+      A<? extends i[], ? super ii[]> a1513;
+      A<? extends ii[], <error descr="Type parameter '? super i[]' is not within its bound; should extend '? extends ii[]'">? super i[]</error>> a1514;
+      A<? extends i[], <error descr="Type parameter '? super i' is not within its bound; should extend '? extends i[]'">? super i</error>> a1515;
+      A<? extends i[], <error descr="Type parameter '? super String' is not within its bound; should extend '? extends i[]'">? super String</error>> a1516;
+      A<? extends i[], <error descr="Type parameter '? super i[][]' is not within its bound; should extend '? extends i[]'">? super i[][]</error>> a1517;
+
+    A<? extends Cloneable, ? extends i[]> a16;
+    A<? extends Cloneable[], ? extends i[][]> a160;
+    A<Cloneable, ? extends i[]> a161;
+    A<? super Cloneable, ? extends i[]> a162;
+    A< I1[], ? extends  I[]> cl;
+
+  }
+
+  void testRawTypes() {
+    class A<T extends A<T>> {}
+    A a;
+    A<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'A<java.lang.String>'">String</error>> a1;
+    A<<error descr="Type parameter 'A' is not within its bound; should extend 'A<A>'">A</error>> a2;
+    A<A<<error descr="Type parameter 'A' is not within its bound; should extend 'A<A>'">A</error>>> a3;
+
+    A<? extends A> a4;
+    A<<error descr="Type parameter '? super A' is not within its bound; should extend 'A<? super A>'">? super A</error>> a5;
+    A<<error descr="Type parameter 'A[]' is not within its bound; should extend 'A<A[]>'">A[]</error>> a7;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedCasts.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedCasts.java
new file mode 100644
index 0000000..0532d1f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedCasts.java
@@ -0,0 +1,108 @@
+import java.util.*;
+
+class X<<warning descr="Type parameter 'T' is never used">T</warning>> {
+
+}
+
+class XX<T> extends X<T> {
+  Object f(X<String> x) {
+    if (x != null) {
+      XX<String> xx = <warning descr="Unchecked cast: 'XX' to 'XX<java.lang.String>'">(XX<String>)new XX()</warning>;
+      return xx;
+    }
+    if (1 == 1) {
+      XX<String> xx = (XX<String>)x;
+      return xx;
+    }
+    return null;
+  }
+}
+
+class eee<COMP extends eee> {
+    COMP comp;
+    COMP foo() {
+        return <warning descr="Unchecked cast: 'eee' to 'COMP'">(COMP) new eee()</warning>;
+    }
+}
+
+class AllPredicate<T>
+    {
+    private List<Set<? super T>> lists;
+
+    public void e(AllPredicate that)
+    {
+         lists = <warning descr="Unchecked cast: 'java.util.List' to 'java.util.List<java.util.Set<? super T>>'">(List<Set<? super T>>)that.lists</warning>;
+    }
+
+    public static List<String> fff() {
+        Collection<String> c = new ArrayList<String>();
+        return (List<String>) c; //not unchecked
+    }
+
+    public static Comparable<Object> ggg() {
+        Object time = new Object();
+        return <warning descr="Unchecked cast: 'java.lang.Object' to 'java.lang.Comparable<java.lang.Object>'">(Comparable<Object>) time</warning>;
+    }
+
+    public static void foo(SortedMap<?, ?> sourceSortedMap) {
+        new TreeMap<Object, Object>(<warning descr="Unchecked cast: 'java.util.Comparator<capture<?>>' to 'java.util.Comparator<? super java.lang.Object>'">(Comparator<? super Object>) sourceSortedMap.comparator()</warning>);
+    }
+}
+
+class K { }
+class L extends K { }
+class M {
+  public static <T extends K> L f(T t) {
+     return (L) t; //this should NOT generate unchecked cast
+  }
+}
+
+class UncheckedCastFalsePositive {
+
+    public static void method(Object something) {
+        if (something instanceof NumberList) {
+            NumberList<? extends Number> <warning descr="Variable 'numberList' is never used">numberList</warning> = (NumberList<?  extends Number>) something;
+        }
+
+    }
+
+    public static class NumberList<E extends Number> extends ArrayList<E> {
+    }
+
+}
+
+class IDEA21547 {
+  class O {}
+  class A<<warning descr="Type parameter 'T' is never used">T</warning>> {}
+  class B<K extends O> extends A<K>{}
+
+  public void bar(A<? extends O> a, B<O> b) {
+    b = <warning descr="Unchecked cast: 'IDEA21547.A<capture<? extends IDEA21547.O>>' to 'IDEA21547.B<IDEA21547.O>'">(B<O>)a</warning>;
+    System.out.println(b);
+  }
+
+  public void bar1(A<?> a, B<O> b) {
+    b = <warning descr="Unchecked cast: 'IDEA21547.A<capture<?>>' to 'IDEA21547.B<IDEA21547.O>'">(B<O>)a</warning>;
+    System.out.println(b);
+  }
+
+  public void bar2(A<?> a, B<?> b) {
+    b = <warning descr="Unchecked cast: 'IDEA21547.A<capture<?>>' to 'IDEA21547.B<IDEA21547.O>'">(B<O>)a</warning>;
+    System.out.println(b);
+  }
+
+  public void bar4(A<? extends O> a, B<?> b) {
+    b = <warning descr="Unchecked cast: 'IDEA21547.A<capture<? extends IDEA21547.O>>' to 'IDEA21547.B<IDEA21547.O>'">(B<O>)a</warning>;
+    System.out.println(b);
+  }
+
+  public void bar5(A<? super O> a, B<?> b) {
+    b = <warning descr="Unchecked cast: 'IDEA21547.A<capture<? super IDEA21547.O>>' to 'IDEA21547.B<IDEA21547.O>'">(B<O>)a</warning>;
+    System.out.println(b);
+  }
+
+  public void bar6(A a, B<?> b) {
+    b = <warning descr="Unchecked cast: 'IDEA21547.A' to 'IDEA21547.B<IDEA21547.O>'">(B<O>)a</warning>;
+    System.out.println(b);
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedOverriding.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedOverriding.java
new file mode 100644
index 0000000..9f71e16b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedOverriding.java
@@ -0,0 +1,45 @@
+class List<T> { T t;}
+
+class Base<T> {
+    List<T> getList(List<T> l) {
+        return null;
+    }
+
+
+}
+
+class Derived extends Base <String> {
+    <warning descr="Unchecked overriding: return type requires unchecked conversion. Found 'List', required 'List<java.lang.String>'">List</warning> getList(List<String> l) {
+        return null;
+    }
+}
+
+class A1 {
+    <T> T foo(T t) {
+        return null;
+    }
+}
+
+class A2 extends A1 {
+    <warning descr="Unchecked overriding: return type requires unchecked conversion. Found 'java.lang.Object', required 'T'">Object</warning> foo(Object o) {
+        return null;
+    }
+}
+
+//IDEADEV-15918
+abstract class Outer<U> {
+    public abstract Inner m(U u);
+
+    public class Inner {
+    }
+}
+
+class Other extends Outer<Other> {
+    public Ither m(Other other) {
+        return new Ither();
+    }
+
+    public class Ither extends Inner {
+    }
+}
+//end of IDEADEV-15918
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedWarningsLevel6.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedWarningsLevel6.java
new file mode 100644
index 0000000..e9ff21b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedWarningsLevel6.java
@@ -0,0 +1,128 @@
+import java.lang.Override;
+import java.util.*;
+class GenericsTest<T> {
+
+    static <S> S next(GenericsTest<S> test)
+    {
+        System.out.println(test);
+        return null;
+    }
+
+    public Iterator<T> iterator()
+    {
+        return new Iterator<T>() {
+            @Override
+            public boolean hasNext()
+            {
+                return false;
+            }
+
+            @Override
+            public T next()
+            {
+                return GenericsTest.next(GenericsTest.this);
+            }
+
+            @Override
+            public void remove()
+            {
+            }
+        };
+    }
+}
+
+class GenericsTest1<T> {
+
+    static <S> S next1(GenericsTest1<S> test)
+    {
+        System.out.println(test);
+        return null;
+    }
+
+    public Iterator<T> iterator()
+    {
+        return new Iterator<T>() {
+            @Override
+            public boolean hasNext()
+            {
+                return false;
+            }
+
+            @Override
+            public T next()
+            {
+                return GenericsTest1.next1(GenericsTest1.this);
+            }
+
+            @Override
+            public void remove()
+            {
+            }
+        };
+    }
+}
+
+
+class GenericsTest2<T> {
+
+    static <S> S next2(GenericsTest2<S> test)
+    {
+        System.out.println(test);
+        return null;
+    }
+
+    public Iterator<T> iterator()
+    {
+        return new Iterator<T>() {
+            @Override
+            public boolean hasNext()
+            {
+                return false;
+            }
+
+            @Override
+            public T next()
+            {
+                return next2(GenericsTest2.this);
+            }
+
+            @Override
+            public void remove()
+            {
+            }
+        };
+    }
+}
+class Example {
+    private static <T> void assertThat(T actual, Matcher<? super T> matcher) {
+      assert actual != null;
+      assert matcher != null;
+    }
+
+    private static <E> Matcher<? super Collection<? extends E>> hasSize(int size) {
+        assert size >=0;
+        return new Matcher<Collection<? extends E>>() {
+          @Override
+          public void foo(Collection<? extends E> es) {
+            System.out.println(es);
+          }
+        };
+    }
+
+    public static void main(String[] args) {
+      List<Boolean> list = <warning descr="Unchecked assignment: 'java.util.ArrayList' to 'java.util.List<java.lang.Boolean>'">new ArrayList()</warning>;
+      System.out.println(list);
+      assertThat(new ArrayList<Boolean>(), hasSize(0));
+    }
+
+    private interface Matcher<T> {
+      void foo(T t);
+    }
+}
+
+abstract class IDEA57337<<warning descr="Type parameter 'S' is never used">S</warning>> {
+    abstract <T> void foo(IDEA57337<? super IDEA57337<T>> x);
+    void bar(IDEA57337<? super IDEA57337<?>> x){
+        foo(x);
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Unused.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Unused.java
new file mode 100644
index 0000000..7b75df1
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Unused.java
@@ -0,0 +1,11 @@
+enum e {
+  A("xxx");
+
+  private String s;
+  e(String str) {
+    s = str;
+  }
+  public String getS() {
+    return s;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Varargs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Varargs.java
new file mode 100644
index 0000000..5ba94fb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Varargs.java
@@ -0,0 +1,33 @@
+class clazz1 {
+    clazz1(int... args) { args = null; }
+    public static class Myclazz1 extends clazz1 {}
+}
+
+class AmbiguousReference {
+  void test() {
+    doSomething<error descr="Ambiguous method call: both 'AmbiguousReference.doSomething(String, Number...)' and 'AmbiguousReference.doSomething(Number...)' match">(null, 1)</error>;
+  }
+
+  void doSomething(String s, Number... n) {
+    s+=n;
+  }
+
+  void doSomething(Number... n) {
+    n.hashCode();
+  }
+}
+
+class OK {
+    protected void fff() {
+        find("");
+    }
+    public void find(String queryString)  {
+       queryString.hashCode();
+    }
+
+    public void find(final String queryString, final Object... values)  {
+       queryString.hashCode();
+       values.hashCode();
+    }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java
new file mode 100644
index 0000000..67f89f9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java
@@ -0,0 +1,285 @@
+import java.util.*;
+import java.util.Comparator;
+
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dsl
+ * Date: Mar 25, 2004
+ * Time: 8:08:44 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class VarianceTesting {
+    void method(List<? extends VarianceTesting> l) {
+//        l.add(new VarianceTesting());
+        l.add(null);
+    }
+
+    static void shuffle(Collection<?> c) {}
+
+    static class X<T> {
+        T field;
+        T[] arrayField;
+        T[] method() {return  arrayField;};
+        void putAll(Collection<? super T> c) {}
+    }
+
+    void method1(List<? super VarianceTesting> l) {
+        List<? extends VarianceTesting> l1 = new ArrayList<VarianceTesting>();
+        l1.add<error descr="'add(capture<? extends VarianceTesting>)' in 'java.util.List' cannot be applied to '(VarianceTesting)'">(new VarianceTesting())</error>;
+        List<List<? extends VarianceTesting>> lll = null;
+        lll.add(l1);
+        X<? extends VarianceTesting> x = new X<VarianceTesting>();
+        VarianceTesting z = x.field;
+        VarianceTesting[] v = x.arrayField;
+        VarianceTesting v1 = x.arrayField[0];
+        x.arrayField[0] = new VarianceTesting();
+        <error descr="Incompatible types. Found: 'VarianceTesting', required: 'capture<? extends VarianceTesting>'">x.field = new VarianceTesting()</error>;
+        VarianceTesting[] k = x.method();
+        k[0] = new VarianceTesting();
+        x.method()[0] = new VarianceTesting();
+        <error descr="Incompatible types. Found: 'VarianceTesting[]', required: 'capture<? extends VarianceTesting>[]'">x.arrayField = new VarianceTesting[10]</error>;
+        l1.addAll<error descr="'addAll(java.util.Collection<capture<? extends VarianceTesting>>)' in 'java.util.List' cannot be applied to '(java.util.ArrayList<VarianceTesting>)'">(new ArrayList<VarianceTesting>())</error>;
+        <error descr="Incompatible types. Found: 'java.util.ArrayList<java.lang.String>', required: 'java.util.List<? extends VarianceTesting>'">List<? extends VarianceTesting> l2 = new ArrayList<String>();</error>
+        List<? extends VarianceTesting> l3 = l2;
+        VarianceTesting t = l1.get(0);
+        l.add(new VarianceTesting());
+        l.add(null);
+        <error descr="Incompatible types. Found: 'java.lang.Object', required: 'VarianceTesting'">VarianceTesting t1 = l.get(0);</error>
+        X<? extends VarianceTesting> x1 = null;
+        x1.putAll(new ArrayList<VarianceTesting>());
+        List<?> unknownlist = l;
+        List<?> unknownlist1 = new ArrayList<VarianceTesting>();
+        List<?> unknownlist2 = new ArrayList<<error descr="Wildcard type '?' cannot be instantiated directly">?</error>>();
+        shuffle(l);
+        shuffle(new ArrayList<VarianceTesting>());
+        List<VarianceTesting> lllll = new ArrayList<VarianceTesting>();
+        lllll.removeAll(new ArrayList<String>());
+    }
+
+}
+
+class SuperTester <U> {
+     void go(Acceptor<? super U> acceptor, U u) {
+          acceptor.accept<error descr="'accept(SuperTester<capture<? super U>>, capture<? super U>)' in 'SuperTester.Acceptor' cannot be applied to '(SuperTester<U>, U)'">(this, u)</error>;
+     }
+
+     static class Acceptor <V> {
+          void accept(SuperTester<V> tester, V v) { }
+     }
+}
+
+class SCR40202 {
+    void foo(Map<?, String> map) {
+        for (<error descr="Incompatible types. Found: 'java.util.Iterator<java.util.Map.Entry<capture<?>,java.lang.String>>', required: 'java.util.Iterator<java.util.Map.Entry<?,java.lang.String>>'">Iterator<Map.Entry<?, String>> it = map.entrySet().iterator();</error> it.hasNext();) {
+
+        }
+    }
+}
+
+class CaptureTest {
+   static class Emum<T> {
+      T t;
+      public static <T extends Emum<T>> T valueOf(Class<T> enumType,
+                                                String name) {
+                                                return null;
+      }
+   }
+
+   void foo (Class<? extends Emum<CaptureTest>> clazz) {
+     Emum.valueOf<error descr="'valueOf(java.lang.Class<T>, java.lang.String)' in 'CaptureTest.Emum' cannot be applied to '(java.lang.Class<capture<? extends CaptureTest.Emum<CaptureTest>>>, java.lang.String)'">(clazz, "CCC")</error>;
+   }
+}
+
+class SuperTest {
+    public List<List<? extends SuperTest>> waitingList;
+
+    public Comparator<List<?>> SIZE_COMPARATOR;
+
+    {
+       //This call has its type arguments inferred alright: T -> List<capture<? extends SuperTest>>
+       Collections.sort(waitingList, SIZE_COMPARATOR);
+    }
+}
+
+class Bug<A> {
+    static class B<C> {
+    }
+
+    static class D<E> {
+        B<E> f() {
+            return null;
+        }
+    }
+
+    <G extends A> void h(B<G> b) {
+    }
+    
+    void foo(D<? extends A> d) {
+        h(d.f());   //This call is OK as a result of reopening captured wildcard for calling "h"
+    }
+}
+
+//IDEA-4215
+class Case2 {
+        class A {}
+
+        class B extends A {}
+
+        Comparator<A> aComparator;
+        Case2() {
+
+            ArrayList<B> blist = new ArrayList<B>();
+
+            // this call is OK: T -> B
+            Collections.sort(blist, aComparator);
+        }
+}
+
+class S1 {
+    <T> void f(List<T> l1, T l2) {
+
+    }
+
+    void bar(List<? extends S1> k) {
+        f<error descr="'f(java.util.List<capture<? extends S1>>, capture<? extends S1>)' in 'S1' cannot be applied to '(java.util.List<capture<? extends S1>>, S1)'">(k,  k.get(0))</error>;
+    }
+}
+
+class S2 {
+    <T> void f(List<T> l1, List<T> l2) {
+
+    }
+
+    void bar(List<? extends S2> k) {
+        f<error descr="'f(java.util.List<T>, java.util.List<T>)' in 'S2' cannot be applied to '(java.util.List<capture<? extends S2>>, java.util.List<capture<? extends S2>>)'">(k, k)</error>;
+    }
+}
+
+class S3 {
+    <T> void f(Map<T,T> l2) {
+
+    }
+
+    void bar(Map<? extends S3, ? extends S3> k) {
+        f<error descr="'f(java.util.Map<T,T>)' in 'S3' cannot be applied to '(java.util.Map<capture<? extends S3>,capture<? extends S3>>)'">(k)</error>;
+    }
+}
+
+class TypeBug {
+    private static class ValueHolder<T> {
+        public T value;
+    }
+
+    public static void main(final String[] args) {
+        List<ValueHolder<?>> multiList = new ArrayList<ValueHolder<?>>();
+
+        ValueHolder<Integer> intHolder = new ValueHolder<Integer>();
+        intHolder.value = 1;
+
+        ValueHolder<Double> doubleHolder = new ValueHolder<Double>();
+        doubleHolder.value = 1.5;
+
+        multiList.add(intHolder);
+        multiList.add(doubleHolder);
+        swapFirstTwoValues<error descr="'swapFirstTwoValues(java.util.List<TypeBug.ValueHolder<T>>)' in 'TypeBug' cannot be applied to '(java.util.List<TypeBug.ValueHolder<?>>)'">(multiList)</error>; //need to be highlighted
+
+        // this line causes a ClassCastException when checked.
+        Integer value = intHolder.value;
+        System.out.println(value);
+    }
+
+    private static <T> void swapFirstTwoValues(List<ValueHolder<T>> multiList) {
+        ValueHolder<T> intHolder = multiList.get(0);
+        ValueHolder<T> doubleHolder = multiList.get(1);
+
+        intHolder.value = doubleHolder.value;
+    }
+}
+
+class OtherBug {
+public static void foo(List<? extends Foo> foos) {
+    final Comparator<Foo> comparator = createComparator();
+    Collections.sort(foos, comparator);  //this call is OK
+  }
+
+  private static Comparator<Foo> createComparator() {
+    return null;
+  }
+
+  public interface Foo {
+  }
+}
+
+class OtherBug1 {
+  public static void foo(List<? super Foo> foos) {
+    final Comparator<Foo> comparator = createComparator();
+    Collections.sort<error descr="'sort(java.util.List<capture<? super OtherBug1.Foo>>, java.util.Comparator<capture<? super OtherBug1.Foo>>)' in 'java.util.Collections' cannot be applied to '(java.util.List<capture<? super OtherBug1.Foo>>, java.util.Comparator<OtherBug1.Foo>)'">(foos, comparator)</error>;
+  }
+
+  private static Comparator<Foo> createComparator() {
+    return null;
+  }
+
+  public interface Foo {
+  }
+}
+
+//IDEADEV-7187
+class AA <B extends AA<B,C>, C extends AA<C, ?>>{}
+//end of IDEADEV-7187
+
+//IDEADEV-8697
+class GenericTest99<E extends GenericTest99<E, F>,F> {
+}
+class GenericTest99D<E extends GenericTest99D<E>> extends GenericTest99<E,Double> {
+}
+class Use99<U extends GenericTest99<?,F>,F> {
+}
+class Use99n extends Use99<GenericTest99D<?>,Double> {
+}
+//end of IDEADEV-8697
+
+class IDEA79360 {
+    public static void main(Map<?, ?> map, Map<Object, Object> test) {
+        map.putAll<error descr="'putAll(java.util.Map<capture<?>,capture<?>>)' in 'java.util.Map' cannot be applied to '(java.util.Map<java.lang.Object,java.lang.Object>)'">(test)</error>;
+        map.put<error descr="'put(capture<?>, capture<?>)' in 'java.util.Map' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+        map.put<error descr="'put(capture<?>, capture<?>)' in 'java.util.Map' cannot be applied to '(java.lang.Object, java.lang.Object)'">(new Object(), new Object())</error>;
+        map = new HashMap<Object, Object>(test);
+    }
+}
+
+class GenericFailureExample {
+
+ interface Descriptor<T extends Comparable<T>> {
+   Class<T> getType();
+ }
+
+ void isMarkedFaultyButCompilesClean(Descriptor<?> n) {
+   bar(n.getType());
+ }
+
+ <T extends Comparable<T>> void butThisWorks(Descriptor<T> n) {
+   bar(n.getType());
+ }
+
+ <T extends Comparable<T>> Comparator<T> bar(Class<T> type) {
+   return null;
+ }
+}
+
+//IDEA-67675
+abstract class A67675<T>
+{
+    abstract T foo();
+}
+
+abstract class B67675<T> extends A67675<T[]> { }
+
+class C67675<T extends B67675<?>>
+{
+    void foo(T x)
+    {
+        x.foo()[0] = "";
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WideningCastToTypeParam.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WideningCastToTypeParam.java
new file mode 100644
index 0000000..7615d72
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WideningCastToTypeParam.java
@@ -0,0 +1,51 @@
+import java.lang.Double;
+
+interface IConverter<C> {
+}
+
+abstract class AbstractNumberConverter<N extends Number> implements IConverter<N> {
+}
+
+class DoubleConverter extends AbstractNumberConverter<Double> {
+}
+
+public class Test {
+  public static <C> IConverter<C> getConverter(Class<C> type) {
+    return (IConverter<C>)new DoubleConverter() {
+    };
+  }
+
+  public static <C extends String> IConverter<C> getConverter1(Class<C> type) {
+    return <error descr="Inconvertible types; cannot cast 'DoubleConverter' to 'IConverter<C>'">(IConverter<C>)new DoubleConverter() {
+    }</error>;
+  }
+
+  public static <C extends Double> IConverter<C> getConverter2(Class<C> type) {
+    return (IConverter<C>)new DoubleConverter() {
+    };
+  }
+
+  public static void main(String[] args) {
+    IConverter<String> converter = getConverter(String.class);
+    IConverter<String> converter1 = getConverter1(String.class);
+    IConverter<String> converter2 = <error descr="Inferred type 'java.lang.String' for type parameter 'C' is not within its bound; should extend 'java.lang.Double'">getConverter2(String.class)</error>;
+  }
+}
+
+
+class Z {
+
+}
+
+class TestNonNarrowingConversion<T extends Z> {
+    public TestNonNarrowingConversion(T u) {
+
+    }
+
+    public T z = null;
+
+    public int a() {
+        <error descr="Incompatible types. Found: 'TestNonNarrowingConversion<Z>', required: 'TestNonNarrowingConversion<T>'">TestNonNarrowingConversion<T> x = new TestNonNarrowingConversion<Z>(new Z());</error>
+        return 1;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardCastConversion.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardCastConversion.java
new file mode 100644
index 0000000..f610bac
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardCastConversion.java
@@ -0,0 +1,548 @@
+public class Test {
+  interface A {}
+  interface B {}
+
+ //? extends A, ? extends B -----------------------------------------
+    void testEE1() {
+        class A {}
+        class B {}
+
+        W<? extends A> xx = null;
+        W<? extends B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A>>' to 'W<? extends B>'">(W<? extends B>) xx</error>;
+    }
+
+    void testEE2() {
+        class A {}
+        class B extends A {}
+
+        W<? extends A> xx = null;
+        W<? extends B> y = (W<? extends B>) xx;
+    }
+
+    void testEE21() {
+        class A {}
+        class B extends A {}
+
+        W<? extends B> xx = null;
+        W<? extends A> y = (W<? extends A>) xx;
+    }
+
+    void testEE211() {
+        class A {}
+        final class B extends A {}
+
+        W<? extends A> xx = null;
+        W<? extends B> y = (W<? extends B>) xx;
+    }
+
+    void test3EE() {
+        W<? extends A> xx = null;
+        W<? extends B> y = (W<? extends B>) xx;
+    }
+
+    void test4EE() {
+        class A {}
+        W<? extends A> xx = null;
+        W<? extends B> y = (W<? extends B>) xx;
+    }
+
+    void test41EE() {
+        class A {}
+        W<? extends B> xx = null;
+        W<? extends A> y = (W<? extends A>) xx;
+    }
+
+    void test411EE() {
+        final class A {}
+        W<? extends B> xx = null;
+        W<? extends A> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends Test.B>>' to 'W<? extends A>'">(W<? extends A>) xx</error>;
+    }
+
+    void test412EE() {
+        final class A implements B {}
+        W<? extends B> xx = null;
+        W<? extends A> y = (W<? extends A>) xx;
+    }
+
+    void test1() {
+        class A {}
+        class B {}
+
+        W<? super A> xx = null;
+        W<? super B> y = (W<? super B>) xx;
+    }
+
+    void test2() {
+        final class A {}
+        final class B {}
+
+        W<? super A> xx = null;
+        W<? super B> y = (W<? super B>) xx;
+    }
+
+   //? super A, ? super B -------------------------
+    void test3SS() {
+        W<? super A> xx = null;
+        W<? super B> y = (W<? super B>) xx;
+    }
+
+  //? extends A, ? super B -------------------------
+    void test1ES() {
+        class A {}
+        class B {}
+
+        W<? extends A> x = null;
+        W<? super B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A>>' to 'W<? super B>'">(W<? super B>) x</error>;
+    }
+
+    void test2ES() {
+        class A {}
+        class B extends A {}
+
+        W<? extends A> x = null;
+        W<? super B> y = (W<? super B>) x;
+    }
+
+    void test3ES() {
+        class A {}
+        class B extends A {}
+
+        W<? extends B> x = null;
+        W<? super A> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends B>>' to 'W<? super A>'">(W<? super A>) x</error>;
+    }
+
+
+    void test4ES() {
+        W<? extends B> x = null;
+        W<? super A> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends Test.B>>' to 'W<? super Test.A>'">(W<? super A>) x</error>;
+    }
+
+    void test5ES() {
+        final class B implements A {}
+
+        W<? extends A> x = null;
+        W<? super B> y = (W<? super B>) x;
+    }
+
+    void test6ES() {
+        final class B implements A {}
+
+        W<? extends B> x = null;
+        W<? super A> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends B>>' to 'W<? super Test.A>'">(W<? super A>) x</error>;
+    }
+
+  // ? extends A, B -----------------------
+    void test1EWC() {
+        class A {
+        }
+        class B {
+        }
+
+        W<? extends A> xx = null;
+        W<B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A>>' to 'W<B>'">(W<B>) xx</error>;
+    }
+
+    void test2EWC() {
+        class A {
+        }
+
+        W<? extends A> xx = null;
+        W<?> y = (W<?>) xx;
+    }
+
+    void test3EWC() {
+        class A {
+        }
+        class B extends A {
+        }
+
+        W<? extends A> xx = null;
+        W<B> y = (W<B>) xx;
+    }
+
+  // ? super A, B -----------------------
+    void test1SWC() {
+        class A {
+        }
+        class B {
+        }
+
+        W<? super A> xx = null;
+        W<B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? super A>>' to 'W<B>'">(W<B>) xx</error>;
+    }
+
+    void test2SWC() {
+        class A {
+        }
+
+        W<? super A> xx = null;
+        W<?> y = (W<?>) xx;
+    }
+
+    void test3SWC() {
+        class A {
+        }
+        class B extends A {
+        }
+
+        W<? super B> xx = null;
+        W<A> y = (W<A>) xx;
+    }
+
+  // ?, ? ------------------------------------------
+  void test1WWW() {
+    W<?> xx = null;
+    W<?> y = xx;
+  }
+
+  //? extends P<? extends A>, B --------------------
+
+    void test1EEWC() {
+        class A {
+        }
+        class B {
+        }
+
+        W<? extends P<? extends A>> xx = null;
+        W<? extends B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends P<? extends A>>>' to 'W<? extends B>'">(W<? extends B>) xx</error>;
+    }
+
+    void test2EEWC() {
+        class A {
+        }
+        class B extends P {
+        }
+
+        W<? extends P<? extends A>> xx = null;
+        W<? extends B> y = (W<? extends B>) xx;
+    }
+
+     void test3EEWC() {
+        class A {
+        }
+        class B<TB> extends P<TB> {
+        }
+
+        W<? extends P<? extends A>> xx = null;
+        W<? extends B<? super A>> y = (W<? extends B<? super A>>) xx;
+    }
+
+
+     void test4EEWC() {
+        class A {
+        }
+        class B<TB> extends P<TB> {
+        }
+
+        W<? extends P<? extends A>> xx = null;
+        W<? extends B<?>> y = (W<? extends B<?>>) xx;
+    }
+
+    void test5EEWC() {
+        class A {
+        }
+        class B<TB> extends P<TB> {
+        }
+        class C {}
+
+        W<? extends P<? extends A>> xx = null;
+        W<? extends B<? extends C>> y = (W<? extends B<? extends C>>) xx;
+    }
+
+  //Array Types inside wildcards
+  void test1AE() {
+        class A {}
+        class B {}
+
+        W<? extends A[]> xx = null;
+        W<? extends B[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A[]>>' to 'W<? extends B[]>'">(W<? extends B[]>) xx</error>;
+    }
+
+    void test11AE() {
+        class A {}
+        class B {}
+
+        W<? extends A[]> xx = null;
+        W<? extends B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A[]>>' to 'W<? extends B>'">(W<? extends B>) xx</error>;
+    }
+
+     void test2AE() {
+        class A {}
+        class B extends A {}
+
+        W<? extends A[]> xx = null;
+        W<? extends B[]> y = (W<? extends B[]>) xx;
+    }
+
+    void test21AE() {
+        class A {}
+        class B extends A {}
+
+        W<? extends A[]> xx = null;
+        W<? extends B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A[]>>' to 'W<? extends B>'">(W<? extends B>) xx</error>;
+    }
+
+
+
+    void testIntAE() {
+
+        W<? extends A[]> xx = null;
+        W<? extends B[]> y = (W<? extends B[]>) xx;
+    }
+
+    void testInt1AE() {
+
+        W<? extends A[]> xx = null;
+        W<? extends B[][]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends Test.A[]>>' to 'W<? extends Test.B[][]>'">(W<? extends B[][]>) xx</error>;
+    }
+
+    void testASS() {
+        class A {}
+        class B {}
+
+        W<? super A[]> xx = null;
+        W<? super B[]> y = (W<? super B[]>) xx;
+    }
+
+    void test1AES() {
+        class A {}
+        class B {}
+
+        W<? extends A[]> x = null;
+        W<? super B[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A[]>>' to 'W<? super B[]>'">(W<? super B[]>) x</error>;
+    }
+
+    void test2AES() {
+        class A {}
+        class B extends A {}
+
+        W<? extends A[]> x = null;
+        W<? super B[]> y = (W<? super B[]>) x;
+    }
+
+    void test3AES() {
+        class A {}
+        class B extends A {}
+
+        W<? extends B[]> x = null;
+        W<? super A[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends B[]>>' to 'W<? super A[]>'">(W<? super A[]>) x</error>;
+    }
+
+
+
+    void test4AES() {
+        W<? extends B[]> x = null;
+        W<? super A[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends Test.B[]>>' to 'W<? super Test.A[]>'">(W<? super A[]>) x</error>;
+    }
+
+    void test5AES() {
+        final class B implements A {}
+
+        W<? extends A[]> x = null;
+        W<? super B[]> y = (W<? super B[]>) x;
+    }
+
+    void test6AES() {
+        final class B implements A {}
+
+        W<? extends B[]> x = null;
+        W<? super A[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends B[]>>' to 'W<? super Test.A[]>'">(W<? super A[]>) x</error>;
+    }
+
+  // type parameters extensions: D<T extends A>
+  void testT3() {
+        class A {
+        }
+        class D<T extends A > {
+            class B extends A {
+            }
+
+            void foo() {
+                D<? extends T> x = null;
+                D<? extends B> y = (D<? extends B>) x;
+            }
+
+        }
+
+    }
+
+    void testT4() {
+        class A {
+        }
+        class D<T extends A> {
+            class B {
+            }
+
+            void foo() {
+                D<? extends T> x = null;
+                D<<error descr="Type parameter '? extends B' is not within its bound; should extend 'A'">? extends B</error>> y = (D<<error descr="Type parameter '? extends B' is not within its bound; should extend 'A'">? extends B</error>>) x;
+            }
+
+        }
+
+    }
+
+
+    void testT5() {
+           class D<T> {
+               class B {
+               }
+
+               void foo() {
+                   D<? extends T> x = null;
+                   D<? extends B> y = (D<? extends B>) x;
+               }
+
+           }
+
+       }
+
+    void testT6() {
+        class A {
+        }
+        class D<T extends A> {
+            class B extends A {
+            }
+
+            void foo() {
+                D<? super T> x = null;
+                D<? super B> y = (D<?  super B>) x;
+            }
+
+        }
+
+    }
+
+     void testT7() {
+        class A {
+        }
+        class D<T extends A> {
+            class B extends A {
+            }
+
+            void foo() {
+                D<? extends T> x = null;
+                D<? super B> y = (D<?  super B>) x;
+            }
+
+        }
+
+    }
+
+     void testT8() {
+        class A {
+        }
+        class D<T extends A> {
+            class B extends A {
+            }
+
+            void foo() {
+                D<? super T> x = null;
+                D<? extends B> y = (D<? extends B>) x;
+            }
+
+        }
+
+    }
+
+     void testT9() {
+        class A {
+        }
+        class D<T> {
+            class B extends A {
+            }
+
+            void foo() {
+                D<? super T> x = null;
+                D<? extends A> y = (D<? extends B>) x;
+            }
+
+        }
+
+    }
+
+    void testUnbounded() {
+      W<?> x = null;
+      W<? extends A> y = ( W<? extends A>) x;
+      W<?> y1 = (W<?>)x;
+    }
+
+    void testTypeParams() {
+      class MyClass<K, V> {
+        MyClass<K, V> convert(MyClass<? super K, ? super V> arg) {
+          MyClass<K, V> result = (MyClass<K, V>)arg;
+          return result;
+        }
+      }
+    }
+
+    //IDEA-63447
+    void testUnboundWildcardWithArrayTypes() {
+        class IUWWAT{
+            private <T> void method1(T[][] matrix) {
+                final Class<T[]> type = (Class<T[]>) matrix.getClass().getComponentType();
+            }
+
+            private <T> void method2(T[][] matrix) {
+                final Class<Object> type = (Class<Object>) matrix.getClass().getComponentType();
+            }
+
+            private <T> void method3(T[][] matrix) {
+                final Class<Object[]> type = (Class<Object[]>) matrix.getClass().getComponentType();
+            }
+
+            private <T> void method4(T[][] matrix) {
+                final Class<Object[][]> type = (Class<Object[][]>) matrix.getClass().getComponentType();
+            }
+        }
+    }
+}
+
+class W<T> {}
+class P<L> {}
+
+// IDEA-62529
+class Refx<T> {
+    Class<? super T> get() { return null; }
+    boolean f() {
+      if (get() == Enum.class) return false;
+      return (Class<Enum>)get() == Enum.class;
+    }
+}
+
+
+//hierarchy of type param bound
+abstract class DomInvocationHandler<T extends AbstractDomChildDescriptionImpl> {
+    void f() {
+        if (this  instanceof IndexedElementInvocationHandler) {
+        }
+    }
+}
+
+interface AbstractDomChildrenDescription {
+}
+
+class AbstractDomChildDescriptionImpl implements AbstractDomChildrenDescription {
+}
+
+class IndexedElementInvocationHandler extends DomInvocationHandler<FixedChildDescriptionImpl> {
+}
+
+class FixedChildDescriptionImpl extends AbstractDomChildDescriptionImpl {
+}
+
+class CaptureSymmetry {
+  interface Collection<A> {}
+  interface List<A> extends Collection<A>{}
+  class ArrayList<A> implements List<A> {}
+
+  public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
+    return null;
+  }
+
+  public <B extends List<?>> Collection<? extends B> getBreakpoints (List<B> b) {
+    Collection<? extends ArrayList<?>> breakpoints = null;
+    Collection<? extends B> regular = breakpoints != null ? unmodifiableCollection((Collection<? extends B>)breakpoints) : b;
+    return null;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardTypes.java
new file mode 100644
index 0000000..d55e641
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardTypes.java
@@ -0,0 +1,246 @@
+import java.util.*;
+
+class a {
+    public void printList(List<?> list) {
+        for (Iterator<?> i = list.iterator(); i.hasNext();) {
+            System.out.println(i.next().toString());
+        }
+    }
+}
+
+class b<<warning descr="Type parameter 'T' is never used">T</warning>> {
+    public interface Lst <E, Self extends Lst<E, Self>> {
+        Self subList(int fromIndex, int toIndex);
+    }
+
+    public static Lst<?, ?> foo(Lst<?, ?> lst) {
+       Lst<?, ?> myl = lst.subList(0, 2);
+       return myl;
+    }
+}
+
+class ThingUser <V> {
+    V v;
+    {
+        new ThingUser<<error descr="Wildcard type '?' cannot be instantiated directly">?</error>>() {
+        };
+    }
+}
+
+class SuperWildcardTest {
+    static void method(List<?> list) {
+        <error descr="Incompatible types. Found: 'java.util.List<capture<?>>', required: 'java.util.List<? super java.lang.String>'">List<? super String>  l = list;</error>
+        l.size();
+    }
+}
+
+class IdeaDev4166 {
+    Map<String, Object> f( Map<String, ?> fieldsTemplate) {
+        return new HashMap<String, Object>( fieldsTemplate);
+    }
+}
+
+//IDEADEV-5816
+class TwoD {
+  int x, y;
+  TwoD(int a, int b) {
+    x = a;
+    y = b;
+  }
+}
+// Three-dimensional coordinates.
+class ThreeD extends TwoD {
+  int z;
+  ThreeD(int a, int b, int c) {
+    super(a, b);
+    z = c;
+  }
+}
+// Four-dimensional coordinates.
+class FourD extends ThreeD {
+  int t;
+  FourD(int a, int b, int c, int d) {
+    super(a, b, c);
+    t = d;
+  }
+}
+// This class holds an array of coordinate objects.
+class Coords<T extends TwoD> {
+  T[] coords;
+  Coords(T[] o) { coords = o; }
+}
+
+// Demonstrate a bounded wildcard.
+class BoundedWildcard {
+
+  static void showXY(Coords<? extends TwoD> c) {
+    System.out.println("X Y Coordinates:");
+    for(int i=0; i < c.coords.length; i++) {
+      System.out.println(c.coords[i].x + " " + c.coords[i].y);
+    }
+    System.out.println();
+  }
+
+  static void showXYZ(Coords<? extends ThreeD> c) {
+    System.out.println("X Y Z Coordinates:");
+    for(int i=0; i < c.coords.length; i++)
+      System.out.println(c.coords[i].x + " " +
+                         c.coords[i].y + " " +
+                         c.coords[i].z);
+    System.out.println();
+  }
+
+  static void showAll(Coords<? extends FourD> c) {
+    System.out.println("X Y Z T Coordinates:");
+    for(int i=0; i < c.coords.length; i++)
+      System.out.println(c.coords[i].x + " " +
+                         c.coords[i].y + " " +
+                         c.coords[i].z + " " +
+                         c.coords[i].t);
+    System.out.println();
+  }
+
+  public static void main(String args[]) {
+    TwoD td[] = {
+      new TwoD(0, 0),
+      new TwoD(7, 9),
+      new TwoD(18, 4),
+      new TwoD(-1, -23)
+    };
+    Coords<TwoD> tdlocs = new Coords<TwoD>(td);
+    System.out.println("Contents of tdlocs.");
+    showXY(tdlocs); // OK, is a TwoD
+    showXYZ<error descr="'showXYZ(Coords<? extends ThreeD>)' in 'BoundedWildcard' cannot be applied to '(Coords<TwoD>)'">(tdlocs)</error>;
+    showAll<error descr="'showAll(Coords<? extends FourD>)' in 'BoundedWildcard' cannot be applied to '(Coords<TwoD>)'">(tdlocs)</error>;
+    // Now, create some FourD objects.
+    FourD fd[] = {
+      new FourD(1, 2, 3, 4),
+      new FourD(6, 8, 14, 8),
+      new FourD(22, 9, 4, 9),
+      new FourD(3, -2, -23, 17)
+    };
+    Coords<FourD> fdlocs = new Coords<FourD>(fd);
+    System.out.println("Contents of fdlocs.");
+    // These are all OK.
+    showXY(fdlocs);
+    showXYZ(fdlocs);
+    showAll(fdlocs);
+  }
+}
+//end of IDEADEV-5816
+
+interface I33 {}
+public class Q<T extends I33> {
+    T t;
+    <V extends I33> List<V> foo(Q<V> v) {
+      v.hashCode();
+      return null;
+    }
+
+    List<? extends I33>  g (Q<?> q) {
+      return foo(q);
+    }
+}
+
+//IDEADEV-16628 
+class CollectionHelper {
+  public static <A> Collection<A> convertDown(Collection<? super A> collection) {
+    return collection == null ? null : null;
+  }
+  public static <A> Collection<A> convertUp(Collection<? extends A> collection) {
+    return collection == null ? null : null;
+  }
+
+  public static void main(String[] args) {
+    // Downcast examples
+    final Collection<Number> numbers1 = new ArrayList<Number>(1);
+    Collection<Integer> integers1 =  CollectionHelper.convertDown(numbers1);
+    integers1.hashCode();
+    // Upcast example
+    final Collection<Integer> integers4 = new ArrayList<Integer>(1);
+    final Collection<Number> numbers4 = CollectionHelper.<Number>convertUp(integers4);
+    numbers4.hashCode();
+  }
+}
+
+//IDEA-62529
+class My<T> {
+    private  Class<? super T> getSuperclass(){
+        return null;
+    }
+
+    public void test() {
+        if (getSuperclass() == List.class);
+    }
+}
+
+class IDEA75178 {
+    void test(Set<String> labels) {
+        final Matcher<? super Object> empty = isEmpty();
+        assertThat(labels, empty);
+        assertAlsoThat(empty, labels);
+    }
+
+    public static <T> void assertThat(T actual, Matcher<T> matcher) { throw new AssertionError(actual.toString() + matcher.toString());}
+    public static <T> void assertAlsoThat(Matcher<T> matcher, T actual) { throw new AssertionError(actual.toString() + matcher.toString());}
+
+    public static <T> Matcher<? super T> isEmpty() {
+        return null;
+    }
+
+    static class Matcher<<warning descr="Type parameter 'T' is never used">T</warning>>{}
+  
+  class Foo {}
+  void testComment() {
+      Set<Foo> foos = Collections.emptySet();
+      assertThatComment(foos, hasSize(0));
+  }
+
+  <E> Matcher<? super Collection<? extends E>> hasSize(int size) {return size == 0 ? null : null;}
+  <T> void assertThatComment(T actual, Matcher<? super T> matcher){ throw new AssertionError(actual.toString() + matcher.toString());}
+}
+
+class IDEA66750 {
+  public void test() {
+    List<List<String>> data = new ArrayList<List<String>>();
+    List<List<?>> y = <error descr="Inconvertible types; cannot cast 'java.util.List<java.util.List<java.lang.String>>' to 'java.util.List<java.util.List<?>>'">(List<List<?>>)data</error>;
+    System.out.println(y);
+
+    ArrayList<Number> al = <error descr="Inconvertible types; cannot cast 'java.util.ArrayList<java.lang.Integer>' to 'java.util.ArrayList<java.lang.Number>'">(ArrayList<Number>) new ArrayList<Integer>(1)</error>;
+    System.out.println(al);
+  }
+}
+
+class IDEA73377 {
+  public Iterator<Map.Entry<Map.Entry<?, ?>, ?>> iterator(Map<?, ?> map) {
+    //noinspection unchecked
+    return <error descr="Inconvertible types; cannot cast 'java.util.Iterator<java.util.Map.Entry<capture<?>,capture<?>>>' to 'java.util.Iterator<java.util.Map.Entry<java.util.Map.Entry<?,?>,?>>'">(Iterator<Map.Entry<Map.Entry<?, ?>, ?>>)map.entrySet().iterator()</error>;
+  }
+}
+
+class IDEA91481 {
+  void bar(){
+    BeanBuilder<? extends DirectBean> builder = <warning descr="Unchecked cast: 'IDEA91481.BeanBuilder<capture<? extends IDEA91481.Bean>>' to 'IDEA91481.BeanBuilder<? extends IDEA91481.DirectBean>'">(BeanBuilder<?  extends DirectBean>) builder()</warning>;
+    System.out.println(builder);
+  }
+
+  BeanBuilder<? extends Bean> builder() {
+    return null;
+  }
+
+  class BeanBuilder<<warning descr="Type parameter 'T' is never used">T</warning>> {}
+  class Bean {}
+  class DirectBean extends Bean {}
+}
+
+class IDEA89640 {
+  interface X {}
+  class Y<<warning descr="Type parameter 'T' is never used">T</warning> extends X> {}
+
+  public static void main(String[] args) {
+    Y<? extends X> a = null;
+    Y<? extends X> b = null;
+    boolean flag = a  != b; 
+    System.out.println(flag);
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsBoundsIntersection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsBoundsIntersection.java
new file mode 100644
index 0000000..3fc74e5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsBoundsIntersection.java
@@ -0,0 +1,15 @@
+class NodeProperty<A, B> {}
+
+class NodeType {}
+class NumberExpression extends NodeType {}
+class Node<NodeTypeT extends NodeType> {
+    public <ValueT> ValueT get(NodeProperty<? super NodeTypeT, ValueT> prop) {
+        return null;
+    }
+}
+
+class Main {
+    public static void main(NodeProperty<NumberExpression, Integer> nval,  Node<? extends NodeType> expr) {
+        int val = expr.get<error descr="'get(NodeProperty<? super capture<? extends NodeType>,ValueT>)' in 'Node' cannot be applied to '(NodeProperty<NumberExpression,java.lang.Integer>)'">(nval)</error>;
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsOnRawTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsOnRawTypes.java
new file mode 100644
index 0000000..ed1aa05
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsOnRawTypes.java
@@ -0,0 +1,15 @@
+import java.util.List;
+
+public class Main<T> {
+    Object get(List<DiagramNode<T>> nodes, A a) {
+        return null;
+    }
+}
+class DiagramNode<T> {}
+
+class A {
+    static void f(Main m, List<DiagramNode<?>> nodes){
+        final Object data = m.get(nodes, new A());
+        final <error descr="Incompatible types. Found: 'java.util.List<DiagramNode<?>>', required: 'java.util.List<DiagramNode>'">List<DiagramNode> n = nodes;</error>
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/exceptions/LambdaParamExceptionVariable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/exceptions/LambdaParamExceptionVariable.java
index 80d78a4..ad62864 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/exceptions/LambdaParamExceptionVariable.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/exceptions/LambdaParamExceptionVariable.java
@@ -5,7 +5,7 @@
     <K extends Throwable> void foo(F<K> f) throws K { }
 
     {
-        foo(<error descr="Cyclic inference">(t)->{}</error>);
+        <error descr="Unhandled exception: java.lang.Throwable">foo((t)->{});</error>
         <error descr="Unhandled exception: java.lang.ClassNotFoundException">foo((ClassNotFoundException t)->{});</error>
     }
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/DefaultConstructorAsArgument.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/DefaultConstructorAsArgument.java
new file mode 100644
index 0000000..9846267
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/DefaultConstructorAsArgument.java
@@ -0,0 +1,21 @@
+class Main2  {
+
+    <R> void bar(Fun<Integer, R> collector) { }
+
+    <T, D> Fun<T, Integer> foo(D d) { return null; }
+
+    public void test() {
+        bar(new Foo<>());
+    }
+
+    interface Fun<T, R> {
+        R _(T t);
+    }
+    
+    class Foo<K> implements Fun<K, Integer> {
+        @Override
+        public Integer _(K k) {
+            return null;
+        }
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution.java
index 43c4ba9..57f194d 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution.java
@@ -1,6 +1,6 @@
 public interface IDEA99969 {
   default IntStream distinct(Stream s) {
-    return s.map(i -> (int) i);
+    return s.map<error descr="Ambiguous method call: both 'Stream.map(Function)' and 'Stream.map(IntFunction)' match">(i -> <error descr="Inconvertible types; cannot cast '<lambda parameter>' to 'int'">(int) i</error>)</error>;
   }
 }
 interface Stream<T> {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java
index c89c855..a178b4d 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java
@@ -8,19 +8,19 @@
     }
 
 
-    private void foo(IO<? extends A> <warning descr="Parameter 'p' is never used">p</warning>) {}
+    private void <warning descr="Private method 'foo(Test.IO<? extends A>)' is never used">foo</warning>(IO<? extends A> <warning descr="Parameter 'p' is never used">p</warning>) {}
     private void <warning descr="Private method 'foo(Test.IN<? extends B>)' is never used">foo</warning>(IN<? extends B> <warning descr="Parameter 'p' is never used">p</warning>) {}
 
 
     private static class Inner<A extends Object, B extends Number> {
         private void <warning descr="Private method 'm8(Test.IO<? extends A>)' is never used">m8</warning>(IO<? extends A> <warning descr="Parameter 'p' is never used">p</warning>) {}
-        private void m8(IN<? extends B> <warning descr="Parameter 'p' is never used">p</warning>) {}
+        private void <warning descr="Private method 'm8(Test.IN<? extends B>)' is never used">m8</warning>(IN<? extends B> <warning descr="Parameter 'p' is never used">p</warning>) {}
     }
 
     public static void main(String[] args) {
         Inner<Number, Double> inn = new Inner<>();
-        inn.m8(p -> 1.0);
-        new Test<Number, Integer>().foo(p -> 1.0);
+        inn.m8<error descr="Ambiguous method call: both 'Inner.m8(IO<? extends Number>)' and 'Inner.m8(IN<? extends Double>)' match">(p -> 1.0)</error>;
+        new Test<Number, Integer>().foo<error descr="Ambiguous method call: both 'Test.foo(IO<? extends Number>)' and 'Test.foo(IN<? extends Integer>)' match">(p -> 1.0)</error>;
 
     }
 }
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution3.java
index 435e10d..6f7e6d0 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution3.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution3.java
@@ -8,8 +8,8 @@
         IntStream mi = sp.map(Inner::foo);
         Stream<Integer> mI = sp.map(Inner::fooBoxed);
 
-        IntStream li = sp.map(inner->inner.foo());
-        Stream<Integer> lI = sp.map(inner -> inner.fooBoxed());
+        IntStream li = sp.map<error descr="Ambiguous method call: both 'Stream.map(Function<? super Inner,?>)' and 'Stream.map(IntFunction<? super Inner>)' match">(inner->inner.<error descr="Cannot resolve method 'foo()'">foo</error>())</error>;
+        Stream<Integer> lI = sp.map<error descr="Ambiguous method call: both 'Stream.map(Function<? super Inner,? extends Integer>)' and 'Stream.map(IntFunction<? super Inner>)' match">(inner -> inner.<error descr="Cannot resolve method 'fooBoxed()'">fooBoxed</error>())</error>;
     }
 
     interface Stream<T> {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguitySpecificReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguitySpecificReturn.java
index c090878..738dd66 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguitySpecificReturn.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguitySpecificReturn.java
@@ -1,15 +1,15 @@
 class IntStream {
   private void foo(IntStream s) {
-    s.map(i -> 1 << i);
-    s.map(i -> 1);
-    s.map(i -> i);
+    s.map<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Integer>)' match">(i -> <error descr="Operator '<<' cannot be applied to 'int', '<lambda parameter>'">1 << i</error>)</error>;
+    s.map<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Integer>)' match">(i -> 1)</error>;
+    s.map<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Integer>)' match">(i -> i)</error>;
   }
 
   public static void main(String[] args) {
     new IntStream().foo(null);
   }
 
-  private IntStream map(IntUnaryOperator mapper) {
+  private IntStream <warning descr="Private method 'map(IntUnaryOperator)' is never used">map</warning>(IntUnaryOperator mapper) {
     System.out.println(mapper);
     return null;
   }
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/InferenceFromArgs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/InferenceFromArgs.java
index 2febfc5..2c5ca5e 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/InferenceFromArgs.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/InferenceFromArgs.java
@@ -15,13 +15,13 @@
     private static <E> void bazz(I<? super E, Integer> i) { }
 
     void foo(B<Integer> b) {
-         bar(null, <error descr="Cyclic inference">(k, v) -> v</error>);
+         bar(null, (k, v) -> v);
          bar(null, null);
          bar(b, (k, v) ->  {return v;});
          bar(b, (k, v) -> {<error descr="Incompatible types. Found: 'java.lang.Integer', required: 'java.lang.String'">String i = k;</error> return v;});
          bar(b, (k, v) -> {Integer  i = k; return v;});
 
-         bazz(<error descr="Cyclic inference">(k, v) -> v</error>);
+         bazz((k, v) -> v);
          bazz((k, v) -> {<error descr="Incompatible types. Found: 'java.lang.Object', required: 'int'">int i = k;</error> return v;});
     }
 
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java
index 4b9b085..774c555 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java
@@ -12,7 +12,7 @@
 
 class Test2 {
   protected <T, U> U exerciseOps(TestData<T> data, TerminalOp<T, U> terminal, IntermediateOp... ops) {
-    return exerciseOps(data, <error descr="Cyclic inference">(u, v) -> u.equals(v)</error>, terminal);
+    <error descr="Incompatible types. Found: 'java.lang.Object', required: 'U'">return exerciseOps(data, (u, v) -> u.equals(v), terminal);</error>
   }
 }
 
@@ -23,15 +23,15 @@
 
   static <T> void bar(I<T> i, List<T> l){
     bar(x -> {}, l);
-    bar(<error descr="Cyclic inference">x -> {}</error>, null);
+    bar(x -> {}, null);
     bar((I<T>)x -> {}, null);
     bar((T x) -> {}, null);
     bar(x -> {}, new ArrayList<T>());
-    bar(<error descr="Cyclic inference">x -> {}</error>, new ArrayList());
+    bar(x -> {}, new ArrayList());
   }
 
   static {
-    bar(<error descr="Cyclic inference">x->{}</error>, new ArrayList());
+    bar(x->{}, new ArrayList());
   }
 }
 
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/NoInferenceResult.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/NoInferenceResult.java
index 7af6276..53e96c39 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/NoInferenceResult.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/NoInferenceResult.java
@@ -21,7 +21,7 @@
         m((String s1) -> s1.length());
         m((String s1) -> s1);
 
-        m1(<error descr="Cyclic inference">() -> { }</error>);
+        m1<error descr="'m1(T)' in 'NoInferenceResult' cannot be applied to '(<lambda expression>)'">(() -> { })</error>;
 
         Foo<String> foo = new Foo<String>();
         foo.map(v -> null);
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java
index 4ca8cb3..a922039 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java
@@ -25,7 +25,7 @@
     }
 
     public static void main(String[] args) {
-        call(i-> {return i;});
+        call<error descr="Ambiguous method call: both 'ReturnTypeIncompatibility.call(I1<Integer>)' and 'ReturnTypeIncompatibility.call(I2<String>)' match">(i-> {return i;})</error>;
     }
 }
 
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java
index d34d61f..8daa44f 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java
@@ -21,9 +21,9 @@
     }
 
     void foo(Foo<String> as, final Foo<Character> ac) {
-        boolean b1 = as.forAll(s -> ac.forAll(c -> false));
-        String s1 = as.forAll(s -> ac.forAll(c -> ""));
-        <error descr="Incompatible types. Found: 'java.lang.String', required: 'boolean'">boolean b2 = as.forAll(s -> ac.forAll(c -> ""));</error>
+        boolean b1 = as.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<String,Boolean>)' and 'Foo.forAll(II<String,String>)' match">(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> false)</error>)</error>;
+        String s1 = as.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<String,Boolean>)' and 'Foo.forAll(II<String,String>)' match">(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> "")</error>)</error>;
+        boolean b2 = as.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<String,Boolean>)' and 'Foo.forAll(II<String,String>)' match">(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> "")</error>)</error>;
         String s2 = as.forAll2(s -> ac.forAll2(<error descr="Incompatible return type boolean in lambda expression">c -> false</error>));
         boolean b3 = as.forAll((I<String, Boolean>)s -> ac.forAll((I<Character, Boolean>)<error descr="Incompatible return type String in lambda expression">c -> ""</error>));
         String s3 = as.forAll((II<String, String>)s -> ac.forAll((II<Character, String>)<error descr="Incompatible return type boolean in lambda expression">c -> false</error>));
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/TypeArgsConsistencyMisc1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/TypeArgsConsistencyMisc1.java
index 613bbeb..be5128f 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/TypeArgsConsistencyMisc1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/TypeArgsConsistencyMisc1.java
@@ -64,8 +64,8 @@
     static <T> void bar3(I<T> i, T t){}
 
     {
-        bar(<error descr="Cyclic inference">x -> x</error>);
-        bar1(<error descr="Cyclic inference">x -> x</error>);
+        bar(x -> x);
+        bar1(x -> x);
         bar2(1, <error descr="Incompatible return type List<Integer> in lambda expression">x -> x</error>);
         bar2("", <error descr="Incompatible return type List<String> in lambda expression">x -> x</error>);
         bar3(<error descr="Incompatible return type List<String> in lambda expression">x -> x</error>, "");
@@ -84,8 +84,8 @@
     static <T> void bar3(I<T> i, T t){}
 
     {
-        bar(<error descr="Cyclic inference">x -> x</error>);
-        bar1(<error descr="Cyclic inference">x -> x</error>);
+        bar(x -> x);
+        bar1(x -> x);
         bar2(1, x -> x);
         bar2("", x -> x);
 
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/WildcardsAndFormalLambdaParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/WildcardsAndFormalLambdaParams.java
new file mode 100644
index 0000000..3dda1b4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/WildcardsAndFormalLambdaParams.java
@@ -0,0 +1,11 @@
+public class Test {
+  interface Predicate<T> {
+    boolean test(T t);
+  }
+
+  {
+    Predicate<? super Integer> p = (Number n) -> n.equals(23);
+    Predicate<Integer> p1 = (<error descr="Incompatible parameter types in lambda expression">Number n</error>) -> n.equals(23);
+    Predicate<Number> p2 = (Number n) -> n.equals(23);
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/inference/SimpleCyclicInference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/inference/SimpleCyclicInference.java
index d344665..400c469 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/inference/SimpleCyclicInference.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/inference/SimpleCyclicInference.java
@@ -8,13 +8,13 @@
 
     void bazz() {
         bar(null);
-        bar(<error descr="Cyclic inference">(z)-> {System.out.println();}</error>);
+        bar((z)-> {System.out.println();});
     }
   
     static <T> T id(T i2) {return i2;}
 
     {
-       id(<error descr="Cyclic inference">() -> {System.out.println("hi");}</error>);
+       id<error descr="'id(T)' in 'NoLambda' cannot be applied to '(<lambda expression>)'">(() -> {System.out.println("hi");})</error>;
        NoLambda.<Runnable>id(() -> {System.out.println("hi");});
     }
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParams.java
index 8ecb69a..5fffb89 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParams.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParams.java
@@ -30,8 +30,8 @@
 
   public static void main(String[] args) {
     call((String i)->{ return i;});
-    call(<error descr="Cyclic inference">i->{ return i;}</error>);
-    call(<error descr="Cyclic inference">i->""</error>);
-    call<error descr="'call(ReturnTypeCompatibility.I1<java.lang.Integer>)' in 'ReturnTypeCompatibility' cannot be applied to '(<lambda expression>)'">((int i)->{ return i;})</error>;
+    call(i->{ return i;});
+    call(i->"");
+    call((<error descr="Incompatible parameter types in lambda expression">int i</error>)->{ return i;});
   }
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterFormalTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterFormalTypes.java
index b39fca9..a5358d3 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterFormalTypes.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterFormalTypes.java
@@ -9,6 +9,6 @@
     static <T> I<T> bar(I<T> i){return i;}
  
     {
-        bar((List<String> list) -> null);
+        bar(list -> null);
     }
 }
diff --git a/java/java-tests/testData/codeInsight/parameterInfo/AnnotationWithGenerics.java b/java/java-tests/testData/codeInsight/parameterInfo/AnnotationWithGenerics.java
new file mode 100644
index 0000000..7dcc9bc
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/parameterInfo/AnnotationWithGenerics.java
@@ -0,0 +1,10 @@
+import java.util.List;
+
+@interface PrepareForTest {
+    Class<List<String[]>> value();
+}
+
+abstract class A implements List<String>{}
+
+@PrepareForTest({A<caret>.class})
+class Main {}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ContractAnnotation.java b/java/java-tests/testData/inspection/dataFlow/fixture/ContractAnnotation.java
index c39c022..a5c27dd 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/ContractAnnotation.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ContractAnnotation.java
@@ -6,14 +6,22 @@
 import java.lang.IllegalArgumentException;
 
 public class AssertIsNotNull {
-  void bar(String s) {
+  void bar(String s, String s1) {
     if (<warning descr="Condition 's == null && trimIfNotNull(s) != null' is always 'false'">s == null && <warning descr="Condition 'trimIfNotNull(s) != null' is always 'false' when reached">trimIfNotNull(s) != null</warning></warning>) {
       throw new AssertionError();
     }
 
     final Object o = call();
     assertIsNotNull(o);
+    System.out.println(o.toString());
     if(<warning descr="Condition 'o == null' is always 'false'">o == null</warning>) {}
+    
+    if (trimIfNotNull(s1) != null) {
+      System.out.println(s1.charAt(0));
+      if (<warning descr="Condition 's1 == null' is always 'false'">s1 == null</warning>) {
+        
+      }
+    }
   }
   
   @Contract("null -> fail")
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ContractPreservesUnknownNullability.java b/java/java-tests/testData/inspection/dataFlow/fixture/ContractPreservesUnknownNullability.java
new file mode 100644
index 0000000..d829f23
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ContractPreservesUnknownNullability.java
@@ -0,0 +1,27 @@
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+
+public class Foo {
+
+  @Contract("null->null")
+  String foo(String s){
+    return s;
+  }
+
+  void bar(String s, String s2) {
+    foo(s);
+    s.hashCode();
+    goo(foo(s2));
+  }
+
+  void bar2(String s, String s2) {
+    foo(s);
+    if (equals(s2)) {
+      s.hashCode();
+    }
+  }
+
+
+  void goo(@NotNull String s) {}
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/FinalGetter.java b/java/java-tests/testData/inspection/dataFlow/fixture/FinalGetter.java
new file mode 100644
index 0000000..839452a
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/FinalGetter.java
@@ -0,0 +1,14 @@
+class Some {
+  final boolean getFoo() { return equals(2); }
+  void changeEverything() {}
+
+  void bar() {
+    if (getFoo()) {
+      changeEverything();
+      if (getFoo()) {
+
+      }
+    }
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ForeachOverWildcards.java b/java/java-tests/testData/inspection/dataFlow/fixture/ForeachOverWildcards.java
new file mode 100644
index 0000000..152c9ea
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ForeachOverWildcards.java
@@ -0,0 +1,12 @@
+import org.jetbrains.annotations.Nullable;
+
+class Some {
+  void bar2(@Nullable Iterable<? extends String> dirs) {
+    if (dirs != null) {
+      for (String dir : dirs) {
+
+      }
+    }
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/IsNullCheck.java b/java/java-tests/testData/inspection/dataFlow/fixture/IsNullCheck.java
index 1b2c485..f87e0de 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/IsNullCheck.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/IsNullCheck.java
@@ -2,8 +2,9 @@
    void bar() {
      final Value v = call();
      if (Value.isNull(v)) {
-       if(<warning descr="Condition 'v == null' is always 'true'">v == null</warning>) {}
+       return;
      }
+     if(<warning descr="Condition 'v == null' is always 'false'">v == null</warning>) {}
    }
     Value call() {return new Value();}
 }
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/LongDisjunctionsNotComplex.java b/java/java-tests/testData/inspection/dataFlow/fixture/LongDisjunctionsNotComplex.java
new file mode 100644
index 0000000..affd67c
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/LongDisjunctionsNotComplex.java
@@ -0,0 +1,47 @@
+class Some {
+  void getName(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10) {
+    if (i1 == 1 ||
+        i1 == 2 ||
+        i1 == 3 ||
+        i1 == 4) { }
+    if (i2 == 1 ||
+        i2 == 2 ||
+        i2 == 3 ||
+        i2 == 4) { }
+    if (i3 == 1 ||
+        i3 == 2 ||
+        i3 == 3 ||
+        i3 == 4) { }
+    if (i4 == 1 ||
+        i4 == 2 ||
+        i4 == 3 ||
+        i4 == 4) { }
+    if (i5 == 1 ||
+        i5 == 2 ||
+        i5 == 3 ||
+        i5 == 4) { }
+    if (i6 == 1 ||
+        i6 == 2 ||
+        i6 == 3 ||
+        i6 == 4) { }
+    if (i7 == 1 ||
+        i7 == 2 ||
+        i7 == 3 ||
+        i7 == 4) { }
+    if (i8 == 1 ||
+        i8 == 2 ||
+        i8 == 3 ||
+        i8 == 4) { }
+    if (i9 == 1 ||
+        i9 == 2 ||
+        i9 == 3 ||
+        i9 == 4) { }
+    if (i10 == 1 ||
+        i10 == 2 ||
+        i10 == 3 ||
+        i10 == 4) { }
+  }
+
+}
+
+
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ManySequentialIfsNotComplex.java b/java/java-tests/testData/inspection/dataFlow/fixture/ManySequentialIfsNotComplex.java
new file mode 100644
index 0000000..605636b
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ManySequentialIfsNotComplex.java
@@ -0,0 +1,37 @@
+class Some {
+  void foo(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, int i11, int i12, int i13, Foo foo) {
+    if (i1 == 0) {
+      i3 = 2;
+      System.out.println(foo.getBar1().length());
+    }
+    if (i2 == 0) System.out.println(foo.getBar2().length());
+    if (i3 == 0) System.out.println(foo.getBar3().length());
+    if (i4 == 0) System.out.println(foo.getBar4().length());
+    if (i5 == 0) System.out.println(foo.getBar5().length());
+    if (i6 == 0) System.out.println(foo.getBar6().length());
+    if (i7 == 0) System.out.println(foo.getBar7().length());
+    if (i8 == 0) System.out.println(foo.getBar8().length());
+    if (i9 == 0) System.out.println(foo.getBar9().length());
+    if (i10 == 0) System.out.println(foo.getBar10().length());
+    if (i11 == 0) System.out.println(foo.getBar11().length());
+    if (i12 == 0) System.out.println(foo.getBar12().length());
+    if (i13 == 0) System.out.println(foo.getBar13().length());
+  }
+
+}
+
+interface Foo {
+  String getBar1();
+  String getBar2();
+  String getBar3();
+  String getBar4();
+  String getBar5();
+  String getBar6();
+  String getBar7();
+  String getBar8();
+  String getBar9();
+  String getBar10();
+  String getBar11();
+  String getBar12();
+  String getBar13();
+}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/WhileNotComplex.java b/java/java-tests/testData/inspection/dataFlow/fixture/WhileNotComplex.java
new file mode 100644
index 0000000..65d32c3
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/WhileNotComplex.java
@@ -0,0 +1,14 @@
+import java.io.File;
+
+class Some {
+  private File findRepository(File file) {
+    while (file != null) {
+      file = file.getParentFile();
+    }
+
+    return new File("foo");
+  }
+
+}
+
+
diff --git a/java/java-tests/testData/inspection/dataFlow/unboxingNPE/expected.xml b/java/java-tests/testData/inspection/dataFlow/unboxingNPE/expected.xml
index caab45d3..000168e 100644
--- a/java/java-tests/testData/inspection/dataFlow/unboxingNPE/expected.xml
+++ b/java/java-tests/testData/inspection/dataFlow/unboxingNPE/expected.xml
@@ -384,10 +384,4 @@
     <description>Condition &lt;code&gt;i&lt;/code&gt; is always &lt;code&gt;true&lt;/code&gt; when reached</description>
   </problem>
 
-  <problem>
-    <file>Test.java</file>
-    <line>62</line>
-    <module>testUnboxingNPE_7454908424878253728</module>
-    <description>Switch label&lt;code&gt;case 0:&lt;/code&gt; is unreachable</description>
-  </problem>
 </problems>
diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll3.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll3.java
new file mode 100644
index 0000000..6c73f83
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll3.java
@@ -0,0 +1,12 @@
+class C {
+    static enum E {
+        A
+    }
+
+    void x(String s1, String s2) {}
+
+    private void y() {
+        x(E.A.toString(), E.<caret>A.toString());
+
+    }
+}
diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll3_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll3_after.java
new file mode 100644
index 0000000..8d7703c
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll3_after.java
@@ -0,0 +1,12 @@
+class C {
+    static enum E {
+        A
+    }
+
+    void x(String s1, String s2) {}
+
+    private void y(E a) {
+        x(a.toString(), a.toString());
+
+    }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java
index 1ccef12..607b1b4 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java
@@ -1,6 +1,7 @@
 package com.intellij.codeInsight;
 
 import com.intellij.codeInsight.hint.ParameterInfoComponent;
+import com.intellij.codeInsight.hint.api.impls.AnnotationParameterInfoHandler;
 import com.intellij.codeInsight.hint.api.impls.MethodParameterInfoHandler;
 import com.intellij.lang.parameterInfo.CreateParameterInfoContext;
 import com.intellij.lang.parameterInfo.ParameterInfoUIContextEx;
@@ -74,4 +75,25 @@
                         MethodParameterInfoHandler
                           .updateMethodPresentation(method, ((MethodCandidateInfo)itemsToShow[0]).getSubstitutor(), parameterContext));
   }
+
+  public void testAnnotationWithGenerics() throws Exception {
+    doTestAnnotationPresentation("<html>Class&lt;List&lt;String[]&gt;&gt; <b>value</b>()</html>");
+  }
+
+  private void doTestAnnotationPresentation(String expectedString) {
+    configureByFile(BASE_PATH + getTestName(false) + ".java");
+
+    final AnnotationParameterInfoHandler handler = new AnnotationParameterInfoHandler();
+    final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile);
+    final PsiAnnotationParameterList list = handler.findElementForParameterInfo(context);
+    assertNotNull(list);
+    final Object[] itemsToShow = context.getItemsToShow();
+    assertNotNull(itemsToShow);
+    assertTrue(itemsToShow.length == 1);
+    assertTrue(itemsToShow[0] instanceof PsiAnnotationMethod);
+    final PsiAnnotationMethod method = (PsiAnnotationMethod)itemsToShow[0];
+    final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler);
+    Assert.assertEquals(expectedString,
+                        AnnotationParameterInfoHandler.updateUIText(method, parameterContext));
+  }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy
index dde4d05..e1250ef 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy
@@ -27,11 +27,75 @@
 $some_long_variable_name = Obj::instance();
 $some_lon<caret>
 '''
-    myFixture.performEditorAction(IdeActions.ACTION_HIPPIE_COMPLETION)
+    complete()
     myFixture.checkResult '''
 $some_long_variable_name = Obj::instance();
 $some_long_variable_name<caret>
 '''
   }
 
+  public void testFromAnotherFile() {
+    myFixture.configureByText "b.txt", '''
+$some_long_variable_name = Obj::instance();
+'''
+    myFixture.configureByText "a.txt", '''
+$some_lon<caret>
+'''
+
+    complete()
+    myFixture.checkResult '''
+$some_long_variable_name<caret>
+'''
+  }
+
+  public void "test no middle matching"() {
+    myFixture.configureByText "a.txt", '''
+fooExpression
+exp<caret>
+'''
+    complete()
+    myFixture.checkResult '''
+fooExpression
+exp<caret>
+'''
+  }
+
+  public void "test words from javadoc"() {
+    myFixture.configureByText "a.java", '''
+/** some comment */
+com<caret>
+'''
+    complete()
+    myFixture.checkResult '''
+/** some comment */
+comment<caret>
+'''
+  }
+  
+  public void "test words from line comments"() {
+    myFixture.configureByText "a.java", '''
+// some comment2
+com<caret>
+'''
+    complete()
+    myFixture.checkResult '''
+// some comment2
+comment2<caret>
+'''
+  }
+  public void "test words from block comments"() {
+    myFixture.configureByText "a.java", '''
+/* some comment3 */
+com<caret>
+'''
+    complete()
+    myFixture.checkResult '''
+/* some comment3 */
+comment3<caret>
+'''
+  }
+
+  private void complete() {
+    myFixture.performEditorAction(IdeActions.ACTION_HIPPIE_COMPLETION)
+  }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
index 697e534..aad87e8 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
@@ -880,7 +880,9 @@
   void foo(int aaa, int aaaaa) { }
   void bar(int aaa, int aaaaa) { foo(<caret>) }
 } """)
-    type 'a,'
+    type 'a'
+    println myFixture.lookupElementStrings
+    type ','
     assert myFixture.editor.document.text.contains('foo(aaa, )')
   }
 
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
index 5380c7e..8e04d87 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
@@ -994,6 +994,7 @@
   public void testNewGenericClass() throws Throwable { doTest('\n') }
   public void testNewGenericInterface() throws Throwable { doTest() }
   public void testEnumPrivateFinal() throws Throwable { doTest() }
+  public void testNoFieldsInImplements() throws Throwable { doTest() }
 
   public void testSwitchConstantsFromReferencedClass() throws Throwable { doTest('\n') }
 
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlighting8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlighting8Test.java
new file mode 100644
index 0000000..2b87ecf
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlighting8Test.java
@@ -0,0 +1,775 @@
+/*
+ * 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.codeInsight.daemon;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
+import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection;
+import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.impl.source.resolve.PsiResolveHelperImpl;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiGraphInferenceHelper;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.testFramework.IdeaTestUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
+  @NonNls private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/genericsHighlighting8";
+
+  @NotNull
+  @Override
+  protected LocalInspectionTool[] configureLocalInspectionTools() {
+    return new LocalInspectionTool[]{new UncheckedWarningLocalInspection(), new UnusedSymbolLocalInspection(), new UnusedImportLocalInspection()};
+  }
+
+  @Override
+  protected Sdk getProjectJDK() {
+    return getTestName(false).contains("Jdk14") ? IdeaTestUtil.getMockJdk14() : super.getProjectJDK();
+  }
+
+  public void testReferenceTypeParams() {
+    doTest();
+  }
+  public void testTypeParameterBoundsList() {
+    doTest();
+  }
+  public void testClassInheritance() {
+    doTest();
+  }
+  public void testTypeInference() {
+    doTest();
+  }
+  public void testRaw() {
+    doTest(true);
+  }
+  public void testExceptions() {
+    doTest();
+  }
+  public void testExplicitMethodParameters() {
+    doTest();
+  }
+  public void testInferenceWithBounds() {
+    doTest();
+  }
+  public void testInferenceWithSuperBounds() {
+    doTest();
+  }
+  public void testInferenceWithUpperBoundPromotion() {
+    doTest();
+  }
+  public void _testVariance() {//todo
+    doTest();
+  }
+  public void testForeachTypes() {
+    doTest();
+  }
+  public void testRawOverridingMethods() {
+    doTest();
+  }    
+  public void _testAutoboxing() { //todo
+    doTest();
+  }                
+  public void testAutoboxingMethods() {
+    doTest();
+  }                                             
+  public void testAutoboxingConstructors() {
+    doTest();
+  }                                      
+  public void testEnumWithAbstractMethods() {
+    doTest();
+  }                                   
+  public void _testEnum() { doTest(); } //todo     
+  public void testEnum56239() {
+    doTest();
+  }
+  public void testSameErasure() {
+    doTest();
+  }          
+  public void testMethods() {
+    doTest();
+  }            
+  public void testFields() {
+    doTest();
+  }           
+  public void testStaticImports() {
+    doTest(true);
+  }   
+  public void testUncheckedCasts() {
+    doTest(true);
+  }
+  public void testUncheckedOverriding() {
+    doTest(true);
+  }
+  public void testWildcardTypes() {
+    doTest(true);
+  }
+  public void testConvertibleTypes() {
+    doTest(true);
+  }
+  public void testIntersectionTypes() {
+    doTest(true);
+  }
+  public void testVarargs() {
+    doTest(true);
+  }
+  public void testTypeArgsOnRaw() {
+    doTest();
+  }          
+  public void testConditionalExpression() {
+    doTest();
+  }  
+  public void testUnused() {
+    doTest(true);
+  }            
+  public void testIDEADEV7337() {
+    doTest(true);
+  }      
+  public void testIDEADEV10459() {
+    doTest(true);
+  }     
+  public void testIDEADEV12951() {
+    doTest(true);
+  }     
+  public void testIDEADEV13011() {
+    doTest(true);
+  }     
+  public void testIDEADEV14006() {
+    doTest(true);
+  }     
+  public void testIDEADEV14103() {
+    doTest(true);
+  }        
+  public void testIDEADEV15534() {
+    doTest(true);
+  }      
+  public void testIDEADEV23157() {
+    doTest(true);
+  }    
+  public void testIDEADEV24166() {
+    doTest(true);
+  }  
+  public void testIDEADEV57343() {
+    doTest();
+  }
+  public void testSOE() {
+    doTest(true);
+  }        
+  public void testGenericExtendException() {
+    doTest();
+  }  
+  public void testSameErasureDifferentReturnTypes() {
+    doTest();
+  }
+  public void testDeepConflictingReturnTypes() {
+    doTest();
+  }  
+  public void testInheritFromTypeParameter() {
+    doTest();
+  }     
+  public void testAnnotationsAsPartOfModifierList() {
+    doTest();
+  } 
+  public void testImplementAnnotation() {
+    doTest();
+  }      
+  public void testOverrideAtLanguageLevel6() {
+    doTest();
+  }    
+  public void testSuperMethodCallWithErasure() {
+    doTest();
+  } 
+  public void testWildcardCastConversion() {
+    doTest();
+  }    
+  public void testTypeWithinItsWildcardBound() {
+    doTest();
+  } 
+  public void testMethodSignatureEquality() {
+    doTest();
+  }    
+  public void testInnerClassRef() {
+    doTest();
+  }             
+  public void testPrivateInnerClassRef() {
+    doTest();
+  }      
+  public void testWideningCastToTypeParam() {
+    doTest();
+  }     
+  public void testCapturedWildcardAssignments() {
+    doTest();
+  }        
+  public void testTypeParameterBoundVisibility() {
+    doTest();
+  }
+  public void testUncheckedWarningsLevel6() {
+    doTest(true);
+  }
+  public void testIDEA77991() {
+    doTest();
+  }                
+  public void testIDEA80386() {
+    doTest();
+  }               
+  public void testIDEA66311() {
+    doTest();
+  }  
+  public void testIDEA67672() {
+    doTest();
+  }  
+  public void testIDEA88895() {
+    doTest();
+  }  
+  public void testIDEA67667() {
+    doTest();
+  }  
+  public void testIDEA66311_16() {
+    doTest();
+  }
+  public void _testIDEA76283() {//todo bounds
+    doTest();
+  }
+  public void testIDEA74899() {
+    doTest();
+  }  
+  public void testIDEA63291() {
+    doTest();
+  }  
+  public void testIDEA72912() {
+    doTest();
+  }         
+  public void testIllegalGenericTypeInInstanceof() {
+    doTest();
+  } 
+  public void testIDEA57339() {
+    doTest();
+  } 
+  public void testIDEA57340() {
+    doTest();
+  }
+  public void testIDEA89771() {
+    doTest();
+  }
+  public void testIDEA89801() {
+    doTest();
+  }
+  public void testIDEA67681() {
+    doTest();
+  }
+  public void testIDEA67599() {
+    doTest();
+  }
+  public void testIDEA57668() {
+    doTest();
+  }
+  public void testIDEA57667() {
+    doTest();
+  }
+  public void testIDEA57650() {
+    doTest();
+  }
+  public void testIDEA57378() {
+    doTest();
+  }
+  public void testIDEA57557() {
+    doTest();
+  }
+  public void testIDEA57563() {
+    doTest();
+  }
+  public void testIDEA57275() {
+    doTest();
+  }
+  public void testIDEA57533() {
+    doTest();
+  }
+  public void testIDEA57509() {
+    doTest();
+  }
+  public void testIDEA57410() {
+    doTest();
+  }
+  public void testIDEA57411() {
+    doTest();
+  }
+  public void testIDEA57484() {
+    doTest();
+  }
+  public void _testIDEA57485() {//todo
+    doTest();
+  }
+  public void testIDEA57486() {
+    doTest();
+  }
+  public void testIDEA57492() {
+    doTest();
+  }
+  public void testIDEA57493() {
+    doTest();
+  }
+  public void testIDEA57495() {
+    doTest();
+  }
+  public void testIDEA57494() {
+    doTest();
+  }
+  public void testIDEA57496() {
+    doTest();
+  }
+  public void testIDEA57264() {
+    doTest();
+  }
+  public void testIDEA57315() {
+    doTest();
+  }
+  public void testIDEA57346() {
+    doTest();
+  }
+  public void testIDEA57284() {
+    doTest();
+  }
+  public void testIDEA57286() {
+    doTest();
+  }
+  public void testIDEA57307() {
+    doTest(true);
+  }
+  public void testIDEA57308() {
+    doTest();
+  }
+  public void testIDEA57310() {
+    doTest();
+  }
+  public void testIDEA57311() {
+    doTest();
+  }
+  public void testIDEA57309() {
+    doTest();
+  }
+  public void testIDEA90802() {
+    doTest();
+  }
+  public void testIDEA70370() {
+    doTest(true);
+  }
+  public void testInaccessibleThroughWildcard() {
+    doTest();
+  }
+  public void testInconvertibleTypes() {
+    doTest();
+  }
+  public void testIncompatibleReturnType() {
+    doTest();
+  }
+  public void testContinueInferenceAfterFirstRawResult() {
+    doTest();
+  }
+  public void testDoNotAcceptLowerBoundIfRaw() {
+    doTest();
+  }
+  public void testStaticOverride() {
+    doTest();
+  }
+  public void testTypeArgumentsGivenOnRawType() {
+    doTest();
+  }
+  public void testSelectFromTypeParameter() {
+    doTest();
+  }
+  public void testTypeArgumentsGivenOnAnonymousClassCreation() {
+    doTest();
+  }
+
+  public void testIDEA94011() {
+    doTest();
+  }
+  public void testDifferentTypeParamsInOverloadedMethods() {
+    doTest(true);
+  }
+
+  public void testIDEA91626() {
+    doTest(true);
+  }
+  public void testIDEA92022() {
+    doTest();
+  }
+  public void testRawOnParameterized() {
+    doTest();
+  }
+  public void testFailedInferenceWithBoxing() {
+    doTest();
+  }
+  public void testFixedFailedInferenceWithBoxing() {
+    doTest();
+  }
+  public void testInferenceWithBoxingCovariant() {
+    doTest();
+  }
+  public void testSuperWildcardIsNotWithinItsBound() {
+    doTest();
+  }
+  public void testSpecificReturnType() {
+    doTest();
+  }
+  public void testParameterizedParameterBound() {
+    doTest();
+  }
+  public void testInstanceClassInStaticContextAccess() {
+    doTest();
+  }
+  public void testFlattenIntersectionType() {
+    doTest();
+  }
+  public void testIDEA97276() {
+    doTest();
+  }
+  public void testWildcardsBoundsIntersection() {
+    doTest();
+  }
+  public void testOverrideWithMoreSpecificReturn() {
+    doTest();
+  }
+  public void testIDEA97888() {
+    doTest();
+  }
+  public void testMethodCallParamsOnRawType() {
+    doTest();
+  }
+  public void testIDEA98421() {
+    doTest();
+  }
+  public void testErasureTypeParameterBound() {
+    doTest();
+  }
+  public void testThisAsAccessObject() {
+    doTest();
+  }
+  public void testIDEA67861() {
+    doTest();
+  }
+  public void testIDEA67597() {
+    doTest();
+  }
+  public void testIDEA57539() {
+    doTest();
+  }
+  public void testIDEA67570() {
+    doTest();
+  }
+  public void testIDEA99061() {
+    doTest();
+  }
+  public void testIDEA99347() {
+    doTest();
+  }
+  public void testIDEA86875() {
+    doTest();
+  }
+  public void testIDEA103760(){
+    doTest();
+  }
+  public void testIDEA105846(){
+    doTest();
+  }
+  public void testIDEA105695(){
+    doTest();
+  }
+  public void testIDEA104992(){
+    doTest();
+  }
+  public void testIDEA57446(){
+    doTest();
+  }
+  public void testIDEA67677(){
+    doTest();
+  }
+  public void testIDEA67798(){
+    doTest();
+  }
+  public void testIDEA57534(){
+    doTest();
+  }
+  public void testIDEA57482(){
+    doTest();
+  }
+  public void testIDEA67577(){
+    doTest();
+  }
+  public void testIDEA57413(){
+    doTest();
+  }
+  public void testIDEA57265(){
+    doTest();
+  }
+  public void testIDEA57271(){
+    doTest();
+  }
+  public void testIDEA57272(){
+    doTest();
+  }
+  public void testIDEA57285(){
+    doTest();
+  }
+  public void testIDEA65066(){
+    doTest();
+  }
+  public void testIDEA67998(){
+    doTest();
+  }
+  public void testIDEA18425(){
+    doTest();
+  }
+  public void testIDEA27080(){
+    doTest();
+  }
+  public void testIDEA22079(){
+    doTest();
+  }
+  public void testIDEA21602(){
+    doTest();
+  }
+  public void testIDEA21602_7(){
+    doTest();
+  }
+
+  public void testIDEA21597() throws Exception {
+    doTest();
+  }
+  public void testIDEA20573() throws Exception {
+    doTest();
+  }
+  public void testIDEA20244() throws Exception {
+    doTest();
+  }
+  public void testIDEA22005() throws Exception {
+    doTest();
+  }
+  public void testIDEA57259() throws Exception {
+    doTest();
+  }
+  public void testIDEA107957() throws Exception {
+    doTest();
+  }
+  public void testIDEA109875() throws Exception {
+    doTest();
+  }
+  public void testIDEA106964() throws Exception {
+    doTest();
+  }
+  public void testIDEA107782() throws Exception {
+    doTest();
+  }
+  public void testInheritedWithDifferentArgsInTypeParams() throws Exception {
+    doTest();
+  }
+  public void testIllegalForwardReferenceInTypeParameterDefinition() throws Exception {
+    doTest();
+  }
+
+  public void testIDEA57877() throws Exception {
+    doTest();
+  }
+  public void testIDEA110568() throws Exception {
+    doTest();
+  }
+  public void testSelfRef() throws Exception {
+    doTest();
+  }
+  public void testTypeParamsCyclicInference() throws Exception {
+    doTest();
+  }
+  public void testCaptureTopLevelWildcardsForConditionalExpression() throws Exception {
+    doTest();
+  }
+  public void testGenericsOverrideMethodInRawInheritor() throws Exception {
+    doTest();
+  }
+
+  public void testIDEA107654() throws Exception {
+    doTest();
+  }
+
+  public void testIDEA55510() throws Exception {
+    doTest();
+  }
+
+  public void testIDEA27185(){
+    doTest();
+  }
+  public void testIDEA67571(){
+    doTest();
+  }
+  public void _testTypeArgumentsOnRawType(){//todo
+    doTest();
+  }
+
+  public void testTypeArgumentsOnRawType17(){
+    doTest();
+  }
+
+  public void testWildcardsOnRawTypes() {
+    doTest();
+  }
+  public void testDisableWithinBoundsCheckForSuperWildcards() {
+    doTest();
+  }
+
+  public void testIDEA108287() throws Exception {
+    doTest();
+  }
+
+  public void testIDEA77128() throws Exception {
+    doTest();
+  }
+
+  public void testDisableCastingToNestedWildcards() throws Exception {
+    doTest();
+  }
+
+  public void testBooleanInferenceFromIfCondition() throws Exception {
+    doTest();
+  }
+
+  public void testMethodCallOnRawTypesExtended() throws Exception {
+    doTest();
+  }
+
+  public void testIDEA104100() {
+    doTest();
+  }
+  public void testIDEA104160() {
+    doTest();
+  }
+  public void testSOEInLeastUpperClass() {
+    doTest();
+  }
+
+  public void testIDEA57334() {
+    doTest();
+  }
+
+  public void testIDEA57325() {
+    doTest();
+  }
+  public void testIDEA67835() {
+    doTest();
+  }
+  public void testIDEA67744() {
+    doTest();
+  }
+  public void testIDEA67682() {
+    doTest();
+  }
+  public void testIDEA57391() {
+    doTest();
+  }
+  public void testIDEA110869() {
+    doTest();
+  }
+  /*public void testIDEA110947() { doTest5(false); }*/
+  public void testIDEA112122() {
+    doTest();
+  }
+  public void testNoInferenceFromTypeCast() {
+    doTest();
+  }
+  public void testCaptureWildcardsInTypeCasts() {
+    doTest();
+  }
+  public void testIDEA111085() {
+    doTest();
+  }
+  public void testIDEA109556() {
+    doTest();
+  }
+  public void testIDEA107440() {
+    doTest();
+  }
+  public void testIDEA57289() {
+    doTest();
+  }
+  public void testIDEA57439() {
+    doTest();
+  }
+  public void testIDEA57312() {
+    doTest();
+  }
+  public void testIDEA67865() {
+    doTest();
+  }
+  public void testBoxingSpecific() {
+    doTest();
+  }
+  public void testIDEA67843() {    //fixme need to change test
+    doTest();
+  }
+  public void testAmbiguousTypeParamVsConcrete() {
+    doTest();
+  }
+  public void testRawAssignments() throws Exception {
+    doTest();
+  }
+  public void testIDEA87860() throws Exception {
+    doTest();
+  }
+
+  private void doTest() {
+    doTest(false);
+  }
+
+   private void doTest(boolean warnings) {
+     LanguageLevelProjectExtension.getInstance(getJavaFacade().getProject()).setLanguageLevel(LanguageLevel.JDK_1_8);
+     IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), myTestRootDisposable);
+     final PsiResolveHelperImpl helper = (PsiResolveHelperImpl)JavaPsiFacade.getInstance(getProject()).getResolveHelper();
+     helper.setTestHelper(new PsiGraphInferenceHelper(getPsiManager()));
+     try {
+       doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false);
+     }
+     finally {
+       helper.setTestHelper(null);
+     }
+   }
+
+
+  public void testIDEA67584() throws Exception {
+    doTest();
+  }
+  public void testIDEA113225() throws Exception {
+    doTest();
+  }
+
+  public void _testJavaUtilCollections_NoVerify() throws Exception {   //todo
+    PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
+    assertNotNull(collectionsClass);
+    collectionsClass = (PsiClass)collectionsClass.getNavigationElement();
+    final String text = collectionsClass.getContainingFile().getText();
+    configureFromFileText("Collections.java", text.replaceAll("\r", "\n"));
+    final PsiResolveHelperImpl helper = (PsiResolveHelperImpl)JavaPsiFacade.getInstance(getProject()).getResolveHelper();
+    helper.setTestHelper(new PsiGraphInferenceHelper(getPsiManager()));
+    try {
+      doTestConfiguredFile(false, false, null);
+    }
+    finally {
+      helper.setTestHelper(null);
+    }
+  }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java
index be7ff01..99c7c27 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java
@@ -26,6 +26,6 @@
   }
 
   private void doTest() throws Exception {
-    doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
+    doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
   }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ExceptionVariablesInferenceTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ExceptionVariablesInferenceTest.java
index 1e665ac..182b9f2 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ExceptionVariablesInferenceTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ExceptionVariablesInferenceTest.java
@@ -42,6 +42,6 @@
   }
 
   private void doTest(final boolean checkWarnings) throws Exception {
-    doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
+    doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
   }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
index 84e60d5..1071f19 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
@@ -79,12 +79,16 @@
     doTest();
   }
 
+  public void testDefaultConstructorAsArgument() throws Exception {
+    doTest();
+  }
+
   private void doTest() throws Exception {
     doTest(false);
   }
 
   private void doTest(final boolean checkWarnings) throws Exception {
     IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable());
-    doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
+    doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
   }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
index cf99110..f2e23bd 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
@@ -37,6 +37,6 @@
   }
 
   private void doTest(boolean checkWarnings, boolean checkInfos) {
-    doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos);
+    doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos);
   }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java
index 633beb0..b6f6654 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java
@@ -51,7 +51,7 @@
   public void testAmbiguityRawGenerics() { doTest(); }
   public void testDefaultMethod() { doTest(); }
   public void testLambdaOnVarargsPlace() { doTest(); }
-  public void testLambdaRawOrNot() { doTest(); }
+  public void testLambdaRawOrNot() { doTest(); }  //todo incorrect testdata
   public void testReturnTypeCompatibility1() { doTest(); }
   public void testNoInferenceResult() { doTest(); }
   public void testInferenceFromArgs() { doTest(); }
@@ -92,12 +92,13 @@
   public void testFunctionalInterfaceCheck() { doTest();}
   public void testUnderscores() { doTest(true);}
   public void testReturnTypeAmbiguity() { doTest();}
+  public void testWildcardsAndFormalLambdaParams() {doTest();}
 
   private void doTest() {
     doTest(false);
   }
 
   private void doTest(final boolean checkWarnings) {
-    doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
+    doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
   }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaInferenceTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaInferenceTest.java
index 6584cdc..96e6058 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaInferenceTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaInferenceTest.java
@@ -30,6 +30,6 @@
   }
 
   private void doTest() throws Exception {
-    doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
+    doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
   }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java
index c27dc9c..94ca90d 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java
@@ -30,6 +30,6 @@
   public void testInferFromFormal() { doTest(); }
 
   private void doTest() {
-    doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
+    doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
   }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java
index 17d7bd1..36f98aa 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java
@@ -35,6 +35,6 @@
   public void testIntersection() { doTest(); }
   public void testSer() { doTest(); }
   private void doTest() {
-    doTest(BASE_PATH + "/" + getTestName(false) + ".java", true, false);
+    doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", true, false);
   }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
index b0b8751..3559d65 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
@@ -95,6 +95,6 @@
 
   private void doTest(boolean warnings) {
     IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable());
-    doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false);
+    doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false);
   }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/PsiPolyExpressionUtilTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/PsiPolyExpressionUtilTest.java
index b892318..cca3bd5 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/PsiPolyExpressionUtilTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/PsiPolyExpressionUtilTest.java
@@ -16,6 +16,7 @@
 package com.intellij.codeInsight.daemon.lambda;
 
 import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
 import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
@@ -79,4 +80,41 @@
     assertNotNull(elementAtCaret);
     return PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class);
   }
+
+  public void testPertinentLambdaExpression() throws Exception {
+    assertTrue(doTestLambdaPertinent("  void bar(List<Runnable> l) {" +
+                                      "   foo(() <caret>-> {}, l);" +
+                                      "  }"));
+  }
+
+  public void testPertinentImplicitLambdaExpression() throws Exception {
+    assertTrue(doTestLambdaPertinent("  void bar(List<Comparable<String>> l) {" +
+                                     "   foo((String s) <caret>-> 1, l);" +
+                                     "  }"));
+  }
+
+  public void testPertinentNestedLambdaExpression() throws Exception {
+    assertTrue(doTestLambdaPertinent("  interface Fun<I, O> { O inOut(I i);}\n" +
+                                     "  void bar(List<Fun<String, Fun<String, String>>> l) {" +
+                                     "   foo((sIn, sOut) -> (sInInner, sOutInner) <caret>-> sOutInner, l);" +
+                                     "  }"));
+  }
+
+  private boolean doTestLambdaPertinent(final String barText) {
+    myFixture.configureByText("Foo.java", "import java.util.*;" +
+                                          "class Foo {" +
+                                          "  <T> T foo(T t, List<T> lT) {" +
+                                          "  }" +
+                                          barText +
+                                          "}");
+    final PsiElement elementAtCaret = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
+    assertNotNull(elementAtCaret);
+    final PsiExpression psiExpression = PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class);
+    assertInstanceOf(psiExpression, PsiLambdaExpression.class);
+    final PsiClass aClass = myFixture.findClass("Foo");
+    assertNotNull(aClass);
+    final PsiMethod[] meths = aClass.findMethodsByName("foo", false);
+    assertTrue(meths.length == 1);
+    return InferenceSession.isPertinentToApplicability(psiExpression, meths[0]);
+  }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceBackwardTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceBackwardTest.java
index fd9369a..07be23a 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceBackwardTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceBackwardTest.java
@@ -31,7 +31,6 @@
 import com.intellij.psi.PsiFile;
 import com.intellij.slicer.SliceAnalysisParams;
 import com.intellij.slicer.SliceHandler;
-import com.intellij.slicer.SliceManager;
 import com.intellij.slicer.SliceUsage;
 import com.intellij.util.CommonProcessors;
 import com.intellij.util.containers.IntArrayList;
@@ -59,7 +58,7 @@
     params.scope = new AnalysisScope(getProject());
     params.dataFlowToThis = true;
 
-    SliceUsage usage = SliceManager.createRootUsage(element, params);
+    SliceUsage usage = SliceUsage.createRootUsage(element, params);
     checkUsages(usage, true, myFlownOffsets);
   }
 
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceForwardTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceForwardTest.java
index 69c3547..7b2d307 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceForwardTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceForwardTest.java
@@ -23,7 +23,6 @@
 import com.intellij.psi.PsiElement;
 import com.intellij.slicer.SliceAnalysisParams;
 import com.intellij.slicer.SliceForwardHandler;
-import com.intellij.slicer.SliceManager;
 import com.intellij.slicer.SliceUsage;
 import com.intellij.util.containers.IntArrayList;
 import gnu.trove.TIntObjectHashMap;
@@ -49,7 +48,7 @@
     SliceAnalysisParams params = new SliceAnalysisParams();
     params.scope = new AnalysisScope(getProject());
     params.dataFlowToThis = false;
-    SliceUsage usage = SliceManager.createRootUsage(element, params);
+    SliceUsage usage = SliceUsage.createRootUsage(element, params);
     SliceBackwardTest.checkUsages(usage, false, myFlownOffsets);
   }
 
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java
index 624ec7f..771cfe3 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java
@@ -1,11 +1,9 @@
 package com.intellij.codeInsight.slice;
 
 import com.intellij.analysis.AnalysisScope;
-import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase;
 import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
 import com.intellij.codeInsight.daemon.impl.HighlightInfo;
 import com.intellij.ide.util.treeView.AbstractTreeNode;
-import com.intellij.lang.annotation.HighlightSeverity;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.wm.impl.ToolWindowHeadlessManagerImpl;
@@ -34,7 +32,7 @@
     params.scope = new AnalysisScope(getProject());
     params.dataFlowToThis = true;
 
-    SliceUsage usage = SliceManager.createRootUsage(element, params);
+    SliceUsage usage = SliceUsage.createRootUsage(element, params);
 
 
     SlicePanel panel = new SlicePanel(getProject(), true, new SliceRootNode(getProject(), new DuplicateMap(), usage), false, ToolWindowHeadlessManagerImpl.HEADLESS_WINDOW) {
@@ -252,7 +250,7 @@
   }
 
   private static void checkStructure(final SliceNode root, @NonNls String dataExpected) {
-    List<SliceNode> actualNodes = new ArrayList<SliceNode>((Collection<? extends SliceNode>)root.getChildren());
+    List<SliceNode> actualNodes = new ArrayList<SliceNode>((Collection)root.getChildren());
     Collections.sort(actualNodes, SliceTreeBuilder.SLICE_NODE_COMPARATOR);
 
     Object[] actualStrings = ContainerUtil.map2Array(actualNodes, new Function<SliceNode, Object>() {
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
index b0df0fb..cc9dee3 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
@@ -286,6 +286,7 @@
   public void testContractAnnotation() { doTest(); }
   public void testContractInLoopNotTooComplex() { doTest(); }
   public void testContractWithNullable() { doTest(); }
+  public void testContractPreservesUnknownNullability() { doTest(); }
 
   public void testBoxingImpliesNotNull() { doTest(); }
   public void testLargeIntegersAreNotEqualWhenBoxed() { doTest(); }
@@ -295,6 +296,12 @@
   public void testAnonymousMethodIndependence() { doTest(); }
   public void testAnonymousFieldIndependence() { doTest(); }
   public void testNoConfusionWithAnonymousConstantInitializer() { doTest(); }
+  public void testForeachOverWildcards() { doTest(); }
+  public void testFinalGetter() { doTest(); }
+  
+  public void testManySequentialIfsNotComplex() { doTest(); }
+  public void testLongDisjunctionsNotComplex() { doTest(); }
+  public void testWhileNotComplex() { doTest(); }
   
   public void _testNullCheckBeforeInstanceof() { doTest(); }
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java
index 480a910..1bd64f4 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java
@@ -15,6 +15,9 @@
  */
 package com.intellij.codeInspection;
 
+import com.intellij.codeInsight.completion.NormalCompletionTest;
+import com.intellij.codeInsight.completion.SmartTypeCompletionTest;
+import com.intellij.codeInsight.slice.SliceBackwardTest;
 import com.intellij.codeInsight.slice.SliceTreeTest;
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -25,6 +28,9 @@
     suite.addTestSuite(DataFlowInspectionTest.class);
     suite.addTestSuite(DataFlowInspectionAncientTest.class);
     suite.addTestSuite(SliceTreeTest.class);
+    suite.addTestSuite(SliceBackwardTest.class);
+    suite.addTestSuite(SmartTypeCompletionTest.class);
+    suite.addTestSuite(NormalCompletionTest.class);
     return suite;
   }
 }
diff --git a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
index e579fbb..49ff835 100644
--- a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
+++ b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
@@ -478,36 +478,36 @@
   private static void runFindForwardAndBackward(FindManager findManager, FindModel findModel, String text, String ext) {
     findModel.setForward(true);
     LightVirtualFile file = new LightVirtualFile("A."+ext, text);
-    int prevousOffset;
+    int previousOffset;
 
     FindResult findResult = findManager.findString(text, 0, findModel, file);
     assertTrue(findResult.isStringFound());
-    prevousOffset = findResult.getStartOffset();
+    previousOffset = findResult.getStartOffset();
 
     findResult = findManager.findString(text, findResult.getEndOffset(), findModel, file);
     assertTrue(findResult.isStringFound());
-    assertTrue(findResult.getStartOffset() > prevousOffset);
-    prevousOffset = findResult.getStartOffset();
+    assertTrue(findResult.getStartOffset() > previousOffset);
+    previousOffset = findResult.getStartOffset();
 
     findResult = findManager.findString(text, findResult.getEndOffset(), findModel, file);
     assertTrue(findResult.isStringFound());
-    assertTrue(findResult.getStartOffset() > prevousOffset);
+    assertTrue(findResult.getStartOffset() > previousOffset);
 
     findModel.setForward(false);
 
     findResult = findManager.findString(text, text.length(), findModel, file);
     assertTrue(findResult.isStringFound());
-    prevousOffset = findResult.getStartOffset();
+    previousOffset = findResult.getStartOffset();
 
-    findResult = findManager.findString(text, prevousOffset, findModel, file);
+    findResult = findManager.findString(text, previousOffset, findModel, file);
     assertTrue(findResult.isStringFound());
-    assertTrue(prevousOffset > findResult.getStartOffset() );
+    assertTrue(previousOffset > findResult.getStartOffset() );
 
-    prevousOffset = findResult.getStartOffset();
+    previousOffset = findResult.getStartOffset();
 
-    findResult = findManager.findString(text, prevousOffset, findModel, file);
+    findResult = findManager.findString(text, previousOffset, findModel, file);
     assertTrue(findResult.isStringFound());
-    assertTrue(prevousOffset > findResult.getStartOffset() );
+    assertTrue(previousOffset > findResult.getStartOffset() );
   }
 
   public void testFindInJavaDocs() throws Exception{
@@ -547,4 +547,35 @@
 
     runFindInCommentsAndLiterals(findManager, findModel, text, "cs");
   }
+
+  public void testFindInLiteralToSkipQuotes() throws Exception{
+    FindManager findManager = FindManager.getInstance(myProject);
+
+    FindModel findModel = new FindModel();
+    findModel.setStringToFind("^done$");
+    findModel.setWholeWordsOnly(false);
+    findModel.setRegularExpressions(true);
+    findModel.setFromCursor(false);
+    findModel.setGlobal(true);
+    findModel.setMultipleFiles(false);
+    findModel.setProjectScope(true);
+
+    String text = "\"done\"; 'done'; 'done' \"done2\"";
+
+    findModel.setInStringLiteralsOnly(true);
+    findModel.setInCommentsOnly(false);
+    runFindForwardAndBackward(findManager, findModel, text, "java");
+
+    text = "def n = \"\"\"done\"\"\"\n def n = /done/\n def n = \"done\"\n def n = \"done2\"";
+
+    runFindForwardAndBackward(findManager, findModel, text, "groovy");
+
+    text = "\"\"; \"done\"; 'done'; 'done' \"done2\"";
+
+    findModel.setStringToFind("done");
+    findModel.setWholeWordsOnly(true);
+    findModel.setRegularExpressions(false);
+
+    runFindForwardAndBackward(findManager, findModel, text, "java");
+  }
 }
diff --git a/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java b/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
index 72e9c2a..80dda6dc 100644
--- a/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
+++ b/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
@@ -42,6 +42,6 @@
 
   public void testMatcher1()          throws Exception {checkTree("ico");}
   public void testMatcher2()          throws Exception {checkTree("ico");}
-  @Bombed(user = "peter", month = Calendar.SEPTEMBER, day = 20)
+  @Bombed(user = "peter", month = Calendar.DECEMBER, day = 20)
   public void testAnonymousMatcher2() throws Exception {checkTree("ico");}
 }
diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy
index 0b4e838..b456d41 100644
--- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy
@@ -131,4 +131,16 @@
 }'''
     doTest(initial: text, expected: text, rules: [rule(CLASS)] )
   }
+
+  void "test statements on the same line"() {
+    def before = '''\
+
+
+
+public enum Sender {a, b; private String value;
+}
+'''
+    doTest(initial: before, expected: before)
+  }
+
 }
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBracesTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBracesTest.java
index 889e591..2e2d0c5 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBracesTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBracesTest.java
@@ -155,4 +155,14 @@
       "}";
     doTextTest(text, text);
   }
+
+  public void testSimpleMethodsInOneLineEvenIfExceedsRightMargin() {
+    getSettings().KEEP_SIMPLE_METHODS_IN_ONE_LINE = true;
+    getSettings().getRootSettings().RIGHT_MARGIN = 90;
+    String text = "public class Repr2 {\n" +
+                  "    public void start() { System.out.println(\"kfjsdkfjsdkfjskdjfslkdjfklsdjfklsdjfksjdfkljsdkfjsd!\"); }\n" +
+                  "}";
+    doTextTest(text, text);
+  }
+
 }
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java
index be33547..b347207 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java
@@ -536,4 +536,13 @@
     getIndentOptions().USE_TAB_CHARACTER = true;
     doTextTest(initial, expected);
   }
+
+  public void testLambdaIndentation() throws Exception {
+    String before = "Runnable r = () ->\n" +
+                    "{\n" +
+                    "    System.out.println(\"olo\");\n" +
+                    "};";
+    doMethodTest(before, before);
+  }
+
 }
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterSpaceTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterSpaceTest.java
index ab35904..e78f718 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterSpaceTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterSpaceTest.java
@@ -33,6 +33,34 @@
                "class Foo {\n" + "    Map<String, String> map() {\n" + "    }\n" + "}");
   }
 
+  public void testDoNotPlaceStatementsOnOneLineIfFirstEndsWithSingleLineComment() {
+    getSettings().KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE = true;
+    getSettings().KEEP_LINE_BREAKS = false;
+    String before = "public class Reproduce {\n" +
+                    "    public void start() {\n" +
+                    "        if (true)\n" +
+                    "            return; // comment\n" +
+                    "        final int count = 5;\n" +
+                    "        for (int i = 0; i < count; i++) {\n" +
+                    "            System.out.println(\"AAA!\");\n" +
+                    "            System.out.println(\"BBB!\"); // ololol\n" +
+                    "            System.out.println(\"asda\"); /* ololo */\n" +
+                    "            System.out.println(\"booo\");\n" +
+                    "        }\n" +
+                    "    }\n" +
+                    "}";
+    String after = "public class Reproduce {\n" +
+                   "    public void start() {\n" +
+                   "        if (true) return; // comment\n" +
+                   "        final int count = 5; for (int i = 0; i < count; i++) {\n" +
+                   "            System.out.println(\"AAA!\"); System.out.println(\"BBB!\"); // ololol\n" +
+                   "            System.out.println(\"asda\"); /* ololo */ System.out.println(\"booo\");\n" +
+                   "        }\n" +
+                   "    }\n" +
+                   "}";
+    doTextTest(before, after);
+  }
+
   public void testSpaceBeforeAnnotationParamArray() {
     // Inspired by IDEA-24329
     getSettings().SPACE_BEFORE_ANNOTATION_ARRAY_INITIALIZER_LBRACE = true;
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java
index 695ac71..68dbf09 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java
@@ -2972,4 +2972,33 @@
                "    }\n" +
                "}");
   }
+
+  public void testCommaInMethodDeclParamsList() {
+    getSettings().SPACE_AFTER_COMMA = true;
+    String before = "public class Test {\n" +
+                    "    public static void act(   int a   ,    int b   ,    int c   ,      int d) {\n" +
+                    "        act(1,2,3,4);\n" +
+                    "    }\n" +
+                    "}\n";
+    String after = "public class Test {\n" +
+                   "    public static void act(int a, int b, int c, int d) {\n" +
+                   "        act(1, 2, 3, 4);\n" +
+                   "    }\n" +
+                   "}\n";
+    doTextTest(before, after);
+    getSettings().SPACE_AFTER_COMMA = false;
+    before = "public class Test {\n" +
+             "    public static void act(   int a   ,    int b   ,      int c   ,      int d) {\n" +
+             "        act(1 ,   2 , 3 ,            4);\n" +
+             "    }\n" +
+             "}\n";
+    after = "public class Test {\n" +
+            "    public static void act(int a,int b,int c,int d) {\n" +
+            "        act(1,2,3,4);\n" +
+            "    }\n" +
+            "}\n";
+    doTextTest(before, after);
+  }
+
+
 }
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/EncapsulateFieldsTest.java b/java/java-tests/testSrc/com/intellij/refactoring/EncapsulateFieldsTest.java
index fd536cb..dd3af4b 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/EncapsulateFieldsTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/EncapsulateFieldsTest.java
@@ -43,11 +43,11 @@
   }
 
   public void testDiffWithReturnTypeOnly() throws Exception {
-    doTest("i", "There already is a method <b><code>Test setI(int)</code></b> which differs from setter <b><code>setI</code></b> by return type only.");
+    doTest("i", "There is already method <b><code>Test setI(int)</code></b> which differs from setter <b><code>setI</code></b> by return type only");
   }
 
    public void testDiffWithReturnTypeOnlyInHierarchy() throws Exception {
-    doTest("i", "There already is a method <b><code>Super setI(int)</code></b> which differs from setter <b><code>setI</code></b> by return type only.");
+    doTest("i", "There is already method <b><code>Super setI(int)</code></b> which differs from setter <b><code>setI</code></b> by return type only");
   }
 
   public void testHideOverriderMethod() throws Exception {
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java
index b5ec296..5be5dad 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java
@@ -59,6 +59,15 @@
     });
   }
 
+  public void testReplaceAll3() throws Exception {
+    doTest(new Pass<AbstractInplaceIntroducer>() {
+      @Override
+      public void pass(AbstractInplaceIntroducer inplaceIntroduceFieldPopup) {
+        inplaceIntroduceFieldPopup.setReplaceAllOccurrences(true);
+      }
+    });
+  }
+
   public void testReplaceAllMethodCalls() throws Exception {
     doTest(new Pass<AbstractInplaceIntroducer>() {
       @Override
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java
index 5fff219..618381a 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java
@@ -1,4 +1,20 @@
 /*
+ * 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.
+ */
+
+/*
  * Created by IntelliJ IDEA.
  * User: dsl
  * Date: 07.05.2002
@@ -114,7 +130,7 @@
   }
 
   public void testSuperInExpression() throws Exception {
-    doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
+    doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
   }
 
   public void testNull() throws Exception {
@@ -150,7 +166,7 @@
   }
 
   public void testSuperWithSideEffect() throws Exception {
-    doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
+    doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
   }
 
   public void testConflictingField() throws Exception {
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java
index a447fa1..07f3a61 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java
@@ -149,8 +149,8 @@
       protected boolean reportConflicts(MultiMap<PsiElement,String> conflicts, final Project project, IntroduceVariableSettings dialog) {
         assertEquals(2, conflicts.size());
         Collection<? extends String> conflictsMessages = conflicts.values();
-        assertTrue(conflictsMessages.contains("Introducing variable may break code logic."));
-        assertTrue(conflictsMessages.contains("Local variable <b><code>c</code></b> is modified in loop body."));
+        assertTrue(conflictsMessages.contains("Introducing variable may break code logic"));
+        assertTrue(conflictsMessages.contains("Local variable <b><code>c</code></b> is modified in loop body"));
         return false;
       }
     });
@@ -242,7 +242,7 @@
     }
     catch (Exception e) {
       assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" +
-                                   "Selected block should represent an expression.");
+                                   "Selected block should represent an expression");
       return;
     }
     fail("Should not be able to perform refactoring");
@@ -254,7 +254,7 @@
     }
     catch (Exception e) {
       assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" +
-                                   "Selected block should represent an expression.");
+                                   "Selected block should represent an expression");
       return;
     }
     fail("Should not be able to perform refactoring");
@@ -366,7 +366,7 @@
     }
     catch (Exception e) {
       assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" +
-                                   "Selected block should represent an expression.");
+                                   "Selected block should represent an expression");
       return;
     }
     fail("Should not be able to perform refactoring");
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MoveClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MoveClassTest.java
index bcaabef..c646301 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/MoveClassTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/MoveClassTest.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.
@@ -78,7 +78,7 @@
       fail("Conflicts expected");
     }
     catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
-      assertEquals("A package-local class <b><code>Class2</code></b> will no longer be accessible from field <b><code>User.class2</code></b>", e.getMessage());
+      assertEquals("Package-local class <b><code>Class2</code></b> will no longer be accessible from field <b><code>User.class2</code></b>", e.getMessage());
     }
   }
 
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java b/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java
index 2caa921..9bc767a 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java
@@ -1,3 +1,18 @@
+/*
+ * 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.refactoring;
 
 import com.intellij.JavaTestUtil;
@@ -172,7 +187,7 @@
       doTest("foo1");
     }
     catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
-      Assert.assertEquals("Method with same erasure is already defined in the class <b><code>RenameTest</code></b>.", e.getMessage());
+      Assert.assertEquals("Method with same erasure is already defined in the class <b><code>RenameTest</code></b>", e.getMessage());
       return;
     }
     fail("Conflicts were not found");
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java b/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java
index f72add5..f771665 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 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.
@@ -81,7 +81,7 @@
       doTestInplaceRename("bar");
     }
     catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
-      assertEquals("Method bar() is already defined in the class <b><code>Foo</code></b>.", e.getMessage());
+      assertEquals("Method bar() is already defined in the class <b><code>Foo</code></b>", e.getMessage());
       checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
       return;
     }
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameMethodMultiTest.java b/java/java-tests/testSrc/com/intellij/refactoring/RenameMethodMultiTest.java
index f2b52e1..6da0cdf 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/RenameMethodMultiTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameMethodMultiTest.java
@@ -1,5 +1,21 @@
+/*
+ * 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.refactoring;
 
+import com.intellij.JavaTestUtil;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.JavaPsiFacade;
@@ -7,7 +23,6 @@
 import com.intellij.psi.PsiMethod;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.refactoring.rename.RenameProcessor;
-import com.intellij.JavaTestUtil;
 import org.junit.Assert;
 
 /**
@@ -51,7 +66,7 @@
     catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
       Assert.assertEquals("Renaming method will override final \"method <b><code>A.finalMethod()</code></b>\"\n" +
                           "Method finalMethod() will override \n" +
-                          "a method of the base class <b><code>p.A</code></b>.", e.getMessage());
+                          "a method of the base class <b><code>p.A</code></b>", e.getMessage());
       return;
     }
     fail("Conflicts were not found");
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java
index 6d66a43..4cf3229 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java
@@ -1,3 +1,18 @@
+/*
+ * 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.refactoring.inline;
 
 import com.intellij.JavaTestUtil;
@@ -108,11 +123,11 @@
   }
 
   public void testAnotherDefinitionUsed() throws Exception {
-    doTest(true, "Cannot perform refactoring.\nAnother variable 'bar' definition is used together with inlined one.");
+    doTest(true, "Cannot perform refactoring.\nAnother variable 'bar' definition is used together with inlined one");
   }
 
   public void testAnotherDefinitionUsed1() throws Exception {
-    doTest(false, "Cannot perform refactoring.\nAnother variable 'bar' definition is used together with inlined one.");
+    doTest(false, "Cannot perform refactoring.\nAnother variable 'bar' definition is used together with inlined one");
   }
 
   public void testTypeArgumentsStatic() throws Exception {
@@ -137,7 +152,7 @@
 
   public void testAssignmentToArrayElement() throws Exception {
     doTest(true, "Cannot perform refactoring.\n" +
-                 "Variable 'arr' is accessed for writing.");
+                 "Variable 'arr' is accessed for writing");
   }
 
   public void testArrayMethodCallInitialized() throws Exception {
@@ -150,7 +165,7 @@
 
   public void testNonEqAssignment() throws Exception {
     doTest(false, "Cannot perform refactoring.\n" +
-                  "Variable 'x' is accessed for writing.");
+                  "Variable 'x' is accessed for writing");
   }
 
   public void testInlineFromTryCatch() throws Exception {
@@ -223,7 +238,7 @@
 
   public void testLocalVarInsideLambdaBodyWriteUsage() throws Exception {
     doTest(true, "Cannot perform refactoring.\n" +
-                 "Variable 'hello' is accessed for writing.");
+                 "Variable 'hello' is accessed for writing");
   }
 
   private void doTest(final boolean inlineDef, String conflictMessage) throws Exception {
diff --git a/java/jdkAnnotations/java/util/annotations.xml b/java/jdkAnnotations/java/util/annotations.xml
index 9699f06c..4d202ed 100644
--- a/java/jdkAnnotations/java/util/annotations.xml
+++ b/java/jdkAnnotations/java/util/annotations.xml
@@ -462,12 +462,7 @@
   <item name="java.util.Arrays void sort(short[], int, int) 0">
     <annotation name="org.jetbrains.annotations.NotNull" />
   </item>
-  <item name="java.util.Calendar void add(int, int) 0" >
-    <annotation name="org.intellij.lang.annotations.MagicConstant">
-      <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
-    </annotation>
-  </item>
-  <item name="java.util.Calendar void clear(int) 0" >
+  <item name="java.util.Calendar boolean isSet(int) 0">
     <annotation name="org.intellij.lang.annotations.MagicConstant">
       <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
     </annotation>
@@ -487,26 +482,6 @@
       <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
     </annotation>
   </item>
-  <item name="java.util.Calendar java.lang.String getDisplayName(int, int, java.util.Locale) 0">
-    <annotation name="org.intellij.lang.annotations.MagicConstant">
-      <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
-    </annotation>
-  </item>
-  <item name="java.util.Calendar java.lang.String getDisplayName(int, int, java.util.Locale) 1">
-    <annotation name="org.intellij.lang.annotations.MagicConstant">
-      <val name="intValues" val="{java.util.Calendar.SHORT, java.util.Calendar.LONG}" />
-    </annotation>
-  </item>
-  <item name="java.util.Calendar java.util.Map&lt;java.lang.String,java.lang.Integer&gt; getDisplayNames(int, int, java.util.Locale) 0">
-    <annotation name="org.intellij.lang.annotations.MagicConstant">
-      <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
-    </annotation>
-  </item>
-  <item name="java.util.Calendar java.util.Map&lt;java.lang.String,java.lang.Integer&gt; getDisplayNames(int, int, java.util.Locale) 1">
-    <annotation name="org.intellij.lang.annotations.MagicConstant">
-      <val name="intValues" val="{java.util.Calendar.SHORT, java.util.Calendar.LONG, java.util.Calendar.ALL_STYLES}" />
-    </annotation>
-  </item>
   <item name="java.util.Calendar int getFirstDayOfWeek()">
     <annotation name="org.intellij.lang.annotations.MagicConstant">
       <val name="intValues" val="{java.util.Calendar.SUNDAY, java.util.Calendar.MONDAY, java.util.Calendar.TUESDAY, java.util.Calendar.WEDNESDAY, java.util.Calendar.THURSDAY, java.util.Calendar.FRIDAY, java.util.Calendar.SATURDAY}" />
@@ -532,7 +507,32 @@
       <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
     </annotation>
   </item>
-  <item name="java.util.Calendar boolean isSet(int) 0">
+  <item name="java.util.Calendar java.lang.String getDisplayName(int, int, java.util.Locale) 0">
+    <annotation name="org.intellij.lang.annotations.MagicConstant">
+      <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
+    </annotation>
+  </item>
+  <item name="java.util.Calendar java.lang.String getDisplayName(int, int, java.util.Locale) 1">
+    <annotation name="org.intellij.lang.annotations.MagicConstant">
+      <val name="intValues" val="{java.util.Calendar.SHORT, java.util.Calendar.LONG}" />
+    </annotation>
+  </item>
+  <item name="java.util.Calendar java.util.Map&lt;java.lang.String,java.lang.Integer&gt; getDisplayNames(int, int, java.util.Locale) 0">
+    <annotation name="org.intellij.lang.annotations.MagicConstant">
+      <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
+    </annotation>
+  </item>
+  <item name="java.util.Calendar java.util.Map&lt;java.lang.String,java.lang.Integer&gt; getDisplayNames(int, int, java.util.Locale) 1">
+    <annotation name="org.intellij.lang.annotations.MagicConstant">
+      <val name="intValues" val="{java.util.Calendar.SHORT, java.util.Calendar.LONG, java.util.Calendar.ALL_STYLES}" />
+    </annotation>
+  </item>
+  <item name="java.util.Calendar void add(int, int) 0" >
+    <annotation name="org.intellij.lang.annotations.MagicConstant">
+      <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
+    </annotation>
+  </item>
+  <item name="java.util.Calendar void clear(int) 0" >
     <annotation name="org.intellij.lang.annotations.MagicConstant">
       <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
     </annotation>
diff --git a/java/jdkAnnotations/java/util/regex/annotations.xml b/java/jdkAnnotations/java/util/regex/annotations.xml
index b3f189e..2afbcb5 100644
--- a/java/jdkAnnotations/java/util/regex/annotations.xml
+++ b/java/jdkAnnotations/java/util/regex/annotations.xml
@@ -11,10 +11,17 @@
       <val name="flagsFromClass" val="java.util.regex.Pattern.class" />
     </annotation>
   </item>
+  <item name='java.util.regex.Pattern java.util.regex.Matcher matcher(java.lang.CharSequence)'>
+    <annotation name='org.jetbrains.annotations.NotNull'/>
+  </item>
   <item name="java.util.regex.Pattern java.util.regex.Pattern compile(java.lang.String) 0">
     <annotation name="org.jetbrains.annotations.NonNls" />
     <annotation name="org.jetbrains.annotations.NotNull" />
   </item>
+  <item name="java.util.regex.Pattern java.util.regex.Pattern compile(java.lang.String, int) 0">
+    <annotation name="org.jetbrains.annotations.NonNls" />
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
   <item name="java.util.regex.Pattern java.util.regex.Pattern compile(java.lang.String, int) 1">
     <annotation name="org.intellij.lang.annotations.MagicConstant">
       <val name="flagsFromClass" val="java.util.regex.Pattern.class" />
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestLexer.java b/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestLexer.java
index 26741c2..1372768 100644
--- a/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestLexer.java
+++ b/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestLexer.java
@@ -27,6 +27,7 @@
 import com.intellij.lexer.LexerBase;
 import com.intellij.psi.TokenType;
 import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.lang.manifest.psi.ManifestTokenType;
 
@@ -63,7 +64,7 @@
   private IElementType myTokenType;
 
   @Override
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     this.myBuffer = buffer;
     this.myEndOffset = endOffset;
     myCurrentState = State.values()[initialState];
@@ -104,6 +105,7 @@
     return myEndOffset;
   }
 
+  @NotNull
   @Override
   public CharSequence getBufferSequence() {
     return myBuffer;
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java
index 60bf96c..52a24e8 100644
--- a/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java
@@ -24,8 +24,11 @@
 import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.vfs.VirtualFileFilter;
+import com.intellij.psi.JavaPsiFacade;
 import com.intellij.psi.PsiDocumentManager;
 import com.intellij.psi.PsiFile;
+import com.intellij.psi.impl.source.resolve.PsiResolveHelperImpl;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiGraphInferenceHelper;
 import com.intellij.testFramework.ExpectedHighlightingData;
 import com.intellij.testFramework.FileTreeAccessFilter;
 import com.intellij.testFramework.HighlightTestInfo;
@@ -80,6 +83,18 @@
     doTestConfiguredFile(checkWarnings, checkInfos, filePath);
   }
 
+  protected void doTestNewInference(@NonNls String filePath, boolean checkWarnings, boolean checkInfos) {
+    final PsiResolveHelperImpl helper = (PsiResolveHelperImpl)JavaPsiFacade.getInstance(getProject()).getResolveHelper();
+    //helper.setTestHelper(new PsiGraphInferenceHelper(getPsiManager()));
+    try {
+      configureByFile(filePath);
+      doTestConfiguredFile(checkWarnings, checkInfos, filePath);
+    }
+    finally {
+      helper.setTestHelper(null);
+    }
+  }
+
   protected void doTest(@NonNls String filePath, boolean checkWarnings, boolean checkWeakWarnings, boolean checkInfos) {
     configureByFile(filePath);
     doTestConfiguredFile(checkWarnings, checkWeakWarnings, checkInfos, filePath);
diff --git a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java
index 7164207..348a1af 100644
--- a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java
+++ b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java
@@ -80,7 +80,7 @@
   public static void enableExternalCompiler(final Project project) {
     new WriteAction() {
       protected void run(final Result result) {
-        CompilerWorkspaceConfiguration.getInstance(project).USE_COMPILE_SERVER = true;
+        CompilerWorkspaceConfiguration.getInstance(project).USE_OUT_OF_PROCESS_BUILD = true;
         ApplicationManagerEx.getApplicationEx().doNotSave(false);
         JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
         table.addJdk(table.getInternalJdk());
@@ -91,7 +91,7 @@
   public static void disableExternalCompiler(final Project project) {
     new WriteAction() {
       protected void run(final Result result) {
-        CompilerWorkspaceConfiguration.getInstance(project).USE_COMPILE_SERVER = false;
+        CompilerWorkspaceConfiguration.getInstance(project).USE_OUT_OF_PROCESS_BUILD = false;
         ApplicationManagerEx.getApplicationEx().doNotSave(true);
         JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
         table.removeJdk(table.getInternalJdk());
diff --git a/java/testFramework/src/com/intellij/ide/projectWizard/NewProjectWizardTestCase.java b/java/testFramework/src/com/intellij/ide/projectWizard/NewProjectWizardTestCase.java
new file mode 100644
index 0000000..8ae8848
--- /dev/null
+++ b/java/testFramework/src/com/intellij/ide/projectWizard/NewProjectWizardTestCase.java
@@ -0,0 +1,18 @@
+package com.intellij.ide.projectWizard;
+
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+
+import java.io.File;
+
+/**
+ * @author Dmitry Avdeev
+ *         Date: 23.09.13
+ */
+public abstract class NewProjectWizardTestCase extends ProjectWizardTestCase {
+  @Override
+  protected AbstractProjectWizard createWizard(Project project, File directory) {
+    return new NewProjectWizard(project, ModulesProvider.EMPTY_MODULES_PROVIDER, directory.getPath());
+  }
+}
diff --git a/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
index 9620aa7..8a05be2 100644
--- a/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
+++ b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
@@ -2,10 +2,11 @@
 
 import com.intellij.ide.actions.ImportModuleAction;
 import com.intellij.ide.impl.NewProjectUtil;
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
 import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
 import com.intellij.ide.util.newProjectWizard.SelectTemplateSettings;
 import com.intellij.ide.util.newProjectWizard.SelectTemplateStep;
-import com.intellij.ide.util.projectWizard.ModuleWizardStep;
+import com.intellij.ide.wizard.Step;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
@@ -38,14 +39,15 @@
  * @author Dmitry Avdeev
  *         Date: 10/29/12
  */
-public abstract class ProjectWizardTestCase extends PlatformTestCase {
+@SuppressWarnings("unchecked")
+public abstract class ProjectWizardTestCase<T extends AbstractProjectWizard> extends PlatformTestCase {
 
   protected final List<Sdk> mySdks = new ArrayList<Sdk>();
-  protected AddModuleWizard myWizard;
+  protected T myWizard;
   @Nullable
   private Project myCreatedProject;
 
-  protected Project createProjectFromTemplate(String group, String name, @Nullable Consumer<ModuleWizardStep> adjuster) throws IOException {
+  protected Project createProjectFromTemplate(String group, String name, @Nullable Consumer<Step> adjuster) throws IOException {
     runWizard(group, name, null, adjuster);
     try {
       myCreatedProject = NewProjectUtil.createFromWizard(myWizard, null);
@@ -68,7 +70,7 @@
   }
 
   @Nullable
-  protected Module createModuleFromTemplate(String group, String name, @Nullable Consumer<ModuleWizardStep> adjuster) throws IOException {
+  protected Module createModuleFromTemplate(String group, String name, @Nullable Consumer<Step> adjuster) throws IOException {
     runWizard(group, name, getProject(), adjuster);
     return createModuleFromWizard();
   }
@@ -77,7 +79,7 @@
     return new NewModuleAction().createModuleFromWizard(myProject, null, myWizard);
   }
 
-  protected void runWizard(String group, String name, Project project, @Nullable Consumer<ModuleWizardStep> adjuster) throws IOException {
+  protected void runWizard(String group, String name, Project project, @Nullable Consumer<Step> adjuster) throws IOException {
 
     createWizard(project);
     SelectTemplateStep step = (SelectTemplateStep)myWizard.getCurrentStepObject();
@@ -98,11 +100,22 @@
   protected void createWizard(Project project) throws IOException {
     File directory = FileUtil.createTempDirectory(getName(), "new", false);
     myFilesToDelete.add(directory);
-    myWizard = new AddModuleWizard(project, DefaultModulesProvider.createForProject(project), directory.getPath());
+    myWizard = createWizard(project, directory);
     UIUtil.dispatchAllInvocationEvents(); // to make default selection applied
   }
 
-  protected void runWizard(Consumer<ModuleWizardStep> adjuster) {
+  protected Project createProject(Consumer<Step> adjuster) throws IOException {
+    createWizard(getProject());
+    runWizard(adjuster);
+    myCreatedProject = NewProjectUtil.createFromWizard(myWizard, null);
+    return myCreatedProject;
+  }
+
+  protected T createWizard(Project project, File directory) {
+    return (T)new AddModuleWizard(project, DefaultModulesProvider.createForProject(project), directory.getPath());
+  }
+
+  protected void runWizard(Consumer<Step> adjuster) {
     while (!myWizard.isLast()) {
       myWizard.doNextAction();
       if (adjuster != null) {
@@ -157,7 +170,7 @@
     return importFrom(path, getProject(), null, provider);
   }
 
-  protected Module importProjectFrom(String path, Consumer<ModuleWizardStep> adjuster, ProjectImportProvider... providers) {
+  protected Module importProjectFrom(String path, Consumer<Step> adjuster, ProjectImportProvider... providers) {
     Module module = importFrom(path, null, adjuster, providers);
     if (module != null) {
       myCreatedProject = module.getProject();
@@ -166,13 +179,14 @@
   }
 
   private Module importFrom(String path,
-                            @Nullable Project project, Consumer<ModuleWizardStep> adjuster,
+                            @Nullable Project project, Consumer<Step> adjuster,
                             final ProjectImportProvider... providers) {
     VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
     assertNotNull("Can't find " + path, file);
     assertTrue(providers[0].canImport(file, project));
 
-    myWizard = ImportModuleAction.createImportWizard(project, null, file, providers);
+    myWizard = (T)ImportModuleAction.createImportWizard(project, null, file, providers);
+    assertNotNull(myWizard);
     if (myWizard.getStepCount() > 0) {
       runWizard(adjuster);
     }
diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementType.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementType.java
index 1adee50..5ee5146 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/JpsElementType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementType.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.
@@ -15,13 +15,17 @@
  */
 package org.jetbrains.jps.model;
 
+import org.jetbrains.annotations.NotNull;
+
 /**
+ * Base interface for all types of elements in JPS model
+ *
+ * <p>
+ * Use {@link org.jetbrains.jps.model.ex.JpsElementTypeBase} as a base class for all implementations of this interface
+ * </p>
  * @author nik
  */
-public abstract class JpsElementType<P extends JpsElement> {
-  private final JpsElementChildRole<P> myPropertiesRole = new JpsElementChildRole<P>();
-
-  public final JpsElementChildRole<P> getPropertiesRole() {
-    return myPropertiesRole;
-  }
+public interface JpsElementType<P extends JpsElement> {
+  @NotNull
+  JpsElementChildRole<P> getPropertiesRole();
 }
diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/DirectoryArtifactType.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/DirectoryArtifactType.java
index 3b66462..79e970e 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/artifact/DirectoryArtifactType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/DirectoryArtifactType.java
@@ -16,10 +16,11 @@
 package org.jetbrains.jps.model.artifact;
 
 import org.jetbrains.jps.model.JpsDummyElement;
+import org.jetbrains.jps.model.ex.JpsElementTypeWithDummyProperties;
 
 /**
  * @author nik
  */
-public class DirectoryArtifactType extends JpsArtifactType<JpsDummyElement> {
+public class DirectoryArtifactType extends JpsElementTypeWithDummyProperties implements JpsArtifactType<JpsDummyElement> {
   public static final DirectoryArtifactType INSTANCE = new DirectoryArtifactType();
 }
diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/JarArtifactType.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/JarArtifactType.java
index c0306a9..bd36fc4 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/artifact/JarArtifactType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/JarArtifactType.java
@@ -16,10 +16,11 @@
 package org.jetbrains.jps.model.artifact;
 
 import org.jetbrains.jps.model.JpsDummyElement;
+import org.jetbrains.jps.model.ex.JpsElementTypeWithDummyProperties;
 
 /**
  * @author nik
  */
-public class JarArtifactType extends JpsArtifactType<JpsDummyElement> {
+public class JarArtifactType extends JpsElementTypeWithDummyProperties implements JpsArtifactType<JpsDummyElement> {
   public static final JarArtifactType INSTANCE = new JarArtifactType();
 }
diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactType.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactType.java
index a4a6c31..fe05178 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactType.java
@@ -19,7 +19,12 @@
 import org.jetbrains.jps.model.JpsElementType;
 
 /**
+ * Represents a type of artifacts in JPS model
+ *
+ * <p>
+ * Use {@link org.jetbrains.jps.model.ex.JpsElementTypeBase} as a base class for implementations of this interface
+ * </p>
  * @author nik
  */
-public abstract class JpsArtifactType<P extends JpsElement> extends JpsElementType<P> {
+public interface JpsArtifactType<P extends JpsElement> extends JpsElementType<P> {
 }
diff --git a/jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementTypeBase.java b/jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementTypeBase.java
new file mode 100644
index 0000000..7894697
--- /dev/null
+++ b/jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementTypeBase.java
@@ -0,0 +1,39 @@
+/*
+ * 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.model.ex;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.JpsElementChildRole;
+import org.jetbrains.jps.model.JpsElementType;
+
+/**
+ * A base class for all implementations of {@link org.jetbrains.jps.model.JpsElementType}.
+ *
+ * <p>
+ * If elements of your type don't have any specific properties extend {@link JpsElementTypeWithDummyProperties} instead.
+ * </p>
+ * @author nik
+ */
+public abstract class JpsElementTypeBase<P extends JpsElement>implements JpsElementType<P> {
+  private final JpsElementChildRole<P> myPropertiesRole = new JpsElementChildRole<P>();
+
+  @NotNull
+  @Override
+  public final JpsElementChildRole<P> getPropertiesRole() {
+    return myPropertiesRole;
+  }
+}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementTypeWithDummyProperties.java b/jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementTypeWithDummyProperties.java
new file mode 100644
index 0000000..630340e
--- /dev/null
+++ b/jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementTypeWithDummyProperties.java
@@ -0,0 +1,34 @@
+/*
+ * 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.model.ex;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.JpsDummyElement;
+import org.jetbrains.jps.model.JpsElementFactory;
+import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
+
+/**
+ * A base class for type elements without any specific properties
+ *
+ * @author nik
+ */
+public abstract class JpsElementTypeWithDummyProperties extends JpsElementTypeBase<JpsDummyElement> implements JpsElementTypeWithDefaultProperties<JpsDummyElement> {
+  @NotNull
+  @Override
+  public JpsDummyElement createDefaultProperties() {
+    return JpsElementFactory.getInstance().createDummyElement();
+  }
+}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JavaResourceRootType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JavaResourceRootType.java
index 7baa1a9..33adf96 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/java/JavaResourceRootType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/JavaResourceRootType.java
@@ -18,13 +18,13 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.jps.model.JpsDummyElement;
 import org.jetbrains.jps.model.JpsElementFactory;
-import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
+import org.jetbrains.jps.model.ex.JpsElementTypeWithDummyProperties;
 import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 
 /**
  * @author nik
  */
-public class JavaResourceRootType extends JpsModuleSourceRootType<JpsDummyElement> implements JpsElementTypeWithDefaultProperties<JpsDummyElement> {
+public class JavaResourceRootType extends JpsElementTypeWithDummyProperties implements JpsModuleSourceRootType<JpsDummyElement> {
   public static final JavaResourceRootType RESOURCE = new JavaResourceRootType();
   public static final JavaResourceRootType TEST_RESOURCE = new JavaResourceRootType();
 
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootType.java
index 2a181f1..97a0368 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootType.java
@@ -17,14 +17,14 @@
 
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.jps.model.JpsElementFactory;
-import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
 import org.jetbrains.jps.model.JpsSimpleElement;
+import org.jetbrains.jps.model.ex.JpsElementTypeBase;
 import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 
 /**
  * @author nik
  */
-public class JavaSourceRootType extends JpsModuleSourceRootType<JpsSimpleElement<JavaSourceRootProperties>> implements JpsElementTypeWithDefaultProperties<JpsSimpleElement<JavaSourceRootProperties>> {
+public class JavaSourceRootType extends JpsElementTypeBase<JpsSimpleElement<JavaSourceRootProperties>> implements JpsModuleSourceRootType<JpsSimpleElement<JavaSourceRootProperties>> {
   public static final JavaSourceRootType SOURCE = new JavaSourceRootType();
   public static final JavaSourceRootType TEST_SOURCE = new JavaSourceRootType();
 
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaLibraryType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaLibraryType.java
index 5330360..0fcc7ec 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaLibraryType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaLibraryType.java
@@ -16,13 +16,15 @@
 package org.jetbrains.jps.model.java;
 
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jps.model.*;
+import org.jetbrains.jps.model.JpsDummyElement;
+import org.jetbrains.jps.model.JpsElementFactory;
+import org.jetbrains.jps.model.ex.JpsElementTypeWithDummyProperties;
 import org.jetbrains.jps.model.library.JpsLibraryType;
 
 /**
  * @author nik
  */
-public class JpsJavaLibraryType extends JpsLibraryType<JpsDummyElement> implements JpsElementTypeWithDefaultProperties<JpsDummyElement> {
+public class JpsJavaLibraryType extends JpsElementTypeWithDummyProperties implements JpsLibraryType<JpsDummyElement> {
   public static final JpsJavaLibraryType INSTANCE = new JpsJavaLibraryType();
 
   @NotNull
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleType.java
index 6a971cf..c4f6299 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleType.java
@@ -18,13 +18,13 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.jps.model.JpsDummyElement;
 import org.jetbrains.jps.model.JpsElementFactory;
-import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
+import org.jetbrains.jps.model.ex.JpsElementTypeWithDummyProperties;
 import org.jetbrains.jps.model.module.JpsModuleType;
 
 /**
  * @author nik
  */
-public class JpsJavaModuleType extends JpsModuleType<JpsDummyElement> implements JpsElementTypeWithDefaultProperties<JpsDummyElement> {
+public class JpsJavaModuleType extends JpsElementTypeWithDummyProperties implements JpsModuleType<JpsDummyElement> {
   public static final JpsJavaModuleType INSTANCE = new JpsJavaModuleType();
 
   @NotNull
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationType.java b/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationType.java
index aa0a7a2..c5c880c 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationType.java
@@ -15,12 +15,13 @@
  */
 package org.jetbrains.jps.model.java.runConfiguration;
 
+import org.jetbrains.jps.model.ex.JpsElementTypeBase;
 import org.jetbrains.jps.model.runConfiguration.JpsRunConfigurationType;
 
 /**
  * @author nik
  */
-public class JpsApplicationRunConfigurationType extends JpsRunConfigurationType<JpsApplicationRunConfigurationProperties> {
+public class JpsApplicationRunConfigurationType extends JpsElementTypeBase<JpsApplicationRunConfigurationProperties> implements JpsRunConfigurationType<JpsApplicationRunConfigurationProperties> {
   public static final JpsApplicationRunConfigurationType INSTANCE = new JpsApplicationRunConfigurationType();
 
   private JpsApplicationRunConfigurationType() {
diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryType.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryType.java
index 81a1de0..238c78e 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryType.java
@@ -19,7 +19,11 @@
 import org.jetbrains.jps.model.JpsElementType;
 
 /**
+ * Represents a type of libraries in JPS model.
+ * <p>
+ * Use {@link org.jetbrains.jps.model.ex.JpsElementTypeBase} as a base class for implementations of this interface
+ * </p>
  * @author nik
  */
-public abstract class JpsLibraryType<P extends JpsElement> extends JpsElementType<P> {
+public interface JpsLibraryType<P extends JpsElement> extends JpsElementType<P> {
 }
diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/sdk/JpsSdkType.java b/jps/model-api/src/org/jetbrains/jps/model/library/sdk/JpsSdkType.java
index 2699fdf..ecc62a7 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/library/sdk/JpsSdkType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/library/sdk/JpsSdkType.java
@@ -17,13 +17,13 @@
 
 import org.jetbrains.jps.model.JpsElement;
 import org.jetbrains.jps.model.JpsElementChildRole;
+import org.jetbrains.jps.model.ex.JpsElementTypeBase;
 import org.jetbrains.jps.model.library.JpsLibraryType;
-import org.jetbrains.jps.model.library.sdk.JpsSdk;
 
 /**
  * @author nik
  */
-public abstract class JpsSdkType<P extends JpsElement> extends JpsLibraryType<JpsSdk<P>> {
+public abstract class JpsSdkType<P extends JpsElement> extends JpsElementTypeBase<JpsSdk<P>> implements JpsLibraryType<JpsSdk<P>> {
   private final JpsElementChildRole<P> mySdkPropertiesRole = new JpsElementChildRole<P>();
 
   public final JpsElementChildRole<P> getSdkPropertiesRole() {
diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java
index 3a1df16..8a85c2f 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java
@@ -45,8 +45,8 @@
   Iterable<JpsTypedModuleSourceRoot<P>> getSourceRoots(@NotNull JpsModuleSourceRootType<P> type);
 
   @NotNull
-  <P extends JpsElement, Type extends JpsModuleSourceRootType<P> & JpsElementTypeWithDefaultProperties<P>>
-  JpsModuleSourceRoot addSourceRoot(@NotNull String url, @NotNull Type rootType);
+  <P extends JpsElement>
+  JpsModuleSourceRoot addSourceRoot(@NotNull String url, @NotNull JpsModuleSourceRootType<P> rootType);
 
   @NotNull
   <P extends JpsElement>
diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootType.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootType.java
index 5a2dbb3..873664a 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootType.java
@@ -17,9 +17,15 @@
 
 import org.jetbrains.jps.model.JpsElement;
 import org.jetbrains.jps.model.JpsElementType;
+import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
 
 /**
+ * Represents a type of source roots of modules in JPS model.
+ *
+ * <p>
+ * Use {@link org.jetbrains.jps.model.ex.JpsElementTypeBase} as a base class for implementations of this interface
+ * </p>
  * @author nik
  */
-public abstract class JpsModuleSourceRootType<P extends JpsElement> extends JpsElementType<P> {
+public interface JpsModuleSourceRootType<P extends JpsElement> extends JpsElementType<P>, JpsElementTypeWithDefaultProperties<P> {
 }
diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleType.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleType.java
index 9062744..10c71cb 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleType.java
@@ -19,7 +19,12 @@
 import org.jetbrains.jps.model.JpsElementType;
 
 /**
+ * Represents a type of modules in JPS model
+ *
+ * <p>
+ * Use {@link org.jetbrains.jps.model.ex.JpsElementTypeBase} as a base class for implementations of this interface
+ * </p>
  * @author nik
  */
-public abstract class JpsModuleType<P extends JpsElement> extends JpsElementType<P> {
+public interface JpsModuleType<P extends JpsElement> extends JpsElementType<P> {
 }
diff --git a/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfigurationType.java b/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfigurationType.java
index 558bf05..ebf0ab6 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfigurationType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfigurationType.java
@@ -19,7 +19,12 @@
 import org.jetbrains.jps.model.JpsElementType;
 
 /**
+ * Represents a type of run configurations in JPS model
+ *
+ * <p>
+ * Use {@link org.jetbrains.jps.model.ex.JpsElementTypeBase} as a base class for implementations of this interface
+ * </p>
  * @author nik
  */
-public abstract class JpsRunConfigurationType<P extends JpsElement> extends JpsElementType<P> {
+public interface JpsRunConfigurationType<P extends JpsElement> extends JpsElementType<P> {
 }
diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaSdkUtil.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaSdkUtil.java
index 32a5a25..2610590 100644
--- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaSdkUtil.java
+++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaSdkUtil.java
@@ -83,9 +83,17 @@
       }
     }
 
-    File classesZip = new File(home, "lib/classes.zip");
-    if (classesZip.isFile()) {
-      rootFiles.add(classesZip);
+    String[] additionalJars = {
+      "jre/bin/default/jclSC170/vm.jar",
+      "jre/lib/i386/default/jclSC170/vm.jar",
+      "jre/lib/amd64/default/jclSC170/vm.jar",
+      "lib/classes.zip"
+    };
+    for (String relativePath : additionalJars) {
+      File jar = new File(home, relativePath);
+      if (jar.isFile()) {
+        rootFiles.add(jar);
+      }
     }
 
     File classesDir = new File(home, "classes");
diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java
index eff6c27..0c76723 100644
--- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java
+++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java
@@ -111,8 +111,7 @@
 
   @NotNull
   @Override
-  public <P extends JpsElement, T extends JpsModuleSourceRootType<P> & JpsElementTypeWithDefaultProperties<P>>
-  JpsModuleSourceRoot addSourceRoot(@NotNull String url, @NotNull T rootType) {
+  public <P extends JpsElement> JpsModuleSourceRoot addSourceRoot(@NotNull String url, @NotNull JpsModuleSourceRootType<P> rootType) {
     return addSourceRoot(url, rootType, rootType.createDefaultProperties());
   }
 
diff --git a/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java b/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java
index 05dc780..22500b2 100644
--- a/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java
+++ b/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java
@@ -18,22 +18,16 @@
 import com.intellij.openapi.application.PathMacroFilter;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.io.FileUtil;
-import org.jdom.Attribute;
-import org.jdom.Comment;
-import org.jdom.Element;
-import org.jdom.Text;
+import org.jdom.*;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.List;
-
 /**
  * @author Eugene Zhuravlev
  * @since Dec 6, 2004
  */
 public abstract class PathMacroMap {
-  private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.PathMacroMap");
-
+  private static final Logger LOG = Logger.getInstance(PathMacroMap.class);
 
   public abstract String substitute(String text, boolean caseSensitive);
 
@@ -41,15 +35,10 @@
     substitute(e, caseSensitive, false);
   }
 
-  public final void substitute(@NotNull Element e, boolean caseSensitive, final boolean recursively,
-                               @Nullable PathMacroFilter filter) {
-    List content = e.getContent();
-    //noinspection ForLoopReplaceableByForEach
-    for (int i = 0, contentSize = content.size(); i < contentSize; i++) {
-      Object child = content.get(i);
+  public final void substitute(@NotNull Element e, boolean caseSensitive, boolean recursively, @Nullable PathMacroFilter filter) {
+    for (Content child : e.getContent()) {
       if (child instanceof Element) {
-        Element element = (Element)child;
-        substitute(element, caseSensitive, recursively, filter);
+        substitute((Element)child, caseSensitive, recursively, filter);
       }
       else if (child instanceof Text) {
         Text t = (Text)child;
@@ -64,16 +53,11 @@
       }
     }
 
-    List attributes = e.getAttributes();
-    //noinspection ForLoopReplaceableByForEach
-    for (int i = 0, attributesSize = attributes.size(); i < attributesSize; i++) {
-      Object attribute1 = attributes.get(i);
-      Attribute attribute = (Attribute)attribute1;
+    for (Attribute attribute : e.getAttributes()) {
       if (filter == null || !filter.skipPathMacros(attribute)) {
-        final String value = (recursively || (filter != null && filter.recursePathMacros(attribute)))
-                             ? substituteRecursively(attribute.getValue(), caseSensitive)
-                             : substitute(attribute.getValue(), caseSensitive);
-        attribute.setValue(value);
+        attribute.setValue((recursively || (filter != null && filter.recursePathMacros(attribute)))
+                           ? substituteRecursively(attribute.getValue(), caseSensitive)
+                           : substitute(attribute.getValue(), caseSensitive));
       }
     }
   }
diff --git a/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java b/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java
index 559ed4d..6f7d41b2 100644
--- a/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java
+++ b/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java
@@ -93,11 +93,11 @@
   }
 
   public void setUseInProcessJavac(boolean value) {
-    //doesn't make sense for new builders
+    warning("projectBuilder.useInProcessJavac option is ignored because it doesn't make sense for new JPS builders");
   }
 
   public void setArrangeModuleCyclesOutputs(boolean value) {
-    //doesn't make sense for new builders
+    warning("projectBuilder.arrangeModuleCyclesOutputs option is ignored because it doesn't make sense for new JPS builders");
   }
 
   public void error(String message) {
@@ -202,6 +202,8 @@
   private void runBuild(final Set<String> modulesSet, final boolean allModules, boolean includeTests) {
     if (!myDryRun) {
       final AntMessageHandler messageHandler = new AntMessageHandler();
+      //noinspection AssignmentToStaticFieldFromInstanceMethod
+      AntLoggerFactory.ourMessageHandler = new AntMessageHandler();
       Logger.setFactory(AntLoggerFactory.class);
       boolean forceBuild = true;
 
@@ -321,14 +323,10 @@
     }
   }
 
-  private class AntLoggerFactory implements Logger.Factory {
+  private static class AntLoggerFactory implements Logger.Factory {
     private static final String COMPILER_NAME = "build runner";
 
-    private final AntMessageHandler myMessageHandler;
-
-    public AntLoggerFactory() {
-      myMessageHandler = new AntMessageHandler();
-    }
+    private static AntMessageHandler ourMessageHandler;
 
     @Override
     public Logger getLoggerInstance(String category) {
@@ -336,16 +334,16 @@
         @Override
         public void error(@NonNls String message, @Nullable Throwable t, @NotNull @NonNls String... details) {
           if (t != null) {
-            myMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, t));
+            ourMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, t));
           }
           else {
-            myMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, BuildMessage.Kind.ERROR, message));
+            ourMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, BuildMessage.Kind.ERROR, message));
           }
         }
 
         @Override
         public void warn(@NonNls String message, @Nullable Throwable t) {
-          myMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, BuildMessage.Kind.WARNING, message));
+          ourMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, BuildMessage.Kind.WARNING, message));
         }
       };
     }
diff --git a/platform/analysis-api/src/com/intellij/codeInspection/ProblemDescriptor.java b/platform/analysis-api/src/com/intellij/codeInspection/ProblemDescriptor.java
index 088308e..be035f2 100644
--- a/platform/analysis-api/src/com/intellij/codeInspection/ProblemDescriptor.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/ProblemDescriptor.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.
@@ -17,6 +17,7 @@
 
 import com.intellij.lang.annotation.ProblemGroup;
 import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.PsiElement;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -30,6 +31,7 @@
   PsiElement getPsiElement();
   PsiElement getStartElement();
   PsiElement getEndElement();
+  TextRange getTextRangeInElement();
   int getLineNumber();
   @NotNull
   ProblemHighlightType getHighlightType();
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightingSessionImpl.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightingSessionImpl.java
index cb7c14d..fe0c3f8 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightingSessionImpl.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightingSessionImpl.java
@@ -41,20 +41,23 @@
   @NotNull private final ProgressIndicator myProgressIndicator;
   private final EditorColorsScheme myEditorColorsScheme;
   private final int myPassId;
+  @NotNull private final TextRange myRestrictRange;
   private final Project myProject;
   private final Document myDocument;
-  private Map<TextRange,RangeMarker> myRanges2markersCache;
+  private final Map<TextRange,RangeMarker> myRanges2markersCache = new THashMap<TextRange, RangeMarker>();
 
   public HighlightingSessionImpl(@NotNull PsiFile psiFile,
                                  @Nullable Editor editor,
                                  @NotNull ProgressIndicator progressIndicator,
                                  EditorColorsScheme editorColorsScheme,
-                                 int passId) {
+                                 int passId,
+                                 @NotNull TextRange restrictRange) {
     myPsiFile = psiFile;
     myEditor = editor;
     myProgressIndicator = progressIndicator;
     myEditorColorsScheme = editorColorsScheme;
     myPassId = passId;
+    myRestrictRange = restrictRange;
     myProject = psiFile.getProject();
     myDocument = PsiDocumentManager.getInstance(myProject).getDocument(psiFile);
   }
@@ -97,36 +100,34 @@
     return myPassId;
   }
 
-  private TransferToEDTQueue<HighlightInfo> myAddHighlighterInEDTQueue;
-  private TransferToEDTQueue<RangeHighlighterEx> myDisposeHighlighterInEDTQueue;
-  void init(@NotNull final TextRange restrictRange) {
-    myRanges2markersCache = new THashMap<TextRange, RangeMarker>();
-    Condition<Object> stopCondition = new Condition<Object>() {
-      @Override
-      public boolean value(Object o) {
-        return myProject.isDisposed() || getProgressIndicator().isCanceled();
-      }
-    };
-    myAddHighlighterInEDTQueue = new TransferToEDTQueue<HighlightInfo>("Apply highlighting results", new Processor<HighlightInfo>() {
-      @Override
-      public boolean process(HighlightInfo info) {
-        final EditorColorsScheme colorsScheme = getColorsScheme();
-        UpdateHighlightersUtil.addHighlighterToEditorIncrementally(myProject, myDocument, getPsiFile(), restrictRange.getStartOffset(),
-                                                                   restrictRange.getEndOffset(),
-                                                                   info, colorsScheme, Pass.UPDATE_ALL, myRanges2markersCache);
+  private final TransferToEDTQueue<HighlightInfo> myAddHighlighterInEDTQueue = new TransferToEDTQueue<HighlightInfo>("Apply highlighting results", new Processor<HighlightInfo>() {
+    @Override
+    public boolean process(HighlightInfo info) {
+      final EditorColorsScheme colorsScheme = getColorsScheme();
+      UpdateHighlightersUtil.addHighlighterToEditorIncrementally(myProject, myDocument, getPsiFile(), myRestrictRange.getStartOffset(),
+                                                                 myRestrictRange.getEndOffset(),
+                                                                 info, colorsScheme, Pass.UPDATE_ALL, myRanges2markersCache);
 
-        return true;
-      }
-    }, stopCondition, 200);
-
-    myDisposeHighlighterInEDTQueue = new TransferToEDTQueue<RangeHighlighterEx>("Dispose abandoned highlighter", new Processor<RangeHighlighterEx>() {
-      @Override
-      public boolean process(@NotNull RangeHighlighterEx highlighter) {
-        highlighter.dispose();
-        return true;
-      }
-    }, stopCondition, 200);
-  }
+      return true;
+    }
+  }, new Condition<Object>() {
+    @Override
+    public boolean value(Object o) {
+      return myProject.isDisposed() || getProgressIndicator().isCanceled();
+    }
+  }, 200);
+  private final TransferToEDTQueue<RangeHighlighterEx> myDisposeHighlighterInEDTQueue = new TransferToEDTQueue<RangeHighlighterEx>("Dispose abandoned highlighter", new Processor<RangeHighlighterEx>() {
+    @Override
+    public boolean process(@NotNull RangeHighlighterEx highlighter) {
+      highlighter.dispose();
+      return true;
+    }
+  }, new Condition<Object>() {
+    @Override
+    public boolean value(Object o) {
+      return myProject.isDisposed() || getProgressIndicator().isCanceled();
+    }
+  }, 200);
 
   void queueHighlightInfo(@NotNull HighlightInfo info) {
     myAddHighlighterInEDTQueue.offer(info);
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java
index 4719ecb..f5a26440 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java
@@ -62,14 +62,13 @@
 
   @NotNull
   private HighlightingSession sessionCreated(@NotNull TextRange restrictRange,
-                                              @NotNull PsiFile file,
-                                              @Nullable Editor editor,
-                                              @NotNull ProgressIndicator progress,
-                                              EditorColorsScheme scheme,
-                                              int passId) {
-    HighlightingSessionImpl impl = new HighlightingSessionImpl(file, editor, progress, scheme, passId);
+                                             @NotNull PsiFile file,
+                                             @Nullable Editor editor,
+                                             @NotNull ProgressIndicator progress,
+                                             EditorColorsScheme scheme,
+                                             int passId) {
+    HighlightingSessionImpl impl = new HighlightingSessionImpl(file, editor, progress, scheme, passId, restrictRange);
     myHighlightingSession = impl;
-    impl.init(restrictRange);
     return impl;
   }
 
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
index 78b638b..ab9581f 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
@@ -78,7 +78,7 @@
   }
 
   @NotNull
-  private static List<ProblemDescriptor> inspect(@NotNull final List<LocalInspectionTool> tools,
+  public static List<ProblemDescriptor> inspect(@NotNull final List<LocalInspectionTool> tools,
                                                 @NotNull final PsiFile file,
                                                 @NotNull final InspectionManager iManager,
                                                 final boolean isOnTheFly,
@@ -92,8 +92,9 @@
     return result;
   }
 
+  // public accessibility for Upsource
   @NotNull
-  private static Map<String, List<ProblemDescriptor>> inspectEx(@NotNull final List<LocalInspectionTool> tools,
+  public static Map<String, List<ProblemDescriptor>> inspectEx(@NotNull final List<LocalInspectionTool> tools,
                                                                @NotNull final PsiFile file,
                                                                @NotNull final InspectionManager iManager,
                                                                final boolean isOnTheFly,
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java
index 42dfa58..45997b0 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java
@@ -102,6 +102,11 @@
     return PsiTreeUtil.findCommonParent(startElement, endElement);
   }
 
+  @Nullable
+  public TextRange getTextRangeInElement() {
+    return myTextRangeInElement;
+  }
+
   @Override
   public PsiElement getStartElement() {
     return myStartSmartPointer.getElement();
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java
index 2f7742d..b6c5ff5 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java
@@ -15,6 +15,11 @@
  */
 package com.intellij.codeInspection;
 
+import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
+import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.editor.colors.CodeInsightColors;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.PsiElement;
@@ -76,4 +81,41 @@
   public static String renderDescriptionMessage(@NotNull CommonProblemDescriptor descriptor, PsiElement element) {
     return renderDescriptionMessage(descriptor, element, false);
   }
+
+  @NotNull
+  public static HighlightInfoType highlightTypeFromDescriptor(@NotNull ProblemDescriptor problemDescriptor, @NotNull HighlightSeverity severity, @NotNull SeverityRegistrar severityRegistrar) {
+    final ProblemHighlightType highlightType = problemDescriptor.getHighlightType();
+    switch (highlightType) {
+      case GENERIC_ERROR_OR_WARNING:
+        return severityRegistrar.getHighlightInfoTypeBySeverity(severity);
+      case LIKE_DEPRECATED:
+        return new HighlightInfoType.HighlightInfoTypeImpl(severity, HighlightInfoType.DEPRECATED.getAttributesKey());
+      case LIKE_UNKNOWN_SYMBOL:
+        if (severity == HighlightSeverity.ERROR) {
+          return new HighlightInfoType.HighlightInfoTypeImpl(severity, HighlightInfoType.WRONG_REF.getAttributesKey());
+        }
+        if (severity == HighlightSeverity.WARNING) {
+          return new HighlightInfoType.HighlightInfoTypeImpl(severity, CodeInsightColors.WEAK_WARNING_ATTRIBUTES);
+        }
+        return severityRegistrar.getHighlightInfoTypeBySeverity(severity);
+      case LIKE_UNUSED_SYMBOL:
+        return new HighlightInfoType.HighlightInfoTypeImpl(severity, HighlightInfoType.UNUSED_SYMBOL.getAttributesKey());
+      case INFO:
+        return HighlightInfoType.INFO;
+      case WEAK_WARNING:
+        return HighlightInfoType.WEAK_WARNING;
+      case ERROR:
+        return HighlightInfoType.WRONG_REF;
+      case GENERIC_ERROR:
+        return HighlightInfoType.ERROR;
+      case INFORMATION:
+        final TextAttributesKey attributes = ((ProblemDescriptorBase)problemDescriptor).getEnforcedTextAttributes();
+        if (attributes != null) {
+          return new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, attributes);
+        }
+        return HighlightInfoType.INFORMATION;
+    }
+    throw new RuntimeException("Cannot map " + highlightType);
+  }
+
 }
diff --git a/platform/bootstrap/src/com/intellij/ide/Bootstrap.java b/platform/bootstrap/src/com/intellij/ide/Bootstrap.java
index ff6693c..847062c 100644
--- a/platform/bootstrap/src/com/intellij/ide/Bootstrap.java
+++ b/platform/bootstrap/src/com/intellij/ide/Bootstrap.java
@@ -24,11 +24,13 @@
  */
 public class Bootstrap {
   private static final String PLUGIN_MANAGER = "com.intellij.ide.plugins.PluginManager";
+  public static final String NO_SPLASH = "nosplash";
 
   private Bootstrap() { }
 
   public static void main(String[] args, String mainClass, String methodName) throws Exception {
-    UrlClassLoader newClassLoader = BootstrapClassLoaderUtil.initClassLoader(args.length == 0);
+    UrlClassLoader newClassLoader = BootstrapClassLoaderUtil.initClassLoader(args.length == 0 || args.length == 1 &&
+                                                                                                 NO_SPLASH.equals(args[0]));
 
     WindowsCommandLineProcessor.ourMirrorClass = Class.forName(WindowsCommandLineProcessor.class.getName(), true, newClassLoader);
 
diff --git a/platform/core-api/src/com/intellij/ide/highlighter/ArchiveFileType.java b/platform/core-api/src/com/intellij/ide/highlighter/ArchiveFileType.java
index 438fb52..72b2b9b 100644
--- a/platform/core-api/src/com/intellij/ide/highlighter/ArchiveFileType.java
+++ b/platform/core-api/src/com/intellij/ide/highlighter/ArchiveFileType.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.
@@ -35,33 +35,40 @@
 
   public static final ArchiveFileType INSTANCE = new ArchiveFileType();
 
+  @Override
   @NotNull
   public String getName() {
     return "ARCHIVE";
   }
 
+  @Override
   @NotNull
   public String getDescription() {
     return IdeBundle.message("filetype.description.archive.files");
   }
 
+  @Override
   @NotNull
   public String getDefaultExtension() {
     return "";
   }
 
+  @Override
   public Icon getIcon() {
     return ICON.getValue();
   }
 
+  @Override
   public boolean isBinary() {
     return true;
   }
 
+  @Override
   public boolean isReadOnly() {
     return false;
   }
 
+  @Override
   public String getCharset(@NotNull VirtualFile file, final byte[] content) {
     return null;
   }
diff --git a/platform/core-api/src/com/intellij/lexer/DelegateLexer.java b/platform/core-api/src/com/intellij/lexer/DelegateLexer.java
index 4b95562..ce8bbbc 100644
--- a/platform/core-api/src/com/intellij/lexer/DelegateLexer.java
+++ b/platform/core-api/src/com/intellij/lexer/DelegateLexer.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.
@@ -20,6 +20,7 @@
 package com.intellij.lexer;
 
 import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public class DelegateLexer extends LexerBase {
@@ -34,7 +35,7 @@
   }
 
   @Override
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     myDelegate.start(buffer, startOffset, endOffset, initialState);
   }
 
@@ -64,6 +65,7 @@
     myDelegate.advance();
   }
 
+  @NotNull
   @Override
   public final CharSequence getBufferSequence() {
     return myDelegate.getBufferSequence();
diff --git a/platform/core-api/src/com/intellij/lexer/DocCommentLexer.java b/platform/core-api/src/com/intellij/lexer/DocCommentLexer.java
index bb121f9..7ea6da5 100644
--- a/platform/core-api/src/com/intellij/lexer/DocCommentLexer.java
+++ b/platform/core-api/src/com/intellij/lexer/DocCommentLexer.java
@@ -17,6 +17,7 @@
 
 import com.intellij.psi.tree.IElementType;
 import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.NotNull;
 
 import java.io.IOException;
 
@@ -45,7 +46,7 @@
     }
 
     @Override
-    public final void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+    public final void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
       myBuffer = buffer;
       myBufferIndex =  startOffset;
       myBufferEndOffset = endOffset;
@@ -59,6 +60,7 @@
       return myState;
     }
 
+    @NotNull
     @Override
     public CharSequence getBufferSequence() {
       return myBuffer;
diff --git a/platform/core-api/src/com/intellij/lexer/DummyLexer.java b/platform/core-api/src/com/intellij/lexer/DummyLexer.java
new file mode 100644
index 0000000..3d13df9
--- /dev/null
+++ b/platform/core-api/src/com/intellij/lexer/DummyLexer.java
@@ -0,0 +1,83 @@
+/*
+ * 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.lexer;
+
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+
+public class DummyLexer extends LexerBase {
+  private CharSequence myBuffer;
+  private int myStartOffset;
+  private int myEndOffset;
+  private final IElementType myTokenType;
+
+  public DummyLexer(IElementType type) {
+    myTokenType = type;
+  }
+
+  @Override
+  public void start(@NotNull final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
+    myBuffer = buffer;
+    myStartOffset = startOffset;
+    myEndOffset = endOffset;
+  }
+
+  @NotNull
+  @Override
+  public CharSequence getBufferSequence() {
+    return myBuffer;
+  }
+
+  @Override
+  public int getState() {
+    return 0;
+  }
+
+  @Override
+  public IElementType getTokenType() {
+    return myStartOffset < myEndOffset ? myTokenType : null;
+  }
+
+  @Override
+  public int getTokenStart() {
+    return myStartOffset;
+  }
+
+  @Override
+  public int getTokenEnd() {
+    return myEndOffset;
+  }
+
+  @Override
+  public void advance() {
+    myStartOffset = myEndOffset;
+  }
+
+  @NotNull
+  @Override
+  public LexerPosition getCurrentPosition() {
+    return new LexerPositionImpl(0, getState());
+  }
+
+  @Override
+  public void restore(@NotNull LexerPosition position) {
+  }
+
+  @Override
+  public int getBufferEnd() {
+    return myEndOffset;
+  }
+}
diff --git a/platform/platform-api/src/com/intellij/lexer/EmptyLexer.java b/platform/core-api/src/com/intellij/lexer/EmptyLexer.java
similarity index 100%
rename from platform/platform-api/src/com/intellij/lexer/EmptyLexer.java
rename to platform/core-api/src/com/intellij/lexer/EmptyLexer.java
diff --git a/platform/core-api/src/com/intellij/lexer/FlexAdapter.java b/platform/core-api/src/com/intellij/lexer/FlexAdapter.java
index cd9ccaf..593f68c 100644
--- a/platform/core-api/src/com/intellij/lexer/FlexAdapter.java
+++ b/platform/core-api/src/com/intellij/lexer/FlexAdapter.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.
@@ -16,6 +16,7 @@
 package com.intellij.lexer;
 
 import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
 
 import java.io.IOException;
 
@@ -39,7 +40,7 @@
   }
 
   @Override
-  public void start(final CharSequence buffer, int startOffset, int endOffset, final int initialState) {
+  public void start(@NotNull final CharSequence buffer, int startOffset, int endOffset, final int initialState) {
     myText = buffer;
     myEnd = endOffset;
     myFlex.reset(myText, startOffset, endOffset, initialState);    
@@ -76,6 +77,7 @@
     myTokenType = null;
   }
 
+  @NotNull
   @Override
   public CharSequence getBufferSequence() {
     return myText;
diff --git a/platform/core-api/src/com/intellij/lexer/LayeredLexer.java b/platform/core-api/src/com/intellij/lexer/LayeredLexer.java
index eabb355..1080337 100644
--- a/platform/core-api/src/com/intellij/lexer/LayeredLexer.java
+++ b/platform/core-api/src/com/intellij/lexer/LayeredLexer.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.
@@ -18,6 +18,7 @@
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.HashSet;
 import java.util.Map;
@@ -75,7 +76,7 @@
   }
 
   @Override
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     LOG.assertTrue(initialState != IN_LAYER_STATE, "Restoring to layer is not supported.");
     myState = initialState;
     myCurrentLayerLexer = null;
@@ -157,13 +158,14 @@
     myState = isLayerActive() ? IN_LAYER_STATE : super.getState();
   }
 
+  @NotNull
   @Override
   public LexerPosition getCurrentPosition() {
     return new LexerPositionImpl(getTokenStart(), getState());
   }
 
   @Override
-  public void restore(LexerPosition position) {
+  public void restore(@NotNull LexerPosition position) {
     start(getBufferSequence(), position.getOffset(), getBufferEnd(), position.getState());
   }
 
diff --git a/platform/core-api/src/com/intellij/lexer/Lexer.java b/platform/core-api/src/com/intellij/lexer/Lexer.java
index 58b4dd3..1ccfd472 100644
--- a/platform/core-api/src/com/intellij/lexer/Lexer.java
+++ b/platform/core-api/src/com/intellij/lexer/Lexer.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.
@@ -16,6 +16,7 @@
 package com.intellij.lexer;
 
 import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -35,20 +36,22 @@
    * @param initialState the initial state of the lexer.
    * @since IDEA 7
    */
-  public abstract void start(CharSequence buffer, int startOffset, int endOffset, int initialState);
+  public abstract void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState);
 
-  public final void start(CharSequence buf, int start, int end) {
+  public final void start(@NotNull CharSequence buf, int start, int end) {
     start(buf, start, end, 0);
   }
 
-  public final void start(CharSequence buf) {
+  public final void start(@NotNull CharSequence buf) {
     start(buf, 0, buf.length(), 0);
   }
 
+  @NotNull
   public CharSequence getTokenSequence() {
     return getBufferSequence().subSequence(getTokenStart(), getTokenEnd());
   }
 
+  @NotNull
   public String getTokenText() {
     return getTokenSequence().toString();
   }
@@ -93,6 +96,7 @@
    *
    * @return the lexer position and state.
    */
+  @NotNull
   public abstract LexerPosition getCurrentPosition();
 
   /**
@@ -100,7 +104,7 @@
    *
    * @param position the state and position to restore to.
    */
-  public abstract void restore(LexerPosition position);
+  public abstract void restore(@NotNull LexerPosition position);
 
   /**
    * Returns the buffer sequence over which the lexer is running. This method should return the
@@ -108,6 +112,7 @@
    * @return the lexer buffer.
    * @since IDEA 7
    */
+  @NotNull
   public abstract CharSequence getBufferSequence();
 
   /**
diff --git a/platform/core-api/src/com/intellij/lexer/LexerBase.java b/platform/core-api/src/com/intellij/lexer/LexerBase.java
index c166bed..b7a69b8 100644
--- a/platform/core-api/src/com/intellij/lexer/LexerBase.java
+++ b/platform/core-api/src/com/intellij/lexer/LexerBase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 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.
@@ -15,7 +15,10 @@
  */
 package com.intellij.lexer;
 
+import org.jetbrains.annotations.NotNull;
+
 public abstract class LexerBase extends Lexer {
+  @NotNull
   @Override
   public LexerPosition getCurrentPosition() {
     final int offset = getTokenStart();
@@ -24,7 +27,7 @@
   }
 
   @Override
-  public void restore(LexerPosition position) {
+  public void restore(@NotNull LexerPosition position) {
     start(getBufferSequence(), position.getOffset(), getBufferEnd(), position.getState());
   }
 }
diff --git a/platform/core-api/src/com/intellij/lexer/MergingLexerAdapterBase.java b/platform/core-api/src/com/intellij/lexer/MergingLexerAdapterBase.java
index bbaace8..2d55098a 100644
--- a/platform/core-api/src/com/intellij/lexer/MergingLexerAdapterBase.java
+++ b/platform/core-api/src/com/intellij/lexer/MergingLexerAdapterBase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2010 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.
@@ -16,6 +16,7 @@
 package com.intellij.lexer;
 
 import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
 
 public class MergingLexerAdapterBase extends DelegateLexer {
   private IElementType myTokenType;
@@ -29,7 +30,7 @@
   }
 
   @Override
-  public void start(final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
+  public void start(@NotNull final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
     super.start(buffer, startOffset, endOffset, initialState);
     myTokenType = null;
   }
@@ -81,7 +82,7 @@
   }
 
   @Override
-  public void restore(LexerPosition position) {
+  public void restore(@NotNull LexerPosition position) {
     MyLexerPosition pos = (MyLexerPosition)position;
 
     getDelegate().restore(pos.getOriginalPosition());
@@ -90,6 +91,7 @@
     myState = pos.getOldState();
   }
 
+  @NotNull
   @Override
   public LexerPosition getCurrentPosition() {
     return new MyLexerPosition(myTokenStart, myTokenType, getDelegate().getCurrentPosition(), myState);
diff --git a/platform/core-api/src/com/intellij/openapi/editor/colors/TextAttributesKey.java b/platform/core-api/src/com/intellij/openapi/editor/colors/TextAttributesKey.java
index 721f51e..53f0565 100644
--- a/platform/core-api/src/com/intellij/openapi/editor/colors/TextAttributesKey.java
+++ b/platform/core-api/src/com/intellij/openapi/editor/colors/TextAttributesKey.java
@@ -64,7 +64,8 @@
     return myExternalName;
   }
 
-  public int compareTo(TextAttributesKey key) {
+  @Override
+  public int compareTo(@NotNull TextAttributesKey key) {
     return myExternalName.compareTo(key.myExternalName);
   }
 
@@ -79,10 +80,12 @@
     return find(externalName);
   }
 
+  @Override
   public void readExternal(Element element) throws InvalidDataException {
     DefaultJDOMExternalizer.readExternal(this, element);
   }
 
+  @Override
   public void writeExternal(Element element) throws WriteExternalException {
     DefaultJDOMExternalizer.writeExternal(this, element);
   }
diff --git a/platform/core-api/src/com/intellij/openapi/editor/markup/AttributesFlyweight.java b/platform/core-api/src/com/intellij/openapi/editor/markup/AttributesFlyweight.java
index 05fa2cd..411fc5e 100644
--- a/platform/core-api/src/com/intellij/openapi/editor/markup/AttributesFlyweight.java
+++ b/platform/core-api/src/com/intellij/openapi/editor/markup/AttributesFlyweight.java
@@ -19,6 +19,7 @@
  */
 package com.intellij.openapi.editor.markup;
 
+import com.intellij.openapi.util.Comparing;
 import com.intellij.util.ConcurrencyUtil;
 import com.intellij.util.containers.StripedLockConcurrentHashMap;
 import org.intellij.lang.annotations.JdkConstants;
@@ -28,17 +29,29 @@
 import java.awt.*;
 
 public class AttributesFlyweight {
-  private final int myHashCode;
   private static final StripedLockConcurrentHashMap<FlyweightKey, AttributesFlyweight> entries = new StripedLockConcurrentHashMap<FlyweightKey, AttributesFlyweight>();
   private static final ThreadLocal<FlyweightKey> ourKey = new ThreadLocal<FlyweightKey>();
 
+  private final int myHashCode;
+  private final Color      myForeground;
+  private final Color      myBackground;
+  @JdkConstants.FontStyle
+  private final int        myFontType;
+  private final Color      myEffectColor;
+  private final EffectType myEffectType;
+  private final Color      myErrorStripeColor;
+
   private static class FlyweightKey implements Cloneable {
-    Color foreground;
-    Color background;
-    @JdkConstants.FontStyle int fontType;
-    Color effectColor;
-    EffectType effectType;
-    Color errorStripeColor;
+    private Color foreground;
+    private Color background;
+    @JdkConstants.FontStyle
+    private int fontType;
+    private Color effectColor;
+    private EffectType effectType;
+    private Color errorStripeColor;
+
+    private FlyweightKey() {
+    }
 
     @Override
     public boolean equals(Object o) {
@@ -59,13 +72,7 @@
 
     @Override
     public int hashCode() {
-      int result = foreground != null ? foreground.hashCode() : 0;
-      result = 31 * result + (background != null ? background.hashCode() : 0);
-      result = 31 * result + fontType;
-      result = 31 * result + (effectColor != null ? effectColor.hashCode() : 0);
-      result = 31 * result + (effectType != null ? effectType.hashCode() : 0);
-      result = 31 * result + (errorStripeColor != null ? errorStripeColor.hashCode() : 0);
-      return result;
+      return calcHashCode(foreground, background, fontType, effectColor, effectType, errorStripeColor);
     }
 
     @Override
@@ -102,39 +109,37 @@
       return flyweight;
     }
 
-    return ConcurrencyUtil.cacheOrGet(entries, key.clone(), new AttributesFlyweight(foreground, background, fontType, effectColor, effectType, errorStripeColor));
+    AttributesFlyweight newValue = new AttributesFlyweight(foreground, background, fontType, effectColor, effectType, errorStripeColor);
+    return ConcurrencyUtil.cacheOrGet(entries, key.clone(), newValue);
   }
 
-  private final Color      myForeground;
-  private final Color      myBackground;
-  @JdkConstants.FontStyle
-  private final int        myFontType;
-  private final Color      myEffectColor ;
-  private final EffectType myEffectType;
-  private final Color      myErrorStripeColor;
-
   private AttributesFlyweight(Color foreground,
-                      Color background,
-                      @JdkConstants.FontStyle int fontType,
-                      Color effectColor,
-                      EffectType effectType,
-                      Color errorStripeColor) {
+                              Color background,
+                              @JdkConstants.FontStyle int fontType,
+                              Color effectColor,
+                              EffectType effectType,
+                              Color errorStripeColor) {
     myForeground = foreground;
     myBackground = background;
     myFontType = fontType;
     myEffectColor = effectColor;
     myEffectType = effectType;
     myErrorStripeColor = errorStripeColor;
-    myHashCode = calcHashCode();
+    myHashCode = calcHashCode(foreground, background, fontType, effectColor, effectType, errorStripeColor);
   }
 
-  private int calcHashCode() {
-    int result = myForeground != null ? myForeground.hashCode() : 0;
-    result = 31 * result + (myBackground != null ? myBackground.hashCode() : 0);
-    result = 31 * result + myFontType;
-    result = 31 * result + (myEffectColor != null ? myEffectColor.hashCode() : 0);
-    result = 31 * result + (myEffectType != null ? myEffectType.hashCode() : 0);
-    result = 31 * result + (myErrorStripeColor != null ? myErrorStripeColor.hashCode() : 0);
+  private static int calcHashCode(Color foreground,
+                                  Color background,
+                                  int fontType,
+                                  Color effectColor,
+                                  EffectType effectType,
+                                  Color errorStripeColor) {
+    int result = foreground != null ? foreground.hashCode() : 0;
+    result = 31 * result + (background != null ? background.hashCode() : 0);
+    result = 31 * result + fontType;
+    result = 31 * result + (effectColor != null ? effectColor.hashCode() : 0);
+    result = 31 * result + (effectType != null ? effectType.hashCode() : 0);
+    result = 31 * result + (errorStripeColor != null ? errorStripeColor.hashCode() : 0);
     return result;
   }
 
@@ -163,28 +168,34 @@
     return myErrorStripeColor;
   }
 
-  public AttributesFlyweight withForeground(Color fore) {
-    return create(fore, myBackground, myFontType, myEffectColor, myEffectType, myErrorStripeColor);
+  @NotNull
+  public AttributesFlyweight withForeground(Color foreground) {
+    return Comparing.equal(foreground, myForeground) ? this : create(foreground, myBackground, myFontType, myEffectColor, myEffectType, myErrorStripeColor);
   }
 
-  public AttributesFlyweight withBackground(Color back) {
-    return create(myForeground, back, myFontType, myEffectColor, myEffectType, myErrorStripeColor);
+  @NotNull
+  public AttributesFlyweight withBackground(Color background) {
+    return Comparing.equal(background, myBackground) ? this : create(myForeground, background, myFontType, myEffectColor, myEffectType, myErrorStripeColor);
   }
 
+  @NotNull
   public AttributesFlyweight withFontType(@JdkConstants.FontStyle int fontType) {
-    return create(myForeground, myBackground, fontType, myEffectColor, myEffectType, myErrorStripeColor);
+    return fontType == myFontType ? this : create(myForeground, myBackground, fontType, myEffectColor, myEffectType, myErrorStripeColor);
   }
 
+  @NotNull
   public AttributesFlyweight withEffectColor(Color effectColor) {
-    return create(myForeground, myBackground, myFontType, effectColor, myEffectType, myErrorStripeColor);
+    return Comparing.equal(effectColor, myEffectColor) ? this : create(myForeground, myBackground, myFontType, effectColor, myEffectType, myErrorStripeColor);
   }
 
+  @NotNull
   public AttributesFlyweight withEffectType(EffectType effectType) {
-    return create(myForeground, myBackground, myFontType, myEffectColor, effectType, myErrorStripeColor);
+    return Comparing.equal(effectType, myEffectType) ? this : create(myForeground, myBackground, myFontType, myEffectColor, effectType, myErrorStripeColor);
   }
 
+  @NotNull
   public AttributesFlyweight withErrorStripeColor(Color stripeColor) {
-    return create(myForeground, myBackground, myFontType, myEffectColor, myEffectType, stripeColor);
+    return Comparing.equal(stripeColor, myErrorStripeColor) ? this : create(myForeground, myBackground, myFontType, myEffectColor, myEffectType, stripeColor);
   }
 
   @Override
@@ -212,19 +223,7 @@
   @NonNls
   @Override
   public String toString() {
-    return "AttributesFlyweight{" +
-           "myForeground=" +
-           myForeground +
-           ", myBackground=" +
-           myBackground +
-           ", myFontType=" +
-           myFontType +
-           ", myEffectColor=" +
-           myEffectColor +
-           ", myEffectType=" +
-           myEffectType +
-           ", myErrorStripeColor=" +
-           myErrorStripeColor +
-           '}';
+    return "AttributesFlyweight{myForeground=" + myForeground + ", myBackground=" + myBackground + ", myFontType=" + myFontType +
+           ", myEffectColor=" + myEffectColor + ", myEffectType=" + myEffectType + ", myErrorStripeColor=" + myErrorStripeColor + '}';
   }
 }
diff --git a/platform/core-api/src/com/intellij/openapi/editor/markup/TextAttributes.java b/platform/core-api/src/com/intellij/openapi/editor/markup/TextAttributes.java
index 715e700..e504a8c 100644
--- a/platform/core-api/src/com/intellij/openapi/editor/markup/TextAttributes.java
+++ b/platform/core-api/src/com/intellij/openapi/editor/markup/TextAttributes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2010 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.
@@ -16,9 +16,13 @@
 package com.intellij.openapi.editor.markup;
 
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.DefaultJDOMExternalizer;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
 import org.intellij.lang.annotations.JdkConstants;
 import org.jdom.Element;
+import org.jetbrains.annotations.Contract;
 import org.jetbrains.annotations.NotNull;
 
 import java.awt.*;
@@ -34,6 +38,9 @@
 
   private boolean myEnforcedDefaults = false;
 
+  @NotNull
+  private AttributesFlyweight myAttrs;
+
   /**
    * Merges (layers) the two given text attributes.
    *
@@ -41,6 +48,7 @@
    * @param above Text attributes to merge "above", overriding settings from "under".
    * @return Merged attributes instance.
    */
+  @Contract("!null, !null -> !null")
   public static TextAttributes merge(TextAttributes under, TextAttributes above) {
     if (under == null) return above;
     if (above == null) return under;
@@ -154,8 +162,6 @@
     }
   }
 
-  private AttributesFlyweight myAttrs;
-
   public TextAttributes() {
     this(null, null, null, EffectType.BOXED, Font.PLAIN);
   }
@@ -194,7 +200,7 @@
   }
 
   @NotNull
-  public static TextAttributes fromFlyweight(AttributesFlyweight flyweight) {
+  public static TextAttributes fromFlyweight(@NotNull AttributesFlyweight flyweight) {
     TextAttributes f = new TextAttributes();
     f.myAttrs = flyweight;
     return f;
@@ -277,12 +283,7 @@
   public void readExternal(Element element) throws InvalidDataException {
     Externalizable ext = new Externalizable();
     ext.readExternal(element);
-    myAttrs = AttributesFlyweight.create(ext.FOREGROUND,
-                                         ext.BACKGROUND,
-                                         ext.FONT_TYPE,
-                                         ext.EFFECT_COLOR,
-                                         ext.getEffectType(),
-                                         ext.ERROR_STRIPE_COLOR);
+    myAttrs = AttributesFlyweight.create(ext.FOREGROUND, ext.BACKGROUND, ext.FONT_TYPE, ext.EFFECT_COLOR, ext.getEffectType(), ext.ERROR_STRIPE_COLOR);
     if (isEmpty()) myEnforcedDefaults = true;
   }
 
@@ -302,18 +303,7 @@
 
   @Override
   public String toString() {
-    return "[" +
-           getForegroundColor() +
-           "," +
-           getBackgroundColor() +
-           "," +
-           getFontType() +
-           "," +
-           getEffectType() +
-           "," +
-           getEffectColor() +
-           "," +
-           getErrorStripeColor() +
-           "]";
+    return "[" + getForegroundColor() + "," + getBackgroundColor() + "," + getFontType() + "," + getEffectType() + "," +
+           getEffectColor() + "," + getErrorStripeColor() + "]";
   }
 }
diff --git a/platform/core-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionFactory.java b/platform/core-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionFactory.java
new file mode 100644
index 0000000..2378fd5
--- /dev/null
+++ b/platform/core-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionFactory.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.openapi.fileTypes;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.KeyedExtensionFactory;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+public class FileTypeExtensionFactory<T> extends KeyedExtensionFactory<T, FileType> {
+  public FileTypeExtensionFactory(@NotNull final Class<T> interfaceClass, @NonNls @NotNull final String epName) {
+    super(interfaceClass, epName, ApplicationManager.getApplication().getPicoContainer());
+  }
+
+  @Override
+  public String getKey(@NotNull final FileType key) {
+    return key.getName();
+  }
+}
\ No newline at end of file
diff --git a/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java b/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
index a1a88c6..6cda4f5 100644
--- a/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
+++ b/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
@@ -22,6 +22,7 @@
   public static final String APPCODE_PREFIX = "AppCode";
   public static final String CPP_PREFIX = "CppIde";
   public static final String PYCHARM_PREFIX = "Python";
+  public static final String PYCHARM_PREFIX2 = "PyCharm";
   public static final String RUBY_PREFIX = "Ruby";
   public static final String PHP_PREFIX = "PhpStorm";
   public static final String WEB_PREFIX = "WebStorm";
@@ -56,7 +57,8 @@
   }
 
   public static boolean isPyCharm() {
-    return PYCHARM_PREFIX.equals(getPlatformPrefix());
+    String prefix = getPlatformPrefix();
+    return PYCHARM_PREFIX.equals(prefix) || (prefix != null && prefix.startsWith(PYCHARM_PREFIX2));
   }
 
   public static boolean isPhpStorm() {
@@ -67,10 +69,6 @@
     return WEB_PREFIX.equals(getPlatformPrefix());
   }
 
-  public static boolean isFlexIde() {
-    return FLEX_PREFIX.equals(getPlatformPrefix());
-  }
-
   public static boolean isIntelliJ() {
     return isIdea() || isCommunity();
   }
diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactory.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactory.java
index 8e31061..010b595 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactory.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactory.java
@@ -32,6 +32,7 @@
     return ServiceManager.getService(project, PsiDirectoryFactory.class);
   }
 
+  @NotNull
   public abstract PsiDirectory createDirectory(@NotNull VirtualFile file);
 
   @NotNull
@@ -40,7 +41,7 @@
   @Nullable
   public abstract PsiDirectoryContainer getDirectoryContainer(@NotNull PsiDirectory directory);
 
-  public abstract boolean isPackage(PsiDirectory directory);
+  public abstract boolean isPackage(@NotNull PsiDirectory directory);
 
-  public abstract boolean isValidPackageName(String name);
+  public abstract boolean isValidPackageName(@Nullable String name);
 }
diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java
index ddbf1ef..d999602 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java
@@ -32,6 +32,7 @@
   public PsiDirectoryFactoryImpl(final PsiManagerImpl manager) {
     myManager = manager;
   }
+  @NotNull
   @Override
   public PsiDirectory createDirectory(@NotNull final VirtualFile file) {
     return new PsiDirectoryImpl(myManager, file);
@@ -52,7 +53,7 @@
   }
 
   @Override
-  public boolean isPackage(PsiDirectory directory) {
+  public boolean isPackage(@NotNull PsiDirectory directory) {
     return false;
   }
 
diff --git a/platform/editor-ui-api/editor-ui-api.iml b/platform/editor-ui-api/editor-ui-api.iml
index a47a2d5..3de8227 100644
--- a/platform/editor-ui-api/editor-ui-api.iml
+++ b/platform/editor-ui-api/editor-ui-api.iml
@@ -11,6 +11,7 @@
     <orderEntry type="module" module-name="util" />
     <orderEntry type="module" module-name="annotations" />
     <orderEntry type="module" module-name="projectModel-api" />
+    <orderEntry type="module" module-name="indexing-api" />
   </component>
 </module>
 
diff --git a/platform/editor-ui-api/src/com/intellij/ide/highlighter/HighlighterFactory.java b/platform/editor-ui-api/src/com/intellij/ide/highlighter/HighlighterFactory.java
new file mode 100644
index 0000000..e94ba79
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/ide/highlighter/HighlighterFactory.java
@@ -0,0 +1,64 @@
+/*
+ * 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.ide.highlighter;
+
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.highlighter.EditorHighlighter;
+import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.SyntaxHighlighter;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+public class HighlighterFactory {
+  private HighlighterFactory() {}
+
+  @NotNull
+  public static EditorHighlighter createHighlighter(SyntaxHighlighter highlighter, @NotNull EditorColorsScheme settings) {
+    return EditorHighlighterFactory.getInstance().createEditorHighlighter(highlighter, settings);
+  }
+
+  @NotNull
+  public static EditorHighlighter createHighlighter(Project project, @NotNull String fileName) {
+    return EditorHighlighterFactory.getInstance().createEditorHighlighter(project, fileName);
+  }
+
+  @NotNull
+  public static EditorHighlighter createHighlighter(Project project, @NotNull VirtualFile file) {
+    return EditorHighlighterFactory.getInstance().createEditorHighlighter(project, file);
+  }
+
+  @NotNull
+  public static EditorHighlighter createHighlighter(Project project, @NotNull FileType fileType) {
+    return EditorHighlighterFactory.getInstance().createEditorHighlighter(project, fileType);
+  }
+
+  @NotNull
+  public static EditorHighlighter createHighlighter(@NotNull EditorColorsScheme settings, @NotNull String fileName, Project project) {
+    return EditorHighlighterFactory.getInstance().createEditorHighlighter(settings, fileName, project);
+  }
+
+  @NotNull
+  public static EditorHighlighter createHighlighter(@NotNull FileType fileType, @NotNull EditorColorsScheme settings, Project project) {
+    return EditorHighlighterFactory.getInstance().createEditorHighlighter(fileType, settings, project);
+  }
+
+  @NotNull
+  public static EditorHighlighter createHighlighter(@NotNull VirtualFile vFile, @NotNull EditorColorsScheme settings, Project project) {
+    return EditorHighlighterFactory.getInstance().createEditorHighlighter(vFile, settings, project);
+  }
+}
\ No newline at end of file
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactory.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactory.java
new file mode 100644
index 0000000..8577857
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactory.java
@@ -0,0 +1,56 @@
+/*
+ * 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.openapi.editor.highlighter;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.SyntaxHighlighter;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author yole
+ */
+public abstract class EditorHighlighterFactory {
+
+  public static EditorHighlighterFactory getInstance() {
+    return ServiceManager.getService(EditorHighlighterFactory.class);
+  }
+
+  @NotNull
+  public abstract EditorHighlighter createEditorHighlighter(final SyntaxHighlighter syntaxHighlighter, @NotNull EditorColorsScheme colors);
+
+  @NotNull
+  public abstract EditorHighlighter createEditorHighlighter(@NotNull FileType fileType, @NotNull EditorColorsScheme settings, final Project project);
+
+  @NotNull
+  public abstract EditorHighlighter createEditorHighlighter(final Project project, @NotNull FileType fileType);
+
+  @NotNull
+  public abstract EditorHighlighter createEditorHighlighter(@NotNull final VirtualFile file, @NotNull EditorColorsScheme globalScheme, @Nullable final Project project);
+
+  @NotNull
+  public abstract EditorHighlighter createEditorHighlighter(final Project project, @NotNull VirtualFile file);
+
+  @NotNull
+  public abstract EditorHighlighter createEditorHighlighter(final Project project, @NotNull String fileName);
+
+  @NotNull
+  public abstract EditorHighlighter createEditorHighlighter(@NotNull EditorColorsScheme settings, @NotNull String fileName, @Nullable final Project project);
+}
\ No newline at end of file
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighter.java b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighter.java
new file mode 100644
index 0000000..a1105ab
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighter.java
@@ -0,0 +1,39 @@
+/*
+ * 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.openapi.fileTypes;
+
+import com.intellij.lexer.EmptyLexer;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.editor.HighlighterColors;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+
+public class PlainSyntaxHighlighter implements SyntaxHighlighter {
+  private static final TextAttributesKey[] ATTRS = {HighlighterColors.TEXT};
+
+  @Override
+  @NotNull
+  public Lexer getHighlightingLexer() {
+    return new EmptyLexer();
+  }
+
+  @Override
+  @NotNull
+  public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
+    return ATTRS;
+  }
+}
\ No newline at end of file
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighterFactory.java b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighterFactory.java
new file mode 100644
index 0000000..df5a83e
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighterFactory.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.openapi.fileTypes;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+public class PlainSyntaxHighlighterFactory extends SyntaxHighlighterFactory {
+  @NotNull
+  public SyntaxHighlighter getSyntaxHighlighter(final Project project, final VirtualFile virtualFile) {
+    return new PlainSyntaxHighlighter();
+  }
+}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java
new file mode 100644
index 0000000..d6c7dc3
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java
@@ -0,0 +1,56 @@
+/*
+ * 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.openapi.fileTypes;
+
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Controls the syntax highlighting of a file.
+ *
+ * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
+ * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.lang.Language, com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
+ */
+public interface SyntaxHighlighter {
+  /**
+   * @deprecated
+   * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
+   * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.lang.Language, com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
+   */
+  SyntaxHighlighterProvider PROVIDER =
+    new FileTypeExtensionFactory<SyntaxHighlighterProvider>(SyntaxHighlighterProvider.class, "com.intellij.syntaxHighlighter").get();
+
+  /**
+   * Returns the lexer used for highlighting the file. The lexer is invoked incrementally when the file is changed, so it must be
+   * capable of saving/restoring state and resuming lexing from the middle of the file.
+   *
+   * @return The lexer implementation.
+   */
+  @NotNull
+  Lexer getHighlightingLexer();
+
+  /**
+   * Returns the list of text attribute keys used for highlighting the specified token type. The attributes of all attribute keys
+   * returned for the token type are successively merged to obtain the color and attributes of the token.
+   *
+   * @param tokenType The token type for which the highlighting is requested.
+   * @return The array of text attribute keys.
+   */
+  @NotNull
+  TextAttributesKey[] getTokenHighlights(IElementType tokenType);
+}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java
new file mode 100644
index 0000000..7f9fc89
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java
@@ -0,0 +1,70 @@
+/*
+ * 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.openapi.fileTypes;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author max
+ */
+public abstract class SyntaxHighlighterFactory {
+  public static final SyntaxHighlighterLanguageFactory LANGUAGE_FACTORY = new SyntaxHighlighterLanguageFactory();
+
+  /**
+   * Returns syntax highlighter for the given language.
+   *
+   * @param language a {@code Language} to get highlighter for
+   * @param project  might be necessary to gather various project settings from
+   * @param file     might be necessary to collect file specific settings
+   * @return {@code SyntaxHighlighter} interface implementation for the given file type
+   */
+  public static SyntaxHighlighter getSyntaxHighlighter(@NotNull Language language, @Nullable Project project, @Nullable VirtualFile file) {
+    return LANGUAGE_FACTORY.forLanguage(language).getSyntaxHighlighter(project, file);
+  }
+
+  /**
+   * Returns syntax highlighter for the given file type.
+   * Note: it is recommended to use {@link #getSyntaxHighlighter(Language, Project, VirtualFile)} in most cases,
+   * and use this method only when you are do not know the language you use.
+   *
+   * @param fileType a file type to use to select appropriate highlighter
+   * @param project  might be necessary to gather various project settings from
+   * @param file     might be necessary to collect file specific settings
+   * @return {@code SyntaxHighlighter} interface implementation for the given file type
+   */
+  @Nullable
+  public static SyntaxHighlighter getSyntaxHighlighter(@NotNull FileType fileType, @Nullable Project project, @Nullable VirtualFile file) {
+    return SyntaxHighlighter.PROVIDER.create(fileType, project, file);
+  }
+
+  /**
+   * Override this method to provide syntax highlighting (coloring) capabilities for your language implementation.
+   * By syntax highlighting we mean highlighting of keywords, comments, braces etc. where lexing the file content is enough
+   * to identify proper highlighting attributes.
+   * <p/>
+   * Default implementation doesn't highlight anything.
+   *
+   * @param project     might be necessary to gather various project settings from.
+   * @param virtualFile might be necessary to collect file specific settings
+   * @return <code>SyntaxHighlighter</code> interface implementation for this particular language.
+   */
+  @NotNull
+  public abstract SyntaxHighlighter getSyntaxHighlighter(@Nullable Project project, @Nullable VirtualFile virtualFile);
+}
\ No newline at end of file
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterLanguageFactory.java b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterLanguageFactory.java
new file mode 100644
index 0000000..dae292f0
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterLanguageFactory.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.openapi.fileTypes;
+
+import com.intellij.lang.LanguageExtension;
+
+public class SyntaxHighlighterLanguageFactory extends LanguageExtension<SyntaxHighlighterFactory> {
+  SyntaxHighlighterLanguageFactory() {
+    super("com.intellij.lang.syntaxHighlighterFactory", new PlainSyntaxHighlighterFactory());
+  }
+}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterProvider.java b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterProvider.java
new file mode 100644
index 0000000..bb5fb4f
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterProvider.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/*
+ * Created by IntelliJ IDEA.
+ * User: yole
+ * Date: 06.11.2007
+ * Time: 19:49:57
+ */
+package com.intellij.openapi.fileTypes;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public interface SyntaxHighlighterProvider {
+  @Nullable
+  SyntaxHighlighter create(@NotNull FileType fileType, @Nullable Project project, @Nullable VirtualFile file);
+}
\ No newline at end of file
diff --git a/platform/lang-api/src/com/intellij/psi/search/TodoAttributesUtil.java b/platform/editor-ui-api/src/com/intellij/psi/search/TodoAttributesUtil.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/psi/search/TodoAttributesUtil.java
rename to platform/editor-ui-api/src/com/intellij/psi/search/TodoAttributesUtil.java
diff --git a/platform/editor-ui-ex/editor-ui-ex.iml b/platform/editor-ui-ex/editor-ui-ex.iml
index 7d91a31..ce87b28 100644
--- a/platform/editor-ui-ex/editor-ui-ex.iml
+++ b/platform/editor-ui-ex/editor-ui-ex.iml
@@ -11,6 +11,8 @@
     <orderEntry type="module" module-name="util" exported="" />
     <orderEntry type="module" module-name="annotations" exported="" />
     <orderEntry type="module" module-name="core-impl" exported="" />
+    <orderEntry type="module" module-name="indexing-impl" />
+    <orderEntry type="module" module-name="projectModel-api" />
   </component>
 </module>
 
diff --git a/platform/editor-ui-ex/src/com/intellij/ide/todo/TodoConfiguration.java b/platform/editor-ui-ex/src/com/intellij/ide/todo/TodoConfiguration.java
new file mode 100644
index 0000000..1eb963e
--- /dev/null
+++ b/platform/editor-ui-ex/src/com/intellij/ide/todo/TodoConfiguration.java
@@ -0,0 +1,204 @@
+/*
+ * 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.ide.todo;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.components.NamedComponent;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.psi.search.*;
+import com.intellij.util.EventDispatcher;
+import com.intellij.util.messages.MessageBus;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Vladimir Kondratyev
+ */
+public class TodoConfiguration implements NamedComponent, JDOMExternalizable {
+  private TodoPattern[] myTodoPatterns;
+  private TodoFilter[] myTodoFilters;
+  private IndexPattern[] myIndexPatterns;
+
+  private final EventDispatcher<PropertyChangeListener> myPropertyChangeMulticaster = EventDispatcher.create(PropertyChangeListener.class);
+
+  @NonNls public static final String PROP_TODO_PATTERNS = "todoPatterns";
+  @NonNls public static final String PROP_TODO_FILTERS = "todoFilters";
+  @NonNls private static final String ELEMENT_PATTERN = "pattern";
+  @NonNls private static final String ELEMENT_FILTER = "filter";
+  private final MessageBus myMessageBus;
+
+  /**
+   * Invoked by reflection
+   */
+  TodoConfiguration(@NotNull MessageBus messageBus) {
+    myMessageBus = messageBus;
+    resetToDefaultTodoPatterns();
+  }
+
+  public void resetToDefaultTodoPatterns() {
+    myTodoPatterns = new TodoPattern[]{
+      new TodoPattern("\\btodo\\b.*", TodoAttributesUtil.createDefault(), false),
+      new TodoPattern("\\bfixme\\b.*", TodoAttributesUtil.createDefault(), false),
+    };
+    myTodoFilters = new TodoFilter[]{};
+    buildIndexPatterns();
+  }
+
+  private void buildIndexPatterns() {
+    myIndexPatterns = new IndexPattern[myTodoPatterns.length];
+    for(int i=0; i<myTodoPatterns.length; i++) {
+      myIndexPatterns [i] = myTodoPatterns [i].getIndexPattern();
+    }
+  }
+
+  public static TodoConfiguration getInstance() {
+    return ServiceManager.getService(TodoConfiguration.class);
+  }
+
+  @Override
+  @NotNull
+  public String getComponentName() {
+    return "TodoConfiguration";
+  }
+
+  @NotNull
+  public TodoPattern[] getTodoPatterns() {
+    return myTodoPatterns;
+  }
+
+  @NotNull
+  public IndexPattern[] getIndexPatterns() {
+    return myIndexPatterns;
+  }
+
+  public void setTodoPatterns(@NotNull TodoPattern[] todoPatterns) {
+    doSetTodoPatterns(todoPatterns, true);
+  }
+
+  private void doSetTodoPatterns(@NotNull TodoPattern[] todoPatterns, final boolean shouldNotifyIndices) {
+    TodoPattern[] oldTodoPatterns = myTodoPatterns;
+    IndexPattern[] oldIndexPatterns = myIndexPatterns;
+
+    myTodoPatterns = todoPatterns;
+    buildIndexPatterns();
+
+    // only trigger index refresh actual index patterns have changed
+    if (shouldNotifyIndices && !Arrays.deepEquals(myIndexPatterns, oldIndexPatterns)) {
+      final PropertyChangeEvent event =
+        new PropertyChangeEvent(this, IndexPatternProvider.PROP_INDEX_PATTERNS, oldTodoPatterns, todoPatterns);
+      myMessageBus.syncPublisher(IndexPatternProvider.INDEX_PATTERNS_CHANGED).propertyChange(event);
+    }
+
+    // only trigger gui and code daemon refresh when either the index patterns or presentation attributes have changed
+    if (!Arrays.deepEquals(myTodoPatterns, oldTodoPatterns)) {
+      final PropertyChangeListener multicaster = myPropertyChangeMulticaster.getMulticaster();
+      multicaster.propertyChange(new PropertyChangeEvent(this, PROP_TODO_PATTERNS, oldTodoPatterns, todoPatterns));
+    }
+  }
+
+  /**
+   * @return <code>TodoFilter</code> with specified <code>name</code>. Method returns
+   *         <code>null</code> if there is no filter with <code>name</code>.
+   */
+  public TodoFilter getTodoFilter(String name) {
+    for (TodoFilter filter : myTodoFilters) {
+      if (filter.getName().equals(name)) {
+        return filter;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * @return all <code>TodoFilter</code>s.
+   */
+  @NotNull
+  public TodoFilter[] getTodoFilters() {
+    return myTodoFilters;
+  }
+
+  public void setTodoFilters(@NotNull TodoFilter[] filters) {
+    TodoFilter[] oldFilters = myTodoFilters;
+    myTodoFilters = filters;
+    myPropertyChangeMulticaster.getMulticaster().propertyChange(new PropertyChangeEvent(this, PROP_TODO_FILTERS, oldFilters, filters));
+  }
+
+  public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {
+    myPropertyChangeMulticaster.addListener(listener);
+  }
+  public void addPropertyChangeListener(@NotNull PropertyChangeListener listener, @NotNull Disposable parentDisposable) {
+    myPropertyChangeMulticaster.addListener(listener,parentDisposable);
+  }
+  public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) {
+    myPropertyChangeMulticaster.removeListener(listener);
+  }
+
+  @Override
+  public void readExternal(Element element) throws InvalidDataException {
+    List<TodoPattern> patternsList = new ArrayList<TodoPattern>();
+    List<TodoFilter> filtersList = new ArrayList<TodoFilter>();
+    for (Element child : element.getChildren()) {
+      if (ELEMENT_PATTERN.equals(child.getName())) {
+        TodoPattern pattern = new TodoPattern(TodoAttributesUtil.createDefault());
+        pattern.readExternal(child, TodoAttributesUtil.getDefaultColorSchemeTextAttributes());
+        patternsList.add(pattern);
+      }
+      else if (ELEMENT_FILTER.equals(child.getName())) {
+        TodoPattern[] patterns = patternsList.toArray(new TodoPattern[patternsList.size()]);
+        TodoFilter filter = new TodoFilter();
+        filter.readExternal(child, patterns);
+        filtersList.add(filter);
+      }
+    }
+    doSetTodoPatterns(patternsList.toArray(new TodoPattern[patternsList.size()]), false);
+    setTodoFilters(filtersList.toArray(new TodoFilter[filtersList.size()]));
+  }
+
+  @Override
+  public void writeExternal(Element element) throws WriteExternalException {
+    final TodoPattern[] todoPatterns = myTodoPatterns;
+    for (TodoPattern pattern : todoPatterns) {
+      Element child = new Element(ELEMENT_PATTERN);
+      pattern.writeExternal(child);
+      element.addContent(child);
+    }
+    for (TodoFilter filter : myTodoFilters) {
+      Element child = new Element(ELEMENT_FILTER);
+      filter.writeExternal(child, todoPatterns);
+      element.addContent(child);
+    }
+  }
+
+  public void colorSettingsChanged() {
+    for (TodoPattern pattern : myTodoPatterns) {
+      TodoAttributes attributes = pattern.getAttributes();
+      if (!attributes.shouldUseCustomTodoColor()) {
+        attributes.setUseCustomTodoColor(false, TodoAttributesUtil.getDefaultColorSchemeTextAttributes());
+      }
+    }
+  }
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/todo/TodoIndexPatternProvider.java b/platform/editor-ui-ex/src/com/intellij/ide/todo/TodoIndexPatternProvider.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/ide/todo/TodoIndexPatternProvider.java
rename to platform/editor-ui-ex/src/com/intellij/ide/todo/TodoIndexPatternProvider.java
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java
similarity index 100%
rename from platform/platform-impl/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java
rename to platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexTodoCacheManagerImpl.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/IndexTodoCacheManagerImpl.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexTodoCacheManagerImpl.java
rename to platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/IndexTodoCacheManagerImpl.java
diff --git a/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java
new file mode 100644
index 0000000..556db38
--- /dev/null
+++ b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java
@@ -0,0 +1,250 @@
+/*
+ * 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 com.intellij.psi.impl.cache.impl.id;
+
+import com.intellij.ide.highlighter.HighlighterFactory;
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageParserDefinitions;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
+import com.intellij.openapi.editor.highlighter.EditorHighlighter;
+import com.intellij.openapi.editor.highlighter.HighlighterIterator;
+import com.intellij.openapi.fileTypes.*;
+import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.CustomHighlighterTokenType;
+import com.intellij.psi.impl.cache.impl.BaseFilterLexer;
+import com.intellij.psi.impl.cache.CacheUtil;
+import com.intellij.psi.impl.cache.impl.IndexPatternUtil;
+import com.intellij.psi.impl.cache.impl.OccurrenceConsumer;
+import com.intellij.psi.impl.cache.impl.todo.TodoIndexEntry;
+import com.intellij.psi.impl.cache.impl.todo.TodoIndexers;
+import com.intellij.psi.search.IndexPattern;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.indexing.DataIndexer;
+import com.intellij.util.indexing.FileContent;
+import com.intellij.util.indexing.SubstitutedFileType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Author: dmitrylomov
+ */
+public abstract class PlatformIdTableBuilding {
+  public static final Key<EditorHighlighter> EDITOR_HIGHLIGHTER = new Key<EditorHighlighter>("Editor");
+  private static final Map<FileType, DataIndexer<TodoIndexEntry, Integer, FileContent>> ourTodoIndexers = new HashMap<FileType, DataIndexer<TodoIndexEntry, Integer, FileContent>>();
+  private static final TokenSet ABSTRACT_FILE_COMMENT_TOKENS = TokenSet.create(CustomHighlighterTokenType.LINE_COMMENT, CustomHighlighterTokenType.MULTI_LINE_COMMENT);
+
+  private PlatformIdTableBuilding() {}
+
+  @Nullable
+  public static DataIndexer<TodoIndexEntry, Integer, FileContent> getTodoIndexer(FileType fileType, final VirtualFile virtualFile) {
+    final DataIndexer<TodoIndexEntry, Integer, FileContent> indexer = ourTodoIndexers.get(fileType);
+
+    if (indexer != null) {
+      return indexer;
+    }
+
+    final DataIndexer<TodoIndexEntry, Integer, FileContent> extIndexer;
+    if (fileType instanceof SubstitutedFileType && !((SubstitutedFileType)fileType).isSameFileType()) {
+      SubstitutedFileType sft = (SubstitutedFileType)fileType;
+      extIndexer =
+        new CompositeTodoIndexer(getTodoIndexer(sft.getOriginalFileType(), virtualFile), getTodoIndexer(sft.getFileType(), virtualFile));
+    }
+    else {
+      extIndexer = TodoIndexers.INSTANCE.forFileType(fileType);
+    }
+    if (extIndexer != null) {
+      return extIndexer;
+    }
+
+    if (fileType instanceof LanguageFileType) {
+      final Language lang = ((LanguageFileType)fileType).getLanguage();
+      final ParserDefinition parserDef = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
+      final TokenSet commentTokens = parserDef != null ? parserDef.getCommentTokens() : null;
+      if (commentTokens != null) {
+        return new TokenSetTodoIndexer(commentTokens, virtualFile);
+      }
+    }
+
+    if (fileType instanceof CustomSyntaxTableFileType) {
+      return new TokenSetTodoIndexer(ABSTRACT_FILE_COMMENT_TOKENS, virtualFile);
+    }
+
+    return null;
+  }
+
+  public static boolean checkCanUseCachedEditorHighlighter(final CharSequence chars, final EditorHighlighter editorHighlighter) {
+    assert editorHighlighter instanceof LexerEditorHighlighter;
+    final boolean b = ((LexerEditorHighlighter)editorHighlighter).checkContentIsEqualTo(chars);
+    if (!b) {
+      final Logger logger = Logger.getInstance(IdTableBuilding.class.getName());
+      logger.warn("Unexpected mismatch of editor highlighter content with indexing content");
+    }
+    return b;
+  }
+
+  @Deprecated
+  public static void registerTodoIndexer(@NotNull FileType fileType, DataIndexer<TodoIndexEntry, Integer, FileContent> indexer) {
+    ourTodoIndexers.put(fileType, indexer);
+  }
+
+  public static boolean isTodoIndexerRegistered(@NotNull FileType fileType) {
+    return ourTodoIndexers.containsKey(fileType) || TodoIndexers.INSTANCE.forFileType(fileType) != null || fileType instanceof InternalFileType;
+  }
+
+  private static class CompositeTodoIndexer implements DataIndexer<TodoIndexEntry, Integer, FileContent> {
+    private final DataIndexer<TodoIndexEntry, Integer, FileContent>[] indexers;
+
+    public CompositeTodoIndexer(@NotNull DataIndexer<TodoIndexEntry, Integer, FileContent>... indexers) {
+      this.indexers = indexers;
+    }
+
+    @NotNull
+    @Override
+    public Map<TodoIndexEntry, Integer> map(FileContent inputData) {
+      Map<TodoIndexEntry, Integer> result = ContainerUtil.newTroveMap();
+      for (DataIndexer<TodoIndexEntry, Integer, FileContent> indexer : indexers) {
+        for (Map.Entry<TodoIndexEntry, Integer> entry : indexer.map(inputData).entrySet()) {
+          TodoIndexEntry key = entry.getKey();
+          if (result.containsKey(key)) {
+            result.put(key, result.get(key) + entry.getValue());
+          } else {
+            result.put(key, entry.getValue());
+          }
+        }
+      }
+      return result;
+    }
+  }
+
+  private static class TokenSetTodoIndexer implements DataIndexer<TodoIndexEntry, Integer, FileContent> {
+    @NotNull private final TokenSet myCommentTokens;
+    private final VirtualFile myFile;
+
+    public TokenSetTodoIndexer(@NotNull final TokenSet commentTokens, @NotNull final VirtualFile file) {
+      myCommentTokens = commentTokens;
+      myFile = file;
+    }
+
+    @Override
+    @NotNull
+    public Map<TodoIndexEntry, Integer> map(final FileContent inputData) {
+      if (IndexPatternUtil.getIndexPatternCount() > 0) {
+        final CharSequence chars = inputData.getContentAsText();
+        final OccurrenceConsumer occurrenceConsumer = new OccurrenceConsumer(null, true);
+        EditorHighlighter highlighter;
+
+        final EditorHighlighter editorHighlighter = inputData.getUserData(EDITOR_HIGHLIGHTER);
+        if (editorHighlighter != null && checkCanUseCachedEditorHighlighter(chars, editorHighlighter)) {
+          highlighter = editorHighlighter;
+        }
+        else {
+          highlighter = HighlighterFactory.createHighlighter(null, myFile);
+          highlighter.setText(chars);
+        }
+
+        final int documentLength = chars.length();
+        BaseFilterLexer.TodoScanningState todoScanningState = null;
+        final HighlighterIterator iterator = highlighter.createIterator(0);
+
+        while (!iterator.atEnd()) {
+          final IElementType token = iterator.getTokenType();
+
+          if (myCommentTokens.contains(token) || CacheUtil.isInComments(token)) {
+            int start = iterator.getStart();
+            if (start >= documentLength) break;
+            int end = iterator.getEnd();
+
+            todoScanningState = BaseFilterLexer.advanceTodoItemsCount(
+              chars.subSequence(start, Math.min(end, documentLength)),
+              occurrenceConsumer,
+              todoScanningState
+            );
+            if (end > documentLength) break;
+          }
+          iterator.advance();
+        }
+        final Map<TodoIndexEntry, Integer> map = new HashMap<TodoIndexEntry, Integer>();
+        for (IndexPattern pattern : IndexPatternUtil.getIndexPatterns()) {
+          final int count = occurrenceConsumer.getOccurrenceCount(pattern);
+          if (count > 0) {
+            map.put(new TodoIndexEntry(pattern.getPatternString(), pattern.isCaseSensitive()), count);
+          }
+        }
+        return map;
+      }
+      return Collections.emptyMap();
+    }
+  }
+
+  public static class PlainTextTodoIndexer implements DataIndexer<TodoIndexEntry, Integer, FileContent> {
+    @Override
+    @NotNull
+    public Map<TodoIndexEntry, Integer> map(final FileContent inputData) {
+      String chars = inputData.getContentAsText().toString(); // matching strings is faster than HeapCharBuffer
+
+      final IndexPattern[] indexPatterns = IndexPatternUtil.getIndexPatterns();
+      if (indexPatterns.length <= 0) {
+        return Collections.emptyMap();
+      }
+      OccurrenceConsumer occurrenceConsumer = new OccurrenceConsumer(null, true);
+      for (IndexPattern indexPattern : indexPatterns) {
+        Pattern pattern = indexPattern.getPattern();
+        if (pattern != null) {
+          Matcher matcher = pattern.matcher(chars);
+          while (matcher.find()) {
+            if (matcher.start() != matcher.end()) {
+              occurrenceConsumer.incTodoOccurrence(indexPattern);
+            }
+          }
+        }
+      }
+      Map<TodoIndexEntry, Integer> map = new HashMap<TodoIndexEntry, Integer>();
+      for (IndexPattern indexPattern : indexPatterns) {
+        final int count = occurrenceConsumer.getOccurrenceCount(indexPattern);
+        if (count > 0) {
+          map.put(new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), count);
+        }
+      }
+      return map;
+    }
+
+  }
+
+  static {
+    IdTableBuilding.registerIdIndexer(PlainTextFileType.INSTANCE, new IdTableBuilding.PlainTextIndexer());
+    registerTodoIndexer(PlainTextFileType.INSTANCE, new PlainTextTodoIndexer());
+
+    //IdTableBuilding.registerIdIndexer(StdFileTypes.IDEA_MODULE, null);
+    //IdTableBuilding.registerIdIndexer(StdFileTypes.IDEA_WORKSPACE, null);
+    //IdTableBuilding.registerIdIndexer(StdFileTypes.IDEA_PROJECT, null);
+
+    //registerTodoIndexer(StdFileTypes.IDEA_MODULE, null);
+    //registerTodoIndexer(StdFileTypes.IDEA_WORKSPACE, null);
+    //registerTodoIndexer(StdFileTypes.IDEA_PROJECT, null);
+  }
+}
diff --git a/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java
new file mode 100644
index 0000000..b9f8ec6
--- /dev/null
+++ b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java
@@ -0,0 +1,168 @@
+/*
+ * 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.psi.impl.cache.impl.todo;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageParserDefinitions;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding;
+import com.intellij.psi.search.IndexPatternProvider;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.util.indexing.*;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.KeyDescriptor;
+import com.intellij.util.messages.MessageBus;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Jan 20, 2008
+ */
+public class TodoIndex extends FileBasedIndexExtension<TodoIndexEntry, Integer> {
+  @NonNls public static final ID<TodoIndexEntry, Integer> NAME = ID.create("TodoIndex");
+
+  public TodoIndex(MessageBus messageBus) {
+    messageBus.connect().subscribe(IndexPatternProvider.INDEX_PATTERNS_CHANGED, new PropertyChangeListener() {
+      @Override
+      public void propertyChange(PropertyChangeEvent evt) {
+        FileBasedIndex.getInstance().requestRebuild(NAME);
+      }
+    });
+  }
+
+  private final KeyDescriptor<TodoIndexEntry> myKeyDescriptor = new KeyDescriptor<TodoIndexEntry>() {
+    @Override
+    public int getHashCode(final TodoIndexEntry value) {
+      return value.hashCode();
+    }
+
+    @Override
+    public boolean isEqual(final TodoIndexEntry val1, final TodoIndexEntry val2) {
+      return val1.equals(val2);
+    }
+
+    @Override
+    public void save(final DataOutput out, final TodoIndexEntry value) throws IOException {
+      out.writeUTF(value.pattern);
+      out.writeBoolean(value.caseSensitive);
+    }
+
+    @Override
+    public TodoIndexEntry read(final DataInput in) throws IOException {
+      final String pattern = in.readUTF();
+      final boolean caseSensitive = in.readBoolean();
+      return new TodoIndexEntry(pattern, caseSensitive);
+    }
+  };
+  
+  private final DataExternalizer<Integer> myValueExternalizer = new DataExternalizer<Integer>() {
+    @Override
+    public void save(final DataOutput out, final Integer value) throws IOException {
+      out.writeInt(value.intValue());
+    }
+
+    @Override
+    public Integer read(final DataInput in) throws IOException {
+      return Integer.valueOf(in.readInt());
+    }
+  };
+
+  private final DataIndexer<TodoIndexEntry, Integer, FileContent> myIndexer = new DataIndexer<TodoIndexEntry, Integer, FileContent>() {
+    @Override
+    @NotNull
+    public Map<TodoIndexEntry,Integer> map(final FileContent inputData) {
+      final VirtualFile file = inputData.getFile();
+      final DataIndexer<TodoIndexEntry, Integer, FileContent> indexer = PlatformIdTableBuilding
+        .getTodoIndexer(inputData.getFileType(), file);
+      if (indexer != null) {
+        return indexer.map(inputData);
+      }
+      return Collections.emptyMap();
+    }
+  };
+  
+  private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() {
+    @Override
+    public boolean acceptInput(final VirtualFile file) {
+      if (!file.isInLocalFileSystem()) {
+        return false; // do not index TODOs in library sources
+      }
+
+      final FileType fileType = file.getFileType();
+
+      if (fileType instanceof LanguageFileType) {
+        final Language lang = ((LanguageFileType)fileType).getLanguage();
+        final ParserDefinition parserDef = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
+        final TokenSet commentTokens = parserDef != null ? parserDef.getCommentTokens() : null;
+        return commentTokens != null;
+      }
+      
+      return PlatformIdTableBuilding.isTodoIndexerRegistered(fileType) ||
+             fileType instanceof CustomSyntaxTableFileType;
+    }
+  };
+
+  @Override
+  public int getVersion() {
+    return 5;
+  }
+
+  @Override
+  public boolean dependsOnFileContent() {
+    return true;
+  }
+
+  @NotNull
+  @Override
+  public ID<TodoIndexEntry, Integer> getName() {
+    return NAME;
+  }
+
+  @NotNull
+  @Override
+  public DataIndexer<TodoIndexEntry, Integer, FileContent> getIndexer() {
+    return myIndexer;
+  }
+
+  @Override
+  public KeyDescriptor<TodoIndexEntry> getKeyDescriptor() {
+    return myKeyDescriptor;
+  }
+
+  @Override
+  public DataExternalizer<Integer> getValueExternalizer() {
+    return myValueExternalizer;
+  }
+
+  @Override
+  public FileBasedIndex.InputFilter getInputFilter() {
+    return myInputFilter;
+  }
+}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternOccurrenceImpl.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternOccurrenceImpl.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternOccurrenceImpl.java
rename to platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternOccurrenceImpl.java
diff --git a/platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternSearcher.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternSearcher.java
new file mode 100644
index 0000000..d108c60
--- /dev/null
+++ b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternSearcher.java
@@ -0,0 +1,274 @@
+/*
+ * 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.psi.impl.search;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageParserDefinitions;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.SyntaxHighlighter;
+import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
+import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.cache.TodoCacheManager;
+import com.intellij.psi.search.IndexPattern;
+import com.intellij.psi.search.IndexPatternOccurrence;
+import com.intellij.psi.search.IndexPatternProvider;
+import com.intellij.psi.search.searches.IndexPatternSearch;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.util.Processor;
+import com.intellij.util.QueryExecutor;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.text.CharSequenceSubSequence;
+import gnu.trove.TIntArrayList;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author yole
+ */
+public class IndexPatternSearcher implements QueryExecutor<IndexPatternOccurrence, IndexPatternSearch.SearchParameters> {
+  @Override
+  public boolean execute(@NotNull final IndexPatternSearch.SearchParameters queryParameters,
+                         @NotNull final Processor<IndexPatternOccurrence> consumer) {
+    final PsiFile file = queryParameters.getFile();
+    VirtualFile virtualFile = file.getVirtualFile();
+    if (file instanceof PsiBinaryFile || file instanceof PsiCompiledElement || virtualFile == null) {
+      return true;
+    }
+
+    final TodoCacheManager cacheManager = TodoCacheManager.SERVICE.getInstance(file.getProject());
+    final IndexPatternProvider patternProvider = queryParameters.getPatternProvider();
+    int count = patternProvider != null
+                ? cacheManager.getTodoCount(virtualFile, patternProvider)
+                : cacheManager.getTodoCount(virtualFile, queryParameters.getPattern());
+    return count == 0 || executeImpl(queryParameters, consumer);
+  }
+
+  protected static boolean executeImpl(IndexPatternSearch.SearchParameters queryParameters,
+                                       Processor<IndexPatternOccurrence> consumer) {
+    final IndexPatternProvider patternProvider = queryParameters.getPatternProvider();
+    final PsiFile file = queryParameters.getFile();
+    TIntArrayList commentStarts = new TIntArrayList();
+    TIntArrayList commentEnds = new TIntArrayList();
+
+    final CharSequence chars = file.getViewProvider().getContents();
+    findCommentTokenRanges(file, chars, queryParameters.getRange(), commentStarts, commentEnds);
+    TIntArrayList occurrences = new TIntArrayList(1);
+    IndexPattern[] patterns = patternProvider != null ? patternProvider.getIndexPatterns() : null;
+
+    for (int i = 0; i < commentStarts.size(); i++) {
+      int commentStart = commentStarts.get(i);
+      int commentEnd = commentEnds.get(i);
+      occurrences.resetQuick();
+
+      if (patternProvider != null) {
+        for (int j = patterns.length - 1; j >=0; --j) {
+          if (!collectPatternMatches(patterns[j], chars, commentStart, commentEnd, file, queryParameters.getRange(), consumer, occurrences)) {
+            return false;
+          }
+        }
+      }
+      else {
+        if (!collectPatternMatches(queryParameters.getPattern(), chars, commentStart, commentEnd, file, queryParameters.getRange(),
+                                   consumer, occurrences)) {
+          return false;
+        }
+      }
+    }
+
+    return true;
+  }
+
+
+  private static final TokenSet COMMENT_TOKENS =
+    TokenSet.create(CustomHighlighterTokenType.LINE_COMMENT, CustomHighlighterTokenType.MULTI_LINE_COMMENT);
+
+  private static void findCommentTokenRanges(final PsiFile file,
+                                             final CharSequence chars,
+                                             final TextRange range,
+                                             final TIntArrayList commentStarts,
+                                             final TIntArrayList commentEnds) {
+    if (file instanceof PsiPlainTextFile) {
+      FileType fType = file.getFileType();
+      if (fType instanceof CustomSyntaxTableFileType) {
+        Lexer lexer = SyntaxHighlighterFactory.getSyntaxHighlighter(fType, file.getProject(), file.getVirtualFile()).getHighlightingLexer();
+        findComments(lexer, chars, range, COMMENT_TOKENS, commentStarts, commentEnds, null);
+      }
+      else {
+        commentStarts.add(0);
+        commentEnds.add(file.getTextLength());
+      }
+    }
+    else {
+      final FileViewProvider viewProvider = file.getViewProvider();
+      final Set<Language> relevantLanguages = viewProvider.getLanguages();
+      for (Language lang : relevantLanguages) {
+        final TIntArrayList commentStartsList = new TIntArrayList();
+        final TIntArrayList commentEndsList = new TIntArrayList();
+
+        final SyntaxHighlighter syntaxHighlighter =
+          SyntaxHighlighterFactory.getSyntaxHighlighter(lang, file.getProject(), file.getVirtualFile());
+        Lexer lexer = syntaxHighlighter.getHighlightingLexer();
+        TokenSet commentTokens = null;
+        IndexPatternBuilder builderForFile = null;
+        for (IndexPatternBuilder builder : Extensions.getExtensions(IndexPatternBuilder.EP_NAME)) {
+          Lexer lexerFromBuilder = builder.getIndexingLexer(file);
+          if (lexerFromBuilder != null) {
+            lexer = lexerFromBuilder;
+            commentTokens = builder.getCommentTokenSet(file);
+            builderForFile = builder;
+          }
+        }
+        if (builderForFile == null) {
+          final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
+          if (parserDefinition != null) {
+            commentTokens = parserDefinition.getCommentTokens();
+          }
+        }
+
+        if (commentTokens != null) {
+          findComments(lexer, chars, range, commentTokens, commentStartsList, commentEndsList, builderForFile);
+          mergeCommentLists(commentStarts, commentEnds, commentStartsList, commentEndsList);
+        }
+      }
+    }
+  }
+
+  private static void mergeCommentLists(TIntArrayList commentStarts,
+                                        TIntArrayList commentEnds,
+                                        TIntArrayList commentStartsList,
+                                        TIntArrayList commentEndsList) {
+    if (commentStarts.isEmpty() && commentEnds.isEmpty()) {
+      commentStarts.add(commentStartsList.toNativeArray());
+      commentEnds.add(commentEndsList.toNativeArray());
+      return;
+    }
+
+    ContainerUtil.mergeSortedArrays(commentStarts, commentEnds, commentStartsList, commentEndsList);
+  }
+
+  private static void findComments(final Lexer lexer,
+                                   final CharSequence chars,
+                                   final TextRange range,
+                                   final TokenSet commentTokens,
+                                   final TIntArrayList commentStarts,
+                                   final TIntArrayList commentEnds,
+                                   final IndexPatternBuilder builderForFile) {
+    for (lexer.start(chars); ; lexer.advance()) {
+      IElementType tokenType = lexer.getTokenType();
+      if (tokenType == null) break;
+
+      if (range != null) {
+        if (lexer.getTokenEnd() <= range.getStartOffset()) continue;
+        if (lexer.getTokenStart() >= range.getEndOffset()) break;
+      }
+
+      boolean isComment = commentTokens.contains(tokenType);
+      if (!isComment) {
+        final Language commentLang = tokenType.getLanguage();
+        final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(commentLang);
+        if (parserDefinition != null) {
+          final TokenSet langCommentTokens = parserDefinition.getCommentTokens();
+          isComment = langCommentTokens.contains(tokenType);
+        }
+      }
+
+      if (isComment) {
+        final int startDelta = builderForFile != null ? builderForFile.getCommentStartDelta(lexer.getTokenType()) : 0;
+        final int endDelta = builderForFile != null ? builderForFile.getCommentEndDelta(lexer.getTokenType()) : 0;
+
+        int start = lexer.getTokenStart() + startDelta;
+        int end = lexer.getTokenEnd() - endDelta;
+        assert start <= end : "Invalid comment range: " +
+                              new TextRange(start, end) +
+                              "; lexer token range=" +
+                              new TextRange(lexer.getTokenStart(), lexer.getTokenEnd()) +
+                              "; delta=" +
+                              new TextRange(startDelta, endDelta) +
+                              "; lexer=" +
+                              lexer +
+                              "; builder=" +
+                              builderForFile +
+                              "; chars length:" +
+                              chars.length();
+        assert end <= chars.length() : "Invalid comment end: " +
+                                       new TextRange(start, end) +
+                                       "; lexer token range=" +
+                                       new TextRange(lexer.getTokenStart(), lexer.getTokenEnd()) +
+                                       "; delta=" +
+                                       new TextRange(startDelta, endDelta) +
+                                       "; lexer=" +
+                                       lexer +
+                                       "; builder=" +
+                                       builderForFile +
+                                       "; chars length:" +
+                                       chars.length();
+        commentStarts.add(start);
+        commentEnds.add(end);
+      }
+    }
+  }
+
+  private static boolean collectPatternMatches(IndexPattern indexPattern,
+                                               CharSequence chars,
+                                               int commentStart,
+                                               int commentEnd,
+                                               PsiFile file,
+                                               TextRange range,
+                                               Processor<IndexPatternOccurrence> consumer,
+                                               TIntArrayList matches
+                                               ) {
+    Pattern pattern = indexPattern.getPattern();
+    if (pattern != null) {
+      ProgressManager.checkCanceled();
+
+      CharSequence input = new CharSequenceSubSequence(chars, commentStart, commentEnd);
+      Matcher matcher = pattern.matcher(input);
+      while (true) {
+        //long time1 = System.currentTimeMillis();
+        boolean found = matcher.find();
+        //long time2 = System.currentTimeMillis();
+        //System.out.println("scanned text of length " + (lexer.getTokenEnd() - lexer.getTokenStart() + " in " + (time2 - time1) + " ms"));
+
+        if (!found) break;
+        int start = matcher.start() + commentStart;
+        int end = matcher.end() + commentStart;
+        if (start != end) {
+          if ((range == null || range.getStartOffset() <= start && end <= range.getEndOffset()) && matches.indexOf(start) == -1) {
+            matches.add(start);
+            if (!consumer.process(new IndexPatternOccurrenceImpl(file, start, end, indexPattern))) {
+              return false;
+            }
+          }
+        }
+
+        ProgressManager.checkCanceled();
+      }
+    }
+    return true;
+  }
+}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/LightIndexPatternSearch.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/LightIndexPatternSearch.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/search/LightIndexPatternSearch.java
rename to platform/editor-ui-ex/src/com/intellij/psi/impl/search/LightIndexPatternSearch.java
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/LightIndexPatternSearcher.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/LightIndexPatternSearcher.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/search/LightIndexPatternSearcher.java
rename to platform/editor-ui-ex/src/com/intellij/psi/impl/search/LightIndexPatternSearcher.java
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/PsiTodoSearchHelperImpl.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/PsiTodoSearchHelperImpl.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/search/PsiTodoSearchHelperImpl.java
rename to platform/editor-ui-ex/src/com/intellij/psi/impl/search/PsiTodoSearchHelperImpl.java
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/TodoItemsCreator.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/TodoItemsCreator.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/search/TodoItemsCreator.java
rename to platform/editor-ui-ex/src/com/intellij/psi/impl/search/TodoItemsCreator.java
diff --git a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java
index 8e46a2f..51fb0d6 100644
--- a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java
+++ b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.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.
@@ -22,10 +22,8 @@
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
 import org.picocontainer.*;
-import org.picocontainer.defaults.AssignabilityRegistrationException;
 import org.picocontainer.defaults.CachingComponentAdapter;
 import org.picocontainer.defaults.ConstructorInjectionComponentAdapter;
-import org.picocontainer.defaults.NotConcreteRegistrationException;
 
 /**
  * @author Alexander Kireyev
@@ -33,6 +31,7 @@
  */
 public class ExtensionComponentAdapter implements LoadingOrder.Orderable, AssignableToComponentAdapter {
   public static final ExtensionComponentAdapter[] EMPTY_ARRAY = new ExtensionComponentAdapter[0];
+
   private Object myComponentInstance;
   private final String myImplementationClassName;
   private final Element myExtensionElement;
@@ -65,36 +64,42 @@
   }
 
   @Override
-  public Object getComponentInstance(final PicoContainer container)
-    throws PicoInitializationException,
-           PicoIntrospectionException,
-           AssignabilityRegistrationException,
-           NotConcreteRegistrationException,
-           ProcessCanceledException {
+  public Object getComponentInstance(final PicoContainer container) throws PicoException, ProcessCanceledException {
     if (myComponentInstance == null) {
-      if (Element.class.equals(getComponentImplementation())) {
-        myComponentInstance = myExtensionElement;
-      }
-      else {
-        Object componentInstance = getDelegate().getComponentInstance(container);
-
-        if (myDeserializeInstance) {
-          try {
-            XmlSerializer.deserializeInto(componentInstance, myExtensionElement);
-          }
-          catch (Exception e) {
-            throw new PicoInitializationException(e);
-          }
+      try {
+        if (Element.class.equals(getComponentImplementation())) {
+          myComponentInstance = myExtensionElement;
         }
+        else {
+          Object componentInstance = getDelegate().getComponentInstance(container);
 
-        ExtensionInitializer initializer = (ExtensionInitializer)container.getComponentInstance(ExtensionInitializer.class);
-        if (initializer != null) {
-          initializer.initExtension(componentInstance);
+          if (myDeserializeInstance) {
+            try {
+              XmlSerializer.deserializeInto(componentInstance, myExtensionElement);
+            }
+            catch (Exception e) {
+              throw new PicoInitializationException(e);
+            }
+          }
+
+          ExtensionInitializer initializer = (ExtensionInitializer)container.getComponentInstance(ExtensionInitializer.class);
+          if (initializer != null) {
+            initializer.initExtension(componentInstance);
+          }
+
+          myComponentInstance = componentInstance;
         }
-        myComponentInstance = componentInstance;
       }
+      catch (ProcessCanceledException e) {
+        throw e;
+      }
+      catch (Throwable t) {
+        PluginId pluginId = myPluginDescriptor != null ? myPluginDescriptor.getPluginId() : null;
+        throw new PicoPluginExtensionInitializationException(t.getMessage(), t, pluginId);
+      }
+
       if (myComponentInstance instanceof PluginAware) {
-        PluginAware pluginAware = (PluginAware) myComponentInstance;
+        PluginAware pluginAware = (PluginAware)myComponentInstance;
         pluginAware.setPluginDescriptor(myPluginDescriptor);
       }
     }
@@ -161,7 +166,8 @@
 
   private synchronized ComponentAdapter getDelegate() {
     if (myDelegate == null) {
-      myDelegate = new CachingComponentAdapter(new ConstructorInjectionComponentAdapter(getComponentKey(), loadClass(myImplementationClassName), null, true));
+      Class impl = loadClass(myImplementationClassName);
+      myDelegate = new CachingComponentAdapter(new ConstructorInjectionComponentAdapter(getComponentKey(), impl, null, true));
     }
 
     return myDelegate;
diff --git a/platform/extensions/src/com/intellij/openapi/extensions/impl/PicoPluginExtensionInitializationException.java b/platform/extensions/src/com/intellij/openapi/extensions/impl/PicoPluginExtensionInitializationException.java
new file mode 100644
index 0000000..07ac622
--- /dev/null
+++ b/platform/extensions/src/com/intellij/openapi/extensions/impl/PicoPluginExtensionInitializationException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.openapi.extensions.impl;
+
+import com.intellij.openapi.extensions.PluginId;
+import org.picocontainer.PicoInitializationException;
+
+public class PicoPluginExtensionInitializationException extends PicoInitializationException {
+  private final PluginId myPluginId;
+
+  public PicoPluginExtensionInitializationException(String message, Throwable cause, PluginId id) {
+    super(message, cause);
+    myPluginId = id;
+  }
+
+  public PluginId getPluginId() {
+    return myPluginId;
+  }
+}
diff --git a/platform/extensions/src/com/intellij/openapi/util/KeyedExtensionFactory.java b/platform/extensions/src/com/intellij/openapi/util/KeyedExtensionFactory.java
new file mode 100644
index 0000000..dee255d
--- /dev/null
+++ b/platform/extensions/src/com/intellij/openapi/util/KeyedExtensionFactory.java
@@ -0,0 +1,109 @@
+/*
+ * 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.openapi.util;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.extensions.KeyedFactoryEPBean;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.picocontainer.PicoContainer;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * @author yole
+ */
+public abstract class KeyedExtensionFactory<T, KeyT> {
+  private final Class<T> myInterfaceClass;
+  private final ExtensionPointName<KeyedFactoryEPBean> myEpName;
+  private final PicoContainer myPicoContainer;
+
+  public KeyedExtensionFactory(@NotNull final Class<T> interfaceClass, @NonNls @NotNull final String epName, @NotNull PicoContainer picoContainer) {
+    myInterfaceClass = interfaceClass;
+    myEpName = new ExtensionPointName<KeyedFactoryEPBean>(epName);
+    myPicoContainer = picoContainer;
+  }
+
+  @NotNull
+  public T get() {
+    final KeyedFactoryEPBean[] epBeans = Extensions.getExtensions(myEpName);
+    InvocationHandler handler = new InvocationHandler() {
+      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        //noinspection unchecked
+        KeyT keyArg = (KeyT) args [0];
+        String key = getKey(keyArg);
+        Object result = getByKey(epBeans, key, method, args);
+        if (result == null) {
+          result = getByKey(epBeans, null, method, args);
+        }
+        return result;
+      }
+    };
+    //noinspection unchecked
+    return (T)Proxy.newProxyInstance(myInterfaceClass.getClassLoader(), new Class<?>[] { myInterfaceClass }, handler );
+  }
+
+  public T getByKey(@NotNull KeyT key) {
+    final KeyedFactoryEPBean[] epBeans = Extensions.getExtensions(myEpName);
+    for (KeyedFactoryEPBean epBean : epBeans) {
+      if (Comparing.strEqual(getKey(key), epBean.key)) {
+        try {
+          if (epBean.implementationClass != null) {
+            return (T)epBean.instantiate(epBean.implementationClass, myPicoContainer);
+          }
+        }
+        catch (Exception e) {
+          throw new RuntimeException(e);
+        }
+      }
+    }
+    return null;
+  }
+
+  private T getByKey(final KeyedFactoryEPBean[] epBeans, final String key, final Method method, final Object[] args) {
+    Object result = null;
+    for(KeyedFactoryEPBean epBean: epBeans) {
+      if (Comparing.strEqual(epBean.key, key, true)) {
+        try {
+          if (epBean.implementationClass != null) {
+            result = epBean.instantiate(epBean.implementationClass, myPicoContainer);
+          }
+          else {
+            Object factory = epBean.instantiate(epBean.factoryClass, myPicoContainer);
+            result = method.invoke(factory, args);
+          }
+          if (result != null) {
+            break;
+          }
+        }
+        catch (RuntimeException e) {
+          throw e;
+        }
+        catch (Exception e) {
+          throw new RuntimeException(e);
+        }
+      }
+    }
+    //noinspection ConstantConditions
+    return (T)result;
+  }
+
+  public abstract String getKey(@NotNull KeyT key);
+}
+
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java
index 7b02d53..57e123b 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java
@@ -18,6 +18,7 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.*;
 import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.Alarm;
 import com.intellij.util.containers.ContainerUtilRt;
@@ -197,12 +198,12 @@
     try {
       String compileOutputPath = data.getCompileOutputPath(ExternalSystemSourceType.SOURCE);
       if (compileOutputPath != null) {
-        extension.setCompilerOutputPath(compileOutputPath);
+        extension.setCompilerOutputPath(VfsUtilCore.pathToUrl(compileOutputPath));
       }
 
       String testCompileOutputPath = data.getCompileOutputPath(ExternalSystemSourceType.TEST);
       if (testCompileOutputPath != null) {
-        extension.setCompilerOutputPathForTests(testCompileOutputPath);
+        extension.setCompilerOutputPathForTests(VfsUtilCore.pathToUrl(testCompileOutputPath));
       }
 
       extension.inheritCompilerOutputPath(data.isInheritProjectCompileOutputPath());
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java
index 3d927e9..3b6dc04 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java
@@ -30,6 +30,7 @@
 
 import javax.swing.*;
 import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.MutableTreeNode;
 import javax.swing.tree.TreeNode;
 import java.util.*;
 
@@ -63,11 +64,8 @@
     }
   };
 
-  @NotNull private final TreeNode[] myNodeHolder  = new TreeNode[1];
-  @NotNull private final int[]      myIndexHolder = new int[1];
-
   @NotNull private final ExternalSystemUiAware myUiAware;
-  @NotNull private final ProjectSystemId       myExternalSystemId;
+  @NotNull private final ProjectSystemId myExternalSystemId;
 
   public ExternalSystemTasksTreeModel(@NotNull ProjectSystemId externalSystemId) {
     super(new ExternalSystemNode<String>(new ExternalSystemNodeDescriptor<String>("", "", "", null)));
@@ -82,7 +80,7 @@
   /**
    * Ensures that current model has a top-level node which corresponds to the given external project info holder
    *
-   * @param project  target external project info holder
+   * @param project target external project info holder
    */
   @SuppressWarnings("unchecked")
   @NotNull
@@ -108,17 +106,15 @@
     }
     ExternalProjectPojo element = new ExternalProjectPojo(project.getName(), project.getPath());
     ExternalSystemNodeDescriptor<ExternalProjectPojo> descriptor = descriptor(element, myUiAware.getProjectIcon());
-    myIndexHolder[0] = root.getChildCount();
     ExternalSystemNode<ExternalProjectPojo> result = new ExternalSystemNode<ExternalProjectPojo>(descriptor);
-    root.add(result);
-    nodesWereInserted(root, myIndexHolder);
+    insertNodeInto(result, root);
     return result;
   }
 
   /**
    * Asks current model to remove all nodes which have given data as a {@link ExternalSystemNodeDescriptor#getElement() payload}.
    *
-   * @param payload  target payload
+   * @param payload target payload
    */
   public void pruneNodes(@NotNull Object payload) {
     Deque<ExternalSystemNode<?>> toProcess = new ArrayDeque<ExternalSystemNode<?>>();
@@ -137,8 +133,7 @@
   }
 
   public void ensureSubProjectsStructure(@NotNull ExternalProjectPojo topLevelProject,
-                                         @NotNull Collection<ExternalProjectPojo> subProjects)
-  {
+                                         @NotNull Collection<ExternalProjectPojo> subProjects) {
     ExternalSystemNode<ExternalProjectPojo> topLevelProjectNode = ensureProjectNodeExists(topLevelProject);
     Map<String/*config path*/, ExternalProjectPojo> toAdd = ContainerUtilRt.newHashMap();
     for (ExternalProjectPojo subProject : subProjects) {
@@ -154,12 +149,8 @@
         taskWeights.put(childElement, subProjects.size() + i);
         continue;
       }
-      
       if (toAdd.remove(((ExternalProjectPojo)childElement).getPath()) == null) {
-        topLevelProjectNode.remove(child);
-        myIndexHolder[0] = i;
-        myNodeHolder[0] = child;
-        nodesWereRemoved(topLevelProjectNode, myIndexHolder, myNodeHolder);
+        removeNodeFromParent(child);
         //noinspection AssignmentToForLoopParameter
         i--;
       }
@@ -168,13 +159,10 @@
       for (Map.Entry<String, ExternalProjectPojo> entry : toAdd.entrySet()) {
         ExternalProjectPojo
           element = new ExternalProjectPojo(entry.getValue().getName(), entry.getValue().getPath());
-        topLevelProjectNode.add(new ExternalSystemNode<ExternalProjectPojo>(descriptor(element, myUiAware.getProjectIcon())));
-        myIndexHolder[0] = topLevelProjectNode.getChildCount() - 1;
-        nodesWereInserted(topLevelProjectNode, myIndexHolder);
+        insertNodeInto(new ExternalSystemNode<ExternalProjectPojo>(descriptor(element, myUiAware.getProjectIcon())),
+                       topLevelProjectNode);
       }
     }
-
-    ExternalSystemUiUtil.sort(topLevelProjectNode, this, NODE_COMPARATOR);
   }
 
   public void ensureTasks(@NotNull String externalProjectConfigPath, @NotNull Collection<ExternalTaskPojo> tasks) {
@@ -198,10 +186,7 @@
       Object element = childNode.getDescriptor().getElement();
       if (element instanceof ExternalTaskExecutionInfo) {
         if (!toAdd.remove(element)) {
-          moduleNode.remove(childNode);
-          myIndexHolder[0] = i;
-          myNodeHolder[0] = childNode;
-          nodesWereRemoved(moduleNode, myIndexHolder, myNodeHolder);
+          removeNodeFromParent(childNode);
           //noinspection AssignmentToForLoopParameter
           i--;
         }
@@ -210,12 +195,11 @@
 
     if (!toAdd.isEmpty()) {
       for (ExternalTaskExecutionInfo taskInfo : toAdd) {
-        moduleNode.add(new ExternalSystemNode<ExternalTaskExecutionInfo>(descriptor(taskInfo, taskInfo.getDescription(), myUiAware.getTaskIcon())));
-        myIndexHolder[0] = moduleNode.getChildCount() - 1;
-        nodesWereInserted(moduleNode, myIndexHolder);
+        insertNodeInto(
+          new ExternalSystemNode<ExternalTaskExecutionInfo>(descriptor(taskInfo, taskInfo.getDescription(), myUiAware.getTaskIcon())),
+          moduleNode);
       }
     }
-    ExternalSystemUiUtil.sort(moduleNode, this, NODE_COMPARATOR);
   }
 
   @NotNull
@@ -241,8 +225,7 @@
         ExternalSystemNode<?> grandChild = child.getChildAt(j);
         Object grandChildElement = grandChild.getDescriptor().getElement();
         if (grandChildElement instanceof ExternalProjectPojo
-            && ((ExternalProjectPojo)grandChildElement).getPath().equals(configPath))
-        {
+            && ((ExternalProjectPojo)grandChildElement).getPath().equals(configPath)) {
           return (ExternalSystemNode<ExternalProjectPojo>)grandChild;
         }
       }
@@ -259,9 +242,40 @@
   private static <T> ExternalSystemNodeDescriptor<T> descriptor(@NotNull T element, @NotNull String description, @Nullable Icon icon) {
     return new ExternalSystemNodeDescriptor<T>(element, element.toString(), description, icon);
   }
-  
+
   @NotNull
   public ExternalSystemNode<?> getRoot() {
     return (ExternalSystemNode<?>)super.getRoot();
   }
+
+  public void insertNodeInto(MutableTreeNode child, MutableTreeNode parent) {
+    int index = findIndexFor(child, parent);
+    super.insertNodeInto(child, parent, index);
+  }
+
+  public void insertNodeInto(MutableTreeNode child, MutableTreeNode parent, int i) {
+    insertNodeInto(child, parent);
+  }
+
+  private static int findIndexFor(MutableTreeNode child, MutableTreeNode parent) {
+    int childCount = parent.getChildCount();
+    if (childCount == 0) {
+      return 0;
+    }
+    if (childCount == 1) {
+      return NODE_COMPARATOR.compare(child, parent.getChildAt(0)) <= 0 ? 0 : 1;
+    }
+    return findIndexFor(child, parent, 0, childCount - 1);
+  }
+
+  private static int findIndexFor(MutableTreeNode child, MutableTreeNode parent, int i1, int i2) {
+    if (i1 == i2) {
+      return NODE_COMPARATOR.compare(child, parent.getChildAt(i1)) <= 0 ? i1 : i1 + 1;
+    }
+    int half = (i1 + i2) / 2;
+    if (NODE_COMPARATOR.compare(child, parent.getChildAt(half)) <= 0) {
+      return findIndexFor(child, parent, i1, half);
+    }
+    return findIndexFor(child, parent, half + 1, i2);
+  }
 }
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java
index 06ae2a1..d987be2 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java
@@ -105,32 +105,6 @@
     component.add(Box.createVerticalGlue(), new GridBag().weightx(1).weighty(1).fillCell().coverLine());
   }
 
-  public static void sort(@NotNull DefaultMutableTreeNode parent,
-                          @NotNull DefaultTreeModel model,
-                          @NotNull Comparator<TreeNode> comparator)
-  {
-    List<MutableTreeNode> children = ContainerUtilRt.newArrayList();
-    THashMap<TreeNode, Integer> initialOrder = ContainerUtil.newIdentityTroveMap();
-    for (int i = 0; i < parent.getChildCount(); i++) {
-      MutableTreeNode child = (MutableTreeNode)parent.getChildAt(i);
-      children.add(child);
-      initialOrder.put(child, i);
-    }
-    Collections.sort(children, comparator);
-    parent.removeAllChildren();
-
-    for (MutableTreeNode child : children) {
-      parent.add(child);
-    }
-    for (int i = 0; i < children.size(); i++) {
-      MutableTreeNode child = children.get(i);
-      Integer initialIndex = initialOrder.get(child);
-      if (initialIndex != i) {
-        model.nodeChanged(child);
-      }
-    }
-  }
-
   /**
    * Applies data from the given settings object to the given model.
    * 
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java
index 3750bff..9e75f7f 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java
@@ -47,8 +47,8 @@
 import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
 import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
 import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.PerformInBackgroundOption;
 import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.progress.Task;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
@@ -461,21 +461,21 @@
       public void run() {
         if (modal) {
           String title = ExternalSystemBundle.message("progress.import.text", projectName, externalSystemId.getReadableName());
-          ProgressManager.getInstance().run(new Task.Modal(project, title, true) {
+          new Task.Backgroundable(project, title, true, PerformInBackgroundOption.DEAF) {
             @Override
             public void run(@NotNull ProgressIndicator indicator) {
               refreshProjectStructureTask.execute(indicator);
             }
-          });
+          }.queue();
         }
         else {
           String title = ExternalSystemBundle.message("progress.refresh.text", projectName, externalSystemId.getReadableName());
-          ProgressManager.getInstance().run(new Task.Backgroundable(project, title) {
+          new Task.Backgroundable(project, title) {
             @Override
             public void run(@NotNull ProgressIndicator indicator) {
               refreshProjectStructureTask.execute(indicator);
             }
-          });
+          }.queue();
         }
       }
     });
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/AbstractCustomLexer.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/AbstractCustomLexer.java
index 92e75ad..263baa2 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/AbstractCustomLexer.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/AbstractCustomLexer.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.
@@ -22,6 +22,7 @@
 import com.intellij.psi.CustomHighlighterTokenType;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
 
@@ -40,7 +41,8 @@
     myTokenParsers = tokenParsers.toArray(new TokenParser[tokenParsers.size()]);
   }
 
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  @Override
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     myBuffer = buffer;
     myStartOffset = startOffset;
     myEndOffset = endOffset;
@@ -52,22 +54,27 @@
     advance();
   }
 
+  @Override
   public int getState() {
     return 0;
   }
 
+  @Override
   public IElementType getTokenType() {
     return myCurrentToken.getType();
   }
 
+  @Override
   public int getTokenStart() {
     return myCurrentToken.getStart();
   }
 
+  @Override
   public int getTokenEnd() {
     return myCurrentToken.getEnd();
   }
 
+  @Override
   public void advance() {
     if (myPosition >= myEndOffset) {
       myCurrentToken.updateData(myPosition, myPosition, null);
@@ -95,10 +102,13 @@
     myCurrentToken.updateData(myPosition, myPosition + 1, CustomHighlighterTokenType.CHARACTER);
   }
 
+  @Override
+  @NotNull
   public CharSequence getBufferSequence() {
     return myBuffer;
   }
 
+  @Override
   public int getBufferEnd() {
     return myEndOffset;
   }
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/SyntaxTable.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/SyntaxTable.java
index 7697451..d6e23b6 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/SyntaxTable.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/SyntaxTable.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.
@@ -70,6 +70,7 @@
     return parser;
   }
 
+  @Override
   protected Object clone() throws CloneNotSupportedException {
     SyntaxTable cl = (SyntaxTable) super.clone();
     cl.myKeywords1 = new TreeSet<String>(myKeywords1);
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java
index af3b3d4..e258e22 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.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.
@@ -54,6 +54,7 @@
                          new BraceTokenParser(">", CustomHighlighterTokenType.R_ANGLE));
   }
 
+  @Override
   protected int getTokenEnd(int position) {
     return position;
   }
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.java
index 383fe63..5d41176 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.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.
@@ -27,6 +27,7 @@
     super(prefix, CustomHighlighterTokenType.NUMBER);
   }
 
+  @Override
   protected int getTokenEnd(int position) {
     for (; position < myEndOffset; position++) {
       if (!StringUtil.isHexDigit(myBuffer.charAt(position))) break;
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.java
index 6f44365..57b29ae8 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.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.
@@ -26,6 +26,7 @@
   public IdentifierParser() {
   }
 
+  @Override
   public boolean hasToken(int position) {
     if (!Character.isJavaIdentifierStart(myBuffer.charAt(position))) return false;
     final int start = position;
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.java
index 0f358da..c5fc32d 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.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.
@@ -39,6 +39,7 @@
     return super.hasToken(position);
   }
 
+  @Override
   protected int getTokenEnd(int position) {
     for (; position < myEndOffset; position++) {
       if (myBuffer.charAt(position) == '\n') break;
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.java
index 018ea20..e878738 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.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.
@@ -29,6 +29,7 @@
     myEndDelimiter = endDelimiter.toCharArray();
   }
 
+  @Override
   protected int getTokenEnd(int position) {
     for (; position < myEndOffset; position++) {
       // todo: implement KMP
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/NumberParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/NumberParser.java
index 2fa17c0..928da95 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/NumberParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/NumberParser.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.
@@ -35,6 +35,7 @@
     }
   }
 
+  @Override
   public boolean hasToken(int position) {
     final int start = position;
     final char startChar = myBuffer.charAt(start);
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.java
index c80015b..7b03d4b 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.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.
@@ -30,6 +30,7 @@
     myPrefix = prefix.toCharArray();
   }
 
+  @Override
   public boolean hasToken(int position) {
     final int start = position;
     int i;
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.java
index 7bfa566..9e08795 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.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.
@@ -34,6 +34,7 @@
     myAllowEscapes = allowEscapes;
   }
 
+  @Override
   protected int getTokenEnd(int position) {
     boolean escaped = false;
     for(; position < myEndOffset; position++) {
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.java
index 2da63cf..e84534d 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.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.
@@ -24,6 +24,7 @@
  */
 public class WhitespaceParser extends TokenParser {
 
+  @Override
   public boolean hasToken(int position) {
     if (!Character.isWhitespace(myBuffer.charAt(position))) return false;
     int start = position;
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/TodoCacheManager.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/TodoCacheManager.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/cache/TodoCacheManager.java
rename to platform/indexing-impl/src/com/intellij/psi/impl/cache/TodoCacheManager.java
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/BaseFilterLexer.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/BaseFilterLexer.java
index d297a9a..cc9dddf 100644
--- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/BaseFilterLexer.java
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/BaseFilterLexer.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.
@@ -22,6 +22,8 @@
 import com.intellij.psi.search.IndexPattern;
 import com.intellij.psi.search.UsageSearchContext;
 import com.intellij.util.text.CharArrayUtil;
+import gnu.trove.TIntArrayList;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.regex.Matcher;
@@ -32,7 +34,7 @@
 
   private int myTodoScannedBound = 0;
   private int myOccurenceMask;
-  private TodoScanningData[] myTodoScanningData;
+  private TodoScanningState myTodoScanningState;
   private CharSequence myCachedBufferSequence;
   private char[] myCachedArraySequence;
   
@@ -49,49 +51,56 @@
     if (start >= end) return; // this prevents scanning of the same comment twice
 
     CharSequence input = myCachedBufferSequence.subSequence(start, end);
-    myTodoScanningData = advanceTodoItemsCount(input, myOccurrenceConsumer, myTodoScanningData);
+    myTodoScanningState = advanceTodoItemsCount(input, myOccurrenceConsumer, myTodoScanningState);
 
     myTodoScannedBound = end;
   }
 
-  public static class TodoScanningData {
-    final IndexPattern pattern;
-    final Matcher matcher;
+  public static class TodoScanningState {
+    final IndexPattern[] myPatterns;
+    final Matcher[] myMatchers;
+    TIntArrayList myOccurences;
 
-    public TodoScanningData(IndexPattern pattern, Matcher matcher) {
-      this.matcher = matcher;
-      this.pattern = pattern;
+    public TodoScanningState(IndexPattern[] patterns, Matcher[] matchers) {
+      myPatterns = patterns;
+      myMatchers = matchers;
+      myOccurences = new TIntArrayList(1);
     }
   }
 
-  public static TodoScanningData[] advanceTodoItemsCount(final CharSequence input, final OccurrenceConsumer consumer, TodoScanningData[] todoScanningData) {
-    if (todoScanningData == null) {
+  public static TodoScanningState advanceTodoItemsCount(final CharSequence input, final OccurrenceConsumer consumer, TodoScanningState todoScanningState) {
+    if (todoScanningState == null) {
       IndexPattern[] patterns = IndexPatternUtil.getIndexPatterns();
-      todoScanningData = new TodoScanningData[patterns.length];
+
+      Matcher[] matchers = new Matcher[patterns.length];
+      todoScanningState = new TodoScanningState(patterns, matchers);
 
       for (int i = 0; i < patterns.length; ++i) {
-        IndexPattern indexPattern = patterns[i];
-        Pattern pattern = indexPattern.getPattern();
+        Pattern pattern = patterns[i].getPattern();
 
         if (pattern != null) {
-          todoScanningData [i] = new TodoScanningData(indexPattern, pattern.matcher(""));
+          matchers[i] = pattern.matcher("");
         }
       }
+    } else {
+      todoScanningState.myOccurences.resetQuick();
     }
 
-    for (TodoScanningData data:todoScanningData) {
-      if (data == null) continue;
-      Matcher matcher = data.matcher;
+    for (int i = todoScanningState.myMatchers.length - 1; i >= 0; --i) {
+      Matcher matcher = todoScanningState.myMatchers[i];
+      if (matcher == null) continue;
       matcher.reset(input);
 
       while (matcher.find()) {
-        if (matcher.start() != matcher.end()) {
-          consumer.incTodoOccurrence(data.pattern);
+        int start = matcher.start();
+        if (start != matcher.end() && todoScanningState.myOccurences.indexOf(start) == -1) {
+          consumer.incTodoOccurrence(todoScanningState.myPatterns[i]);
+          todoScanningState.myOccurences.add(start);
         }
       }
     }
 
-    return todoScanningData;
+    return todoScanningState;
   }
 
   @Override
@@ -140,7 +149,7 @@
   }
 
   @Override
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     super.start(buffer, startOffset, endOffset, initialState);
     myCachedBufferSequence = getBufferSequence();
     myCachedArraySequence = CharArrayUtil.fromSequenceWithoutCopying(myCachedBufferSequence);
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java
index 7886102..59f0a6e 100644
--- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java
@@ -22,6 +22,7 @@
 import com.intellij.lang.findUsages.FindUsagesProvider;
 import com.intellij.lang.findUsages.LanguageFindUsages;
 import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.InternalFileType;
 import com.intellij.openapi.fileTypes.LanguageFileType;
 import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
 import com.intellij.psi.CustomHighlighterTokenType;
@@ -65,15 +66,15 @@
     }
   }
 
-  private static final HashMap<FileType, FileTypeIdIndexer> ourIdIndexers = new HashMap<FileType, FileTypeIdIndexer>();
+  private static final Map<FileType, FileTypeIdIndexer> ourIdIndexers = new HashMap<FileType, FileTypeIdIndexer>();
 
   @Deprecated
-  public static void registerIdIndexer(FileType fileType, FileTypeIdIndexer indexer) {
+  public static void registerIdIndexer(@NotNull FileType fileType, FileTypeIdIndexer indexer) {
     ourIdIndexers.put(fileType, indexer);
   }
 
-  public static boolean isIdIndexerRegistered(FileType fileType) {
-    return ourIdIndexers.containsKey(fileType) || IdIndexers.INSTANCE.forFileType(fileType) != null;
+  public static boolean isIdIndexerRegistered(@NotNull FileType fileType) {
+    return ourIdIndexers.containsKey(fileType) || IdIndexers.INSTANCE.forFileType(fileType) != null || fileType instanceof InternalFileType;
   }
 
 
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndexers.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndexers.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndexers.java
rename to platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndexers.java
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/IndexPatternBuilder.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/IndexPatternBuilder.java
new file mode 100644
index 0000000..167ae038
--- /dev/null
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/IndexPatternBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.psi.impl.search;
+
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author yole
+ */
+public interface IndexPatternBuilder {
+  ExtensionPointName<IndexPatternBuilder> EP_NAME = ExtensionPointName.create("com.intellij.indexPatternBuilder");
+
+  @Nullable
+  Lexer getIndexingLexer(@NotNull PsiFile file);
+  @Nullable
+  TokenSet getCommentTokenSet(@NotNull PsiFile file);
+  int getCommentStartDelta(IElementType tokenType);
+  int getCommentEndDelta(IElementType tokenType);
+}
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/TodoItemImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/TodoItemImpl.java
new file mode 100644
index 0000000..07a6bf2
--- /dev/null
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/TodoItemImpl.java
@@ -0,0 +1,70 @@
+/*
+ * 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.psi.impl.search;
+
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.search.TodoItem;
+import com.intellij.psi.search.TodoPattern;
+import org.jetbrains.annotations.NotNull;
+
+public class TodoItemImpl implements TodoItem {
+  private final PsiFile myFile;
+  private final int myStartOffset;
+  private final int myEndOffset;
+  private final TodoPattern myPattern;
+
+  public TodoItemImpl(@NotNull PsiFile file, int startOffset, int endOffset, @NotNull TodoPattern pattern) {
+    myFile = file;
+    myStartOffset = startOffset;
+    myEndOffset = endOffset;
+    myPattern = pattern;
+  }
+
+  @NotNull
+  @Override
+  public PsiFile getFile() {
+    return myFile;
+  }
+
+  @NotNull
+  @Override
+  public TextRange getTextRange() {
+    return new TextRange(myStartOffset, myEndOffset);
+  }
+
+  @NotNull
+  @Override
+  public TodoPattern getPattern() {
+    return myPattern;
+  }
+
+  public int hashCode(){
+    return myFile.hashCode()+myStartOffset+myEndOffset+myPattern.hashCode();
+  }
+
+  public boolean equals(Object obj){
+    if(!(obj instanceof TodoItemImpl)){
+      return false;
+    }
+    TodoItemImpl todoItem=(TodoItemImpl)obj;
+    return myFile.equals(todoItem.myFile) &&
+           myStartOffset == todoItem.myStartOffset &&
+           myEndOffset == todoItem.myEndOffset &&
+           myPattern.equals(todoItem.myPattern);
+  }
+}
diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java
index ab7b43c..df14ef0 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java
@@ -29,7 +29,9 @@
    * @deprecated not used anymore, only the user controls whether the lookup will be focused
    */
   @NotNull
-  public abstract ThreeState shouldFocusLookup(@NotNull CompletionParameters parameters);
+  public ThreeState shouldFocusLookup(@NotNull CompletionParameters parameters) { 
+    return ThreeState.UNSURE; 
+  }
 
   /**
    * This method is invoked first when a completion autopopup is scheduled. Extensions are able to cancel this completion process based on location.
diff --git a/platform/lang-api/src/com/intellij/facet/FacetTypeRegistry.java b/platform/lang-api/src/com/intellij/facet/FacetTypeRegistry.java
index 7884b7b..8e2ce49 100644
--- a/platform/lang-api/src/com/intellij/facet/FacetTypeRegistry.java
+++ b/platform/lang-api/src/com/intellij/facet/FacetTypeRegistry.java
@@ -17,6 +17,7 @@
 package com.intellij.facet;
 
 import com.intellij.openapi.components.ServiceManager;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -38,14 +39,18 @@
    */
   public abstract void unregisterFacetType(FacetType facetType);
 
+  @NotNull
   public abstract FacetTypeId[] getFacetTypeIds();
 
+  @NotNull
   public abstract FacetType[] getFacetTypes();
 
+  @NotNull
   public abstract FacetType[] getSortedFacetTypes();
 
   @Nullable
   public abstract FacetType findFacetType(String id);
 
-  public abstract <F extends Facet<C>, C extends FacetConfiguration> FacetType<F, C> findFacetType(FacetTypeId<F> typeId);
+  @NotNull
+  public abstract <F extends Facet<C>, C extends FacetConfiguration> FacetType<F, C> findFacetType(@NotNull FacetTypeId<F> typeId);
 }
diff --git a/platform/lang-api/src/com/intellij/facet/ui/FacetBasedFrameworkSupportProvider.java b/platform/lang-api/src/com/intellij/facet/ui/FacetBasedFrameworkSupportProvider.java
index 89d33e1..742f8d9 100644
--- a/platform/lang-api/src/com/intellij/facet/ui/FacetBasedFrameworkSupportProvider.java
+++ b/platform/lang-api/src/com/intellij/facet/ui/FacetBasedFrameworkSupportProvider.java
@@ -66,9 +66,7 @@
    * @see #getPrecedingFrameworkProviderIds()
    */
   public static String getProviderId(final FacetTypeId<?> typeId) {
-    FacetType<?,?> type = FacetTypeRegistry.getInstance().findFacetType(typeId);
-    LOG.assertTrue(type != null, typeId);
-    return getProviderId(type);
+    return getProviderId(FacetTypeRegistry.getInstance().findFacetType(typeId));
   }
 
   @Override
@@ -77,8 +75,7 @@
     FacetTypeId<?> typeId = myFacetType.getUnderlyingFacetType();
     if (typeId == null) return null;
 
-    FacetType<?,?> type = FacetTypeRegistry.getInstance().findFacetType(typeId);
-    return type != null ? getProviderId(type) : null;
+    return getProviderId(FacetTypeRegistry.getInstance().findFacetType(typeId));
 
   }
 
diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java
index 665b593..26fd925 100644
--- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java
+++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java
@@ -33,6 +33,11 @@
 
   public abstract ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider);
 
+  /** @deprecated Will be removed soon */
+  public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider, boolean forNewWizard) {
+    return forNewWizard ? ModuleWizardStep.EMPTY_ARRAY : createWizardSteps(wizardContext, modulesProvider);
+  }
+
   @Nullable
   public ModuleWizardStep modifySettingsStep(@NotNull SettingsStep settingsStep) {
     return null;
diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
index f14cd7a..45f25cd 100644
--- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
+++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
@@ -17,6 +17,7 @@
 
 import com.intellij.ide.IdeBundle;
 import com.intellij.ide.highlighter.ModuleFileType;
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.extensions.ExtensionPointName;
@@ -57,7 +58,6 @@
   private String myContentEntryPath;
   private final Set<ModuleConfigurationUpdater> myUpdaters = new HashSet<ModuleConfigurationUpdater>();
   private final EventDispatcher<ModuleBuilderListener> myDispatcher = EventDispatcher.create(ModuleBuilderListener.class);
-  private Map<String, Boolean> myAvailableFrameworks;
 
   @NotNull
   public static List<ModuleBuilder> getAllBuilders() {
@@ -140,6 +140,11 @@
     }
   }
 
+  @Nullable
+  public JComponent getCustomOptionsPanel(Disposable parentDisposable) {
+    return null;
+  }
+
   protected List<WizardInputField> getAdditionalFields() {
     return Collections.emptyList();
   }
@@ -362,10 +367,14 @@
     return myJdk;
   }
 
+  private Map<String, Boolean> myAvailableFrameworks;
+
+  /** @deprecated will be removed */
   public Map<String, Boolean> getAvailableFrameworks() {
     return myAvailableFrameworks;
   }
 
+  /** @deprecated will be removed */
   public void setAvailableFrameworks(Map<String, Boolean> availableFrameworks) {
     myAvailableFrameworks = availableFrameworks;
   }
diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java
index 314607cb..b6893cf 100644
--- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java
+++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java
@@ -17,6 +17,7 @@
 
 import com.intellij.ide.util.BrowseFilesListener;
 import com.intellij.ide.wizard.StepAdapter;
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.util.IconLoader;
 import com.intellij.ui.FieldPanel;
@@ -26,15 +27,22 @@
 import javax.swing.*;
 import java.awt.*;
 
-public abstract class ModuleWizardStep extends StepAdapter {
+public abstract class ModuleWizardStep extends StepAdapter implements Disposable {
 
   protected static final Icon ICON = IconLoader.getIcon("/addmodulewizard.png");
   public static final ModuleWizardStep[] EMPTY_ARRAY = new ModuleWizardStep[0];
 
   @Override
   public abstract JComponent getComponent();
+
+  /** Commits data from UI into ModuleBuilder and WizardContext */
   public abstract void updateDataModel();
 
+  /** Update UI from ModuleBuilder and WizardContext */
+  public void updateStep() {
+    // empty by default
+  }
+
   @NonNls public String getHelpId() {
     return null;
   }
@@ -47,10 +55,6 @@
     // empty by default
   }
 
-  public void updateStep() {
-    // empty by default
-  }
-
   @Override
   public Icon getIcon() {
     return ICON;
@@ -67,6 +71,11 @@
   public void disposeUIResources() {
   }
 
+  @Override
+  public void dispose() {
+    disposeUIResources();
+  }
+
   public static FieldPanel createFieldPanel(final JTextField field, final String labelText, final BrowseFilesListener browseButtonActionListener) {
     final FieldPanel fieldPanel = new FieldPanel(field, labelText, null, browseButtonActionListener, null);
     fieldPanel.getFieldLabel().setFont(UIUtil.getLabelFont().deriveFont(Font.BOLD));
diff --git a/platform/lang-api/src/com/intellij/lang/annotation/ExternalAnnotator.java b/platform/lang-api/src/com/intellij/lang/annotation/ExternalAnnotator.java
index 46d641e..9f8644c 100644
--- a/platform/lang-api/src/com/intellij/lang/annotation/ExternalAnnotator.java
+++ b/platform/lang-api/src/com/intellij/lang/annotation/ExternalAnnotator.java
@@ -30,24 +30,6 @@
  */
 public abstract class ExternalAnnotator<InitialInfoType, AnnotationResultType> {
   /**
-   * @deprecated use {@link ExternalAnnotator#collectInformation(PsiFile)} instead
-   */
-  @Nullable
-  @Deprecated
-  public InitialInfoType collectionInformation(@NotNull PsiFile file) {
-    return null;
-  }
-
-  /**
-   * @deprecated use {@link ExternalAnnotator#collectInformation(PsiFile, Editor, boolean)} instead
-   */
-  @Nullable
-  @Deprecated()
-  public InitialInfoType collectInformation(@NotNull PsiFile file, @NotNull Editor editor) {
-    return collectInformation(file);
-  }
-
-  /**
    * Collects initial information required for annotation. Expected to run within read action.
    * See {@link ExternalAnnotator#collectInformation(PsiFile, Editor, boolean)} for details.
    *
@@ -56,7 +38,7 @@
    */
   @Nullable
   public InitialInfoType collectInformation(@NotNull PsiFile file) {
-    return collectionInformation(file);
+    return null;
   }
 
   /**
@@ -70,7 +52,7 @@
    */
   @Nullable
   public InitialInfoType collectInformation(@NotNull PsiFile file, @NotNull Editor editor, boolean hasErrors) {
-    return hasErrors ? null : collectInformation(file, editor);
+    return hasErrors ? null : collectInformation(file);
   }
 
   /**
@@ -92,15 +74,4 @@
    */
   public void apply(@NotNull PsiFile file, AnnotationResultType annotationResult, @NotNull AnnotationHolder holder) {
   }
-
-  /**
-   * Annotates the specified file.
-   *
-   * @param file   the file to annotate.
-   * @param holder the container which receives annotations created by the plugin.
-   */
-  // todo: adapt existing annotators to a new API
-  @Deprecated
-  public void annotate(PsiFile file, AnnotationHolder holder) {
-  }
 }
diff --git a/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java b/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java
index 74937ac..d728aff 100644
--- a/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java
+++ b/platform/lang-api/src/com/intellij/lexer/CompositeLexer.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.
@@ -16,6 +16,7 @@
 package com.intellij.lexer;
 
 import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
 
 public abstract class CompositeLexer extends LexerBase {
   private final Lexer myLexer1;
@@ -30,12 +31,13 @@
   protected abstract IElementType getCompositeTokenType(IElementType type1, IElementType type2);
 
   @Override
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     myLexer1.start(buffer, startOffset, endOffset, (initialState >> 16) & 0xFFFF);
     myLexer2.start(buffer, startOffset, endOffset, initialState & 0xFFFF);
     myCurOffset = startOffset;
   }
 
+  @NotNull
   @Override
   public CharSequence getBufferSequence() {
     return myLexer1.getBufferSequence();
diff --git a/platform/lang-api/src/com/intellij/lexer/FilterLexer.java b/platform/lang-api/src/com/intellij/lexer/FilterLexer.java
index 328a8cf..6f03469 100644
--- a/platform/lang-api/src/com/intellij/lexer/FilterLexer.java
+++ b/platform/lang-api/src/com/intellij/lexer/FilterLexer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 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.
@@ -17,6 +17,7 @@
 
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
 
 public class FilterLexer extends DelegateLexer {
   private final Filter myFilter;
@@ -55,7 +56,7 @@
   }
 
   @Override
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     super.start(buffer, startOffset, endOffset, initialState);
     myPrevTokenEnd = -1;
     locateToken();
@@ -73,13 +74,14 @@
     return myPrevTokenEnd;
   }
 
+  @NotNull
   @Override
   public LexerPosition getCurrentPosition() {
     return getDelegate().getCurrentPosition();    //To change body of overridden methods use File | Settings | File Templates.
   }
 
   @Override
-  public void restore(LexerPosition position) {
+  public void restore(@NotNull LexerPosition position) {
     getDelegate().restore(position);
     myPrevTokenEnd = -1;
   }
diff --git a/platform/lang-api/src/com/intellij/lexer/StoppableLexerAdapter.java b/platform/lang-api/src/com/intellij/lexer/StoppableLexerAdapter.java
index f8fec84..3763297 100644
--- a/platform/lang-api/src/com/intellij/lexer/StoppableLexerAdapter.java
+++ b/platform/lang-api/src/com/intellij/lexer/StoppableLexerAdapter.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.
@@ -20,6 +20,7 @@
 package com.intellij.lexer;
 
 import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
 
 public class StoppableLexerAdapter extends DelegateLexer {
 
@@ -61,13 +62,14 @@
     return myStopped ? null : super.getTokenType();
   }
 
+  @NotNull
   @Override
   public LexerPosition getCurrentPosition() {
     return getDelegate().getCurrentPosition();
   }
 
   @Override
-  public void restore(LexerPosition position) {
+  public void restore(@NotNull LexerPosition position) {
     getDelegate().restore(position);
   }
 
diff --git a/platform/lang-api/src/com/intellij/lexer/StringLiteralLexer.java b/platform/lang-api/src/com/intellij/lexer/StringLiteralLexer.java
index 978c01b..a163e5b 100644
--- a/platform/lang-api/src/com/intellij/lexer/StringLiteralLexer.java
+++ b/platform/lang-api/src/com/intellij/lexer/StringLiteralLexer.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,6 +19,7 @@
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.StringEscapesTokenTypes;
 import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * @author max
@@ -74,7 +75,7 @@
   }
 
   @Override
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     myBuffer = buffer;
     myStart = startOffset;
     if (myQuoteChar == NO_QUOTE_CHAR) {
@@ -249,6 +250,7 @@
     myEnd = locateToken(myStart);
   }
 
+  @NotNull
   @Override
   public CharSequence getBufferSequence() {
     return myBuffer;
diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java b/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
index 14c0e46..8152efd 100644
--- a/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
+++ b/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
@@ -20,6 +20,7 @@
  */
 package com.intellij.openapi.roots.ui;
 
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.projectRoots.ui.SdkPathEditor;
 import com.intellij.openapi.roots.OrderRootType;
@@ -29,7 +30,9 @@
 import javax.swing.*;
 
 public interface OrderRootTypeUIFactory {
-  KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType> FACTORY = new KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType>(OrderRootTypeUIFactory.class, "com.intellij.OrderRootTypeUI") {
+  KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType> FACTORY = new KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType>(OrderRootTypeUIFactory.class, "com.intellij.OrderRootTypeUI",
+                                                                                                                                          ApplicationManager
+                                                                                                                                            .getApplication().getPicoContainer()) {
     @Override
     public String getKey(@NotNull final OrderRootType key) {
       return key.name();
diff --git a/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java b/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java
index 69193ae..c3685b03 100644
--- a/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java
+++ b/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java
@@ -37,10 +37,6 @@
   public void updateDetailView(DetailView panel) {
     if (panel == null) return;
 
-    if (equals(panel.getCurrentItem())) {
-      return;
-    }
-
     doUpdateDetailView(panel, panel.hasEditorOnly());
 
     panel.setCurrentItem(this);
diff --git a/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.form b/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.form
new file mode 100644
index 0000000..d0b545c
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.form
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.application.options.ImportSchemeChooserDialog">
+  <grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="10" left="10" bottom="10" right="10"/>
+    <constraints>
+      <xy x="48" y="54" width="436" height="321"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <grid id="50b89" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="9d822" class="com.intellij.ui.components.JBLabel">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text value="Import to:"/>
+            </properties>
+          </component>
+          <component id="172e4" class="javax.swing.JTextField" binding="myTargetNameField">
+            <constraints>
+              <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                <preferred-size width="150" height="-1"/>
+              </grid>
+            </constraints>
+            <properties/>
+          </component>
+          <component id="1a0d0" class="javax.swing.JCheckBox" binding="myUseCurrentScheme">
+            <constraints>
+              <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text value="Current scheme"/>
+            </properties>
+          </component>
+        </children>
+      </grid>
+      <scrollpane id="41119" class="com.intellij.ui.components.JBScrollPane">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="f1a29" class="com.intellij.ui.components.JBList" binding="mySchemeList">
+            <constraints/>
+            <properties/>
+          </component>
+        </children>
+      </scrollpane>
+      <vspacer id="5cb42">
+        <constraints>
+          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+    </children>
+  </grid>
+</form>
diff --git a/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.java b/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.java
new file mode 100644
index 0000000..78ed30a
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.java
@@ -0,0 +1,100 @@
+package com.intellij.application.options;
+
+import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.options.Scheme;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.ui.components.JBList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class ImportSchemeChooserDialog extends DialogWrapper {
+  private JPanel contentPane;
+  private JBList mySchemeList;
+  private JTextField myTargetNameField;
+  private JCheckBox myUseCurrentScheme;
+  private String mySelectedName;
+  private final static String UNNAMED_SCHEME_ITEM = "<" + ApplicationBundle.message("code.style.scheme.import.unnamed") + ">";
+  private final List<String> myNames = new ArrayList<String>();
+
+  public ImportSchemeChooserDialog(@NotNull Component parent,
+                                   String[] schemeNames,
+                                   final @Nullable String currScheme) {
+    super(parent, false);
+    if (schemeNames.length > 0) {
+      myNames.addAll(Arrays.asList(schemeNames));
+    }
+    else {
+      myNames.add(UNNAMED_SCHEME_ITEM);
+    }
+    mySchemeList.setModel(new DefaultListModel() {
+      @Override
+      public int getSize() {
+        return myNames.size();
+      }
+
+      @Override
+      public Object getElementAt(int index) {
+        return myNames.get(index);
+      }
+    });
+    mySchemeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+    mySchemeList.addListSelectionListener(new ListSelectionListener() {
+      @Override
+      public void valueChanged(ListSelectionEvent e) {
+        int index = mySchemeList.getSelectedIndex();
+        if (index >= 0) {
+          mySelectedName = myNames.get(index);
+          if (!myUseCurrentScheme.isSelected() && !UNNAMED_SCHEME_ITEM.equals(mySelectedName)) myTargetNameField.setText(mySelectedName);
+        }
+      }
+    });
+    myUseCurrentScheme.setEnabled(currScheme != null);
+    myUseCurrentScheme.addActionListener(new ActionListener() {
+      @Override
+      public void actionPerformed(ActionEvent e) {
+        if (myUseCurrentScheme.isSelected()) {
+          myTargetNameField.setEnabled(false);
+          if (currScheme != null) {
+            myTargetNameField.setText(currScheme);
+          }
+        }
+        else {
+          myTargetNameField.setEnabled(true);
+          if (mySelectedName != null) myTargetNameField.setText(mySelectedName);
+        }
+      }
+    });
+    mySchemeList.getSelectionModel().setSelectionInterval(0,0);
+    init();
+  }
+
+  public String getSelectedName() {
+    return UNNAMED_SCHEME_ITEM.equals(mySelectedName) ? null : mySelectedName;
+  }
+
+  @Nullable
+  @Override
+  protected JComponent createCenterPanel() {
+    return contentPane;
+  }
+
+  public boolean isUseCurrentScheme() {
+    return myUseCurrentScheme.isSelected();
+  }
+
+  @Nullable
+  public String getTargetName() {
+    String name = myTargetNameField.getText();
+    return name != null && !name.trim().isEmpty() ? name : null;
+  }
+}
diff --git a/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.form b/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.form
new file mode 100644
index 0000000..9e42611
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.form
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.application.options.ImportSourceChooserDialog">
+  <grid id="cbd77" binding="myContentPane" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="10" left="10" bottom="10" right="10"/>
+    <constraints>
+      <xy x="48" y="54" width="436" height="297"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <grid id="e3588" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
+            <preferred-size width="200" height="200"/>
+          </grid>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <scrollpane id="89ab8" class="com.intellij.ui.components.JBScrollPane">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+            <border type="none"/>
+            <children>
+              <component id="5063d" class="com.intellij.ui.components.JBList" binding="mySourceList">
+                <constraints/>
+                <properties/>
+              </component>
+            </children>
+          </scrollpane>
+        </children>
+      </grid>
+    </children>
+  </grid>
+</form>
diff --git a/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.java b/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.java
new file mode 100644
index 0000000..067c868
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.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 com.intellij.application.options;
+
+import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.options.Scheme;
+import com.intellij.openapi.options.SchemeImporterEP;
+import com.intellij.openapi.options.SchemesManager;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.ui.components.JBCheckBox;
+import com.intellij.ui.components.JBList;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class ImportSourceChooserDialog <S extends Scheme> extends DialogWrapper {
+  private JPanel myContentPane;
+  private JBList mySourceList;
+
+  private String mySelectedSourceName;
+  private final ListModel myListModel;
+  
+  private final static String SHARED_IMPORT_SOURCE = ApplicationBundle.message("import.scheme.shared");
+  
+  public ImportSourceChooserDialog(JComponent parent, Class<S> schemeClass, SchemesManager schemesManager) {
+    super(parent, true);
+    setTitle(ApplicationBundle.message("title.import.scheme.from"));
+    myListModel = new SourceListModel(SchemeImporterEP.getExtensions(schemeClass), schemesManager.isImportAvailable());
+    initSourceList();
+    init();
+  }
+  
+  private void initSourceList() {
+    mySourceList.setModel(myListModel);
+    mySourceList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+    mySourceList.addListSelectionListener(new ListSelectionListener() {
+      @Override
+      public void valueChanged(ListSelectionEvent e) {
+        int index = mySourceList.getSelectedIndex();
+        if (index >= 0) {
+          setSelectedSourceName((String)myListModel.getElementAt(index));
+        }
+      }
+    });
+    mySourceList.setSelectedIndex(0);
+  }
+  
+  @Nullable
+  @Override
+  protected JComponent createCenterPanel() {
+    return myContentPane;
+  }
+  
+  private void setSelectedSourceName(String name) {
+    mySelectedSourceName = name;
+  }
+
+  @Nullable
+  public String getSelectedSourceName() {
+    return mySelectedSourceName;
+  }
+  
+  public boolean isImportFromSharedSelected() {
+    return SHARED_IMPORT_SOURCE.equals(mySelectedSourceName);
+  }
+  
+  private class SourceListModel extends DefaultListModel {
+    private List<String> mySourceNames = new ArrayList<String>();
+    
+    public SourceListModel(Collection<SchemeImporterEP<S>> extensions, boolean isSharedImportAvailable) {
+      for (SchemeImporterEP extension : extensions) {
+        mySourceNames.add(extension.name);
+      }
+      if (isSharedImportAvailable) {
+        mySourceNames.add(SHARED_IMPORT_SOURCE);
+      }
+    }
+
+    @Override
+    public int getSize() {
+      return mySourceNames.size();
+    }
+
+    @Override
+    public Object getElementAt(int index) {
+      return mySourceNames.get(index);
+    }
+  }
+
+}
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesModel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesModel.java
index 91d0782..4b2764b 100644
--- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesModel.java
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesModel.java
@@ -209,6 +209,10 @@
     myDispatcher.getMulticaster().currentSettingsChanged();
   }
 
+  public void fireSchemeChanged(CodeStyleScheme scheme) {
+    myDispatcher.getMulticaster().schemeChanged(scheme);
+  }
+
   public CodeStyleScheme getSelectedGlobalScheme() {
     return myGlobalSelected;
   }
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java
index a4c5d97..151a92f 100644
--- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java
@@ -15,18 +15,31 @@
  */
 package com.intellij.application.options.codeStyle;
 
-import com.intellij.application.options.ExportSchemeAction;
-import com.intellij.application.options.SaveSchemeDialog;
-import com.intellij.application.options.SchemesToImportPopup;
+import com.intellij.application.options.*;
 import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDialog;
+import com.intellij.openapi.fileChooser.FileChooserFactory;
+import com.intellij.openapi.options.SchemeImportException;
+import com.intellij.openapi.options.SchemeImporter;
+import com.intellij.openapi.options.SchemeImporterEP;
 import com.intellij.openapi.options.SchemesManager;
+import com.intellij.openapi.project.ProjectManager;
 import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.MessageType;
 import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.popup.Balloon;
+import com.intellij.openapi.ui.popup.BalloonBuilder;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.codeStyle.CodeStyleScheme;
 import com.intellij.psi.codeStyle.CodeStyleSchemes;
 import com.intellij.psi.impl.source.codeStyle.CodeStyleSchemeImpl;
+import com.intellij.ui.awt.RelativePoint;
 import com.intellij.ui.table.JBTable;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import javax.swing.event.ListSelectionEvent;
@@ -35,6 +48,8 @@
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.*;
 import java.util.List;
 
@@ -54,6 +69,7 @@
   private final MySchemesTableModel mySchemesTableModel;
   private final CodeStyleSchemesModel myModel;
   private final Component myParent;
+  private final SchemesManager<CodeStyleScheme, CodeStyleSchemeImpl> mySchemesManager;
 
 
   protected ManageCodeStyleSchemesDialog(final Component parent, CodeStyleSchemesModel schemesModel) {
@@ -98,15 +114,15 @@
       }
     });
 
-    final SchemesManager<CodeStyleScheme, CodeStyleSchemeImpl> schemesManager = CodeStyleSchemesModel.getSchemesManager();
+    mySchemesManager = CodeStyleSchemesModel.getSchemesManager();
 
-    if (schemesManager.isExportAvailable()) {
+    if (mySchemesManager.isExportAvailable()) {
       myExportButton.setVisible(true);
       myExportButton.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(final ActionEvent e) {
           CodeStyleScheme selected = getSelectedScheme();
-          ExportSchemeAction.doExport((CodeStyleSchemeImpl)selected, schemesManager);
+          ExportSchemeAction.doExport((CodeStyleSchemeImpl)selected, mySchemesManager);
         }
       });
       myExportButton.setMnemonic('S');
@@ -115,21 +131,12 @@
       myExportButton.setVisible(false);
     }
 
-    if (schemesManager.isImportAvailable()) {
+    if (mySchemesManager.isImportAvailable() || SchemeImporterEP.getExtensions(CodeStyleScheme.class).size() > 0) {
       myImportButton.setVisible(true);
       myImportButton.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(final ActionEvent e) {
-          SchemesToImportPopup<CodeStyleScheme, CodeStyleSchemeImpl> popup =
-            new SchemesToImportPopup<CodeStyleScheme, CodeStyleSchemeImpl>(parent) {
-              @Override
-              protected void onSchemeSelected(final CodeStyleSchemeImpl scheme) {
-                if (scheme != null) {
-                  myModel.addScheme(scheme, true);
-                }
-              }
-            };
-          popup.show(schemesManager, myModel.getSchemes());
+          chooseAndImport();
         }
       });
     }
@@ -140,6 +147,138 @@
     init();
   }
 
+  
+  private void chooseAndImport() {
+    ImportSourceChooserDialog<CodeStyleScheme> importSourceChooserDialog =
+      new ImportSourceChooserDialog<CodeStyleScheme>(myContentPane, CodeStyleScheme.class, mySchemesManager);
+    importSourceChooserDialog.show();
+    if (importSourceChooserDialog.isOK()) {
+      if (importSourceChooserDialog.isImportFromSharedSelected()) {
+          SchemesToImportPopup<CodeStyleScheme, CodeStyleSchemeImpl> popup =
+            new SchemesToImportPopup<CodeStyleScheme, CodeStyleSchemeImpl>(myContentPane) {
+              @Override
+              protected void onSchemeSelected(final CodeStyleSchemeImpl scheme) {
+                if (scheme != null) {
+                  myModel.addScheme(scheme, true);
+                }
+              }
+            };
+          popup.show(mySchemesManager, myModel.getSchemes());
+      }
+      else {
+        String selectedImporterName = importSourceChooserDialog.getSelectedSourceName();
+        if (selectedImporterName != null) {
+          try {
+            String schemeName = importExternalCodeStyle(selectedImporterName);
+            if (schemeName != null) {
+              showStatus(myImportButton,
+                         ApplicationBundle.message("message.code.style.scheme.import.success", selectedImporterName, schemeName),
+                         MessageType.INFO);
+            }
+          }
+          catch (SchemeImportException e) {
+            showStatus(myImportButton,
+                       ApplicationBundle.message("message.code.style.scheme.import.failure", selectedImporterName, e.getMessage()),
+                       MessageType.ERROR);
+          }
+        }
+      }
+    }
+  }
+
+  private static void showStatus(final Component component, final String message, MessageType messageType) {
+    BalloonBuilder balloonBuilder = JBPopupFactory.getInstance()
+      .createHtmlTextBalloonBuilder(message, messageType.getDefaultIcon(),
+                                    messageType.getPopupBackground(), null);
+    balloonBuilder.setFadeoutTime(5000);
+    final Balloon balloon = balloonBuilder.createBalloon();
+    final Rectangle rect = component.getBounds();
+    final Point p = new Point(rect.x, rect.y + rect.height);
+    final RelativePoint point = new RelativePoint(component, p);
+    balloon.show(point, Balloon.Position.below);
+    Disposer.register(ProjectManager.getInstance().getDefaultProject(), balloon);
+  }  
+  
+  @Nullable
+  private String importExternalCodeStyle(String importerName) throws SchemeImportException {
+    final SchemeImporter<CodeStyleScheme> importer = SchemeImporterEP.getImporter(importerName, CodeStyleScheme.class);
+    if (importer != null) {
+      FileChooserDialog fileChooser = FileChooserFactory.getInstance()
+        .createFileChooser(new FileChooserDescriptor(true, false, false, false, false, false) {
+          @Override
+          public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
+            return file.isDirectory() || importer.getSourceExtension().equals(file.getExtension());
+          }
+          @Override
+          public boolean isFileSelectable(VirtualFile file) {
+            return !file.isDirectory() && importer.getSourceExtension().equals(file.getExtension());
+          }
+        }, null, myContentPane);
+      VirtualFile[] selection = fileChooser.choose(null, null);
+      if (selection.length == 1) {
+        VirtualFile selectedFile = selection[0];
+        try {
+          InputStream nameInputStream = selectedFile.getInputStream();
+          String[] schemeNames;
+          try {
+            schemeNames = importer.readSchemeNames(nameInputStream);
+          }
+          finally {
+            nameInputStream.close();
+          }
+          CodeStyleScheme currScheme = myModel.getSelectedScheme();
+          ImportSchemeChooserDialog schemeChooserDialog =
+            new ImportSchemeChooserDialog(myContentPane, schemeNames, !currScheme.isDefault() ? currScheme.getName() : null);
+          schemeChooserDialog.show();
+          if (schemeChooserDialog.isOK()) {
+            String schemeName = schemeChooserDialog.getSelectedName();
+            String targetName = schemeChooserDialog.getTargetName();
+            CodeStyleScheme targetScheme = null;
+            if (schemeChooserDialog.isUseCurrentScheme()) {
+              targetScheme = myModel.getSelectedScheme();
+            }
+            else {
+              if (targetName == null) targetName = ApplicationBundle.message("code.style.scheme.import.unnamed");
+              for (CodeStyleScheme scheme : myModel.getSchemes()) {
+                if (targetName.equals(scheme.getName())) {
+                  targetScheme = scheme;
+                  break;
+                }
+              }
+              if (targetScheme == null) {
+                int row = mySchemesTableModel.createNewScheme(getSelectedScheme(), targetName);
+                mySchemesTable.getSelectionModel().setSelectionInterval(row, row);
+                targetScheme = mySchemesTableModel.getSchemeAt(row);
+              }
+              else {
+                int result = Messages.showYesNoDialog(myContentPane,
+                                                      ApplicationBundle.message("message.code.style.scheme.already.exists", targetName),
+                                                      ApplicationBundle.message("title.code.style.settings.import"),
+                                                      Messages.getQuestionIcon());
+                if (result != Messages.OK) {
+                  return null;
+                }
+              }
+            }
+            InputStream dataInputStream = selectedFile.getInputStream();
+            try {
+              importer.importScheme(dataInputStream, schemeName, targetScheme);
+              myModel.fireSchemeChanged(targetScheme);
+            }
+            finally {
+              dataInputStream.close();
+            }
+            return targetScheme.getName();
+          }
+        }
+        catch (IOException e) {
+          throw new SchemeImportException(e);
+        } 
+      }
+    }
+    return null;
+  }
+
   private void updateActions() {
     CodeStyleScheme selectedScheme = getSelectedScheme();
     myDeleteButton.setEnabled(!(selectedScheme.isDefault() || mySchemesTableModel.isProjectScheme(selectedScheme)));
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/HippieWordCompletionHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/HippieWordCompletionHandler.java
index e4dabb9..1660195 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/HippieWordCompletionHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/HippieWordCompletionHandler.java
@@ -27,11 +27,14 @@
 import com.intellij.openapi.editor.ex.EditorEx;
 import com.intellij.openapi.editor.highlighter.HighlighterIterator;
 import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.TextEditor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.PsiFile;
-import com.intellij.psi.impl.cache.impl.id.IdTableBuilding;
+import com.intellij.util.text.CharArrayUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -42,6 +45,7 @@
  */
 public class HippieWordCompletionHandler implements CodeInsightActionHandler {
   private static final Key<CompletionState> KEY_STATE = new Key<CompletionState>("HIPPIE_COMPLETION_STATE");
+  private static final String WHITESPACE_CHARS = " \t\n";
   private final boolean myForward;
 
   public HippieWordCompletionHandler(boolean forward) {
@@ -64,7 +68,7 @@
     String oldPrefix = completionState.oldPrefix;
     CompletionVariant lastProposedVariant = completionState.lastProposedVariant;
 
-    if (lastProposedVariant == null || oldPrefix == null || !prefixMatches(oldPrefix, currentPrefix) ||
+    if (lastProposedVariant == null || oldPrefix == null || !new CamelHumpMatcher(oldPrefix).isStartMatch(currentPrefix) ||
         !currentPrefix.equals(lastProposedVariant.variant)) {
       //we are starting over
       oldPrefix = currentPrefix;
@@ -201,24 +205,15 @@
 
     final int caretOffset = editor.getCaretModel().getOffset();
 
-    HighlighterIterator iterator = ((EditorEx)editor).getHighlighter().createIterator(0);
-    while (!iterator.atEnd()) {
-      int start = iterator.getStart();
-      int end = iterator.getEnd();
-      if ((start > caretOffset || end < caretOffset) &&  //skip prefix itself
-          end - start > matcher.getPrefix().length() && isWordLike(chars, start, end)) {
-        final String word = chars.subSequence(start, end).toString();
-        if (matcher.prefixMatches(word)) {
-          CompletionVariant v = new CompletionVariant(word, start);
-          if (end > caretOffset) {
-            afterWords.add(v);
-          }
-          else {
-            words.add(v);
-          }
+    addWordsForEditor((EditorEx)editor, matcher, chars, words, afterWords, caretOffset);
+
+    for(FileEditor fileEditor: FileEditorManager.getInstance(file.getProject()).getAllEditors()) {
+      if (fileEditor instanceof TextEditor) {
+        Editor anotherEditor = ((TextEditor)fileEditor).getEditor();
+        if (anotherEditor != editor) {
+          addWordsForEditor((EditorEx)anotherEditor, matcher, anotherEditor.getDocument().getCharsSequence(), words, afterWords, 0);
         }
       }
-      iterator.advance();
     }
 
     Set<String> allWords = new HashSet<String>();
@@ -245,29 +240,82 @@
 
     return result;
   }
+  
+  private interface TokenProcessor {
+    boolean processToken(int start, int end);
+  } 
 
-  private static boolean prefixMatches(String prefix, String word) {
-    return new CamelHumpMatcher(prefix == null ? "" : prefix).isStartMatch(word);
+  private static void addWordsForEditor(EditorEx editor,
+                                        final CamelHumpMatcher matcher,
+                                        final CharSequence chars,
+                                        final List<CompletionVariant> words,
+                                        final List<CompletionVariant> afterWords, final int caretOffset) {
+    int startOffset = 0;
+    TokenProcessor processor = new TokenProcessor() {
+      @Override
+      public boolean processToken(int start, int end) {
+        if ((start > caretOffset || end < caretOffset) &&  //skip prefix itself
+            end - start > matcher.getPrefix().length() && isWordLike(chars, start, end)) {
+          final String word = chars.subSequence(start, end).toString();
+          if (matcher.isStartMatch(word)) {
+            CompletionVariant v = new CompletionVariant(word, start);
+            if (end > caretOffset) {
+              afterWords.add(v);
+            }
+            else {
+              words.add(v);
+            }
+          }
+        }
+        return true;
+      }
+    };
+    processWords(editor, startOffset, processor);
+  }
+
+  private static void processWords(Editor editor, int startOffset, TokenProcessor processor) {
+    CharSequence chars = editor.getDocument().getCharsSequence();
+    HighlighterIterator iterator = ((EditorEx)editor).getHighlighter().createIterator(startOffset);
+    while (!iterator.atEnd()) {
+      int start = iterator.getStart();
+      int end = iterator.getEnd();
+      while (start < end) {
+        int nextWs = StringUtil.indexOfAny(chars, WHITESPACE_CHARS, start, end);
+        if (nextWs < 0) {
+          if (isWordLike(chars, start, end) && !processor.processToken(start, end)) {
+            return;
+          }
+          break;
+        }
+        if (isWordLike(chars, start, end) && !processor.processToken(start, nextWs)) {
+          return;
+        }
+        start = CharArrayUtil.shiftForward(chars, nextWs, WHITESPACE_CHARS);
+      }
+      iterator.advance();
+    }
   }
 
   private static CompletionData computeData(final Editor editor, final CharSequence charsSequence) {
     final int offset = editor.getCaretModel().getOffset();
 
     final CompletionData data = new CompletionData();
-
-    final int caretOffset = editor.getCaretModel().getOffset();
-
-    HighlighterIterator iterator = ((EditorEx)editor).getHighlighter().createIterator(offset - 1);
-    int start = iterator.getStart();
-    int end = iterator.getEnd();
-    if (start <= offset && end >= offset) {
-      if (isWordLike(charsSequence, start, end)) {
-        data.myPrefix = charsSequence.subSequence(start, offset).toString();
-        data.myWordUnderCursor = charsSequence.subSequence(start, end).toString();
-        data.startOffset = start;
+    
+    processWords(editor, offset - 1, new TokenProcessor() {
+      @Override
+      public boolean processToken(int start, int end) {
+        if (start > offset) {
+          return false;
+        }
+        if (end >= offset) {
+          data.myPrefix = charsSequence.subSequence(start, offset).toString();
+          data.myWordUnderCursor = charsSequence.subSequence(start, end).toString();
+          data.startOffset = start;
+          return false;
+        }
+        return true;
       }
-    }
-    iterator.advance();
+    });
 
     if (data.myPrefix == null) {
       data.myPrefix = "";
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java
index 100e1e1..82cd682 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java
@@ -96,10 +96,6 @@
         boolean errorFound = daemonCodeAnalyzer.getFileStatusMap().wasErrorFound(myDocument);
 
         for(ExternalAnnotator externalAnnotator: externalAnnotators) {
-          if (!errorFound) {
-            externalAnnotator.annotate(psiRoot, myAnnotationHolder);
-          }
-
           final Object collectedInfo = externalAnnotator.collectInformation(psiRoot, myEditor, errorFound);
           if (collectedInfo != null) {
             myAnnotator2DataMap.put(externalAnnotator, new MyData(psiRoot, collectedInfo));
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
index 02879fb..295c177 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
@@ -513,42 +513,6 @@
     }
   }
 
-  @NotNull
-  private HighlightInfoType highlightTypeFromDescriptor(@NotNull ProblemDescriptor problemDescriptor, @NotNull HighlightSeverity severity) {
-    final ProblemHighlightType highlightType = problemDescriptor.getHighlightType();
-    switch (highlightType) {
-      case GENERIC_ERROR_OR_WARNING:
-        return mySeverityRegistrar.getHighlightInfoTypeBySeverity(severity);
-      case LIKE_DEPRECATED:
-        return new HighlightInfoType.HighlightInfoTypeImpl(severity, HighlightInfoType.DEPRECATED.getAttributesKey());
-      case LIKE_UNKNOWN_SYMBOL:
-        if (severity == HighlightSeverity.ERROR) {
-          return new HighlightInfoType.HighlightInfoTypeImpl(severity, HighlightInfoType.WRONG_REF.getAttributesKey());
-        }
-        if (severity == HighlightSeverity.WARNING) {
-          return new HighlightInfoType.HighlightInfoTypeImpl(severity, CodeInsightColors.WEAK_WARNING_ATTRIBUTES);
-        }
-        return mySeverityRegistrar.getHighlightInfoTypeBySeverity(severity);
-      case LIKE_UNUSED_SYMBOL:
-        return new HighlightInfoType.HighlightInfoTypeImpl(severity, HighlightInfoType.UNUSED_SYMBOL.getAttributesKey());
-      case INFO:
-        return HighlightInfoType.INFO;
-       case WEAK_WARNING:
-        return HighlightInfoType.WEAK_WARNING;
-      case ERROR:
-        return HighlightInfoType.WRONG_REF;
-      case GENERIC_ERROR:
-        return HighlightInfoType.ERROR;
-      case INFORMATION:
-        final TextAttributesKey attributes = ((ProblemDescriptorBase)problemDescriptor).getEnforcedTextAttributes();
-        if (attributes != null) {
-          return new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, attributes);
-        }
-        return HighlightInfoType.INFORMATION;
-    }
-    throw new RuntimeException("Cannot map " + highlightType);
-  }
-
   @Override
   protected void applyInformationWithProgress() {
     UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument, myStartOffset, myEndOffset, myInfos, getColorsScheme(), getId());
@@ -592,7 +556,7 @@
                                              PsiElement element) {
     if (element == null) return;
     if (myIgnoreSuppressed && SuppressionUtil.inspectionResultSuppressed(element, tool.getTool())) return;
-    HighlightInfoType level = highlightTypeFromDescriptor(descriptor, severity);
+    HighlightInfoType level = ProblemDescriptorUtil.highlightTypeFromDescriptor(descriptor, severity, mySeverityRegistrar);
     HighlightInfo info = createHighlightInfo(descriptor, tool, level, emptyActionRegistered, element);
     if (info == null) return;
 
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java
index 14617b0..279aa54 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.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.
@@ -171,7 +171,7 @@
    * @param offset  target offset where line feed will be inserted
    * @return        offset to use for inserting closing brace
    */
-  private static int calculateOffsetToInsertClosingBrace(PsiFile file, CharSequence text, final int offset) {
+  protected int calculateOffsetToInsertClosingBrace(PsiFile file, CharSequence text, final int offset) {
     PsiElement element = PsiUtilCore.getElementAtOffset(file, offset);
     ASTNode node = element.getNode();
     if (node != null && node.getElementType() == TokenType.WHITE_SPACE) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
index 8b33bb7..0e5bcb2 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
@@ -315,7 +315,7 @@
         if (i == paramCount + added - 1) {
           myOneLineComponents[index] = new OneLineComponent();
           setBackground(background);
-          buf.append(myOneLineComponents[index].setup(text, flagsMap, background));
+          buf.append(myOneLineComponents[index].setup(escapeString(text), flagsMap, background));
           add(myOneLineComponents[index], new GridBagConstraints(0, index, 1, 1, 1, 0, GridBagConstraints.WEST,
                                                                  GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
           index += 1;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java
index 2a4594e..134143d 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java
@@ -30,6 +30,7 @@
 import com.intellij.openapi.editor.event.DocumentEvent;
 import com.intellij.openapi.editor.ex.EditorEx;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.ComboBox;
 import com.intellij.openapi.ui.popup.JBPopup;
 import com.intellij.openapi.ui.popup.JBPopupAdapter;
 import com.intellij.openapi.ui.popup.JBPopupFactory;
@@ -232,7 +233,7 @@
 
     gbConstraints.gridx = 1;
     gbConstraints.insets = new Insets(0, 4, 0, 0);
-    myExpandByCombo = new JComboBox(new Object[]{myDefaultShortcutItem, SPACE, TAB, ENTER});
+    myExpandByCombo = new ComboBox(new Object[]{myDefaultShortcutItem, SPACE, TAB, ENTER}, -1);
     myExpandByCombo.addItemListener(new ItemListener() {
       @Override
       public void itemStateChanged(ItemEvent e) {
@@ -309,6 +310,9 @@
     final Runnable updateLabel = new Runnable() {
       @Override
       public void run() {
+        myExpandByCombo.setEnabled(isExpandableFromEditor());
+        updateHighlighter();
+
         StringBuilder sb = new StringBuilder();
         String oldPrefix = "";
         for (TemplateContextType type : getApplicableContexts()) {
@@ -343,7 +347,7 @@
       public boolean onClick(MouseEvent e, int clickCount) {
         if (disposeContextPopup()) return false;
 
-        final JPanel content = createPopupContextPanel(updateLabel);
+        final JPanel content = createPopupContextPanel(updateLabel, myContext);
         Dimension prefSize = content.getPreferredSize();
         if (myLastSize != null && (myLastSize.width > prefSize.width || myLastSize.height > prefSize.height)) {
           content.setPreferredSize(new Dimension(Math.max(prefSize.width, myLastSize.width), Math.max(prefSize.height, myLastSize.height)));
@@ -374,7 +378,7 @@
     return false;
   }
 
-  private JPanel createPopupContextPanel(final Runnable onChange) {
+  static JPanel createPopupContextPanel(final Runnable onChange, final Map<TemplateContextType, Boolean> context) {
     JPanel panel = new JPanel(new BorderLayout());
 
     MultiMap<TemplateContextType, TemplateContextType> hierarchy = new MultiMap<TemplateContextType, TemplateContextType>() {
@@ -383,7 +387,7 @@
         return new LinkedHashMap<TemplateContextType, Collection<TemplateContextType>>();
       }
     };
-    for (TemplateContextType type : myContext.keySet()) {
+    for (TemplateContextType type : context.keySet()) {
       hierarchy.putValue(type.getBaseContextType(), type);
     }
 
@@ -401,17 +405,15 @@
       protected void onNodeStateChanged(CheckedTreeNode node) {
         final TemplateContextType type = (TemplateContextType)((Pair)node.getUserObject()).first;
         if (type != null) {
-          myContext.put(type, node.isChecked());
+          context.put(type, node.isChecked());
         }
-        myExpandByCombo.setEnabled(isExpandableFromEditor());
-        updateHighlighter();
         onChange.run();
 
       }
     };
 
     for (TemplateContextType type : hierarchy.get(null)) {
-      addContextNode(hierarchy, root, type);
+      addContextNode(hierarchy, root, type, context);
     }
 
     ((DefaultTreeModel)checkboxTree.getModel()).nodeStructureChanged(root);
@@ -434,23 +436,23 @@
     return panel;
   }
 
-  private void addContextNode(MultiMap<TemplateContextType, TemplateContextType> hierarchy,
-                              CheckedTreeNode parent,
-                              TemplateContextType type) {
+  private static void addContextNode(MultiMap<TemplateContextType, TemplateContextType> hierarchy,
+                                     CheckedTreeNode parent,
+                                     TemplateContextType type, Map<TemplateContextType, Boolean> context) {
     final Collection<TemplateContextType> children = hierarchy.get(type);
     final String name = UIUtil.removeMnemonic(type.getPresentableName());
     final CheckedTreeNode node = new CheckedTreeNode(Pair.create(children.isEmpty() ? type : null, name));
     parent.add(node);
 
     if (children.isEmpty()) {
-      node.setChecked(myContext.get(type));
+      node.setChecked(context.get(type));
     }
     else {
       for (TemplateContextType child : children) {
-        addContextNode(hierarchy, node, child);
+        addContextNode(hierarchy, node, child, context);
       }
       final CheckedTreeNode other = new CheckedTreeNode(Pair.create(type, "Other"));
-      other.setChecked(myContext.get(type));
+      other.setChecked(context.get(type));
       node.add(other);
     }
   }
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java
index 19033d9..76a423a 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java
@@ -30,12 +30,11 @@
 import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.options.SchemesManager;
 import com.intellij.openapi.project.DumbAwareAction;
-import com.intellij.openapi.ui.InputValidator;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.ui.Splitter;
+import com.intellij.openapi.ui.*;
 import com.intellij.openapi.ui.popup.JBPopupFactory;
 import com.intellij.openapi.ui.popup.ListPopup;
 import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.EmptyRunnable;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.ui.*;
 import com.intellij.util.Alarm;
@@ -848,12 +847,43 @@
       }
     };
 
+    final DumbAwareAction changeContext = new DumbAwareAction("Change context...") {
+
+      @Override
+      public void update(AnActionEvent e) {
+        boolean enabled = !getSelectedTemplates().isEmpty();
+        e.getPresentation().setEnabled(enabled);
+        super.update(e);
+      }
+
+      @Override
+      public void actionPerformed(AnActionEvent e) {
+        Map<TemplateImpl, DefaultMutableTreeNode> templates = getSelectedTemplates();
+        Map<TemplateContextType, Boolean> context = ContainerUtil.newHashMap();
+        for (TemplateContextType type : TemplateManagerImpl.getAllContextTypes()) {
+          context.put(type, Boolean.FALSE);
+        }
+        JPanel contextPanel = LiveTemplateSettingsEditor.createPopupContextPanel(EmptyRunnable.INSTANCE, context);
+        DialogBuilder builder = new DialogBuilder(TemplateListPanel.this);
+        builder.setCenterPanel(contextPanel);
+        builder.setTitle("Change Context Type For Selected Templates");
+        int result = builder.show();
+        if (result == DialogWrapper.OK_EXIT_CODE) {
+          for (TemplateImpl template : templates.keySet()) {
+            getTemplateContext(template).putAll(context);
+          }
+        } 
+      }
+    };
+
+
     myTree.addMouseListener(new PopupHandler() {
       @Override
       public void invokePopup(Component comp, int x, int y) {
         final DefaultActionGroup group = new DefaultActionGroup();
         group.add(rename);
         group.add(move);
+        group.add(changeContext);
         ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group).getComponent().show(comp, x, y);
       }
     });
diff --git a/platform/lang-impl/src/com/intellij/conversion/impl/ConversionServiceImpl.java b/platform/lang-impl/src/com/intellij/conversion/impl/ConversionServiceImpl.java
index a428f57..09ad57a 100644
--- a/platform/lang-impl/src/com/intellij/conversion/impl/ConversionServiceImpl.java
+++ b/platform/lang-impl/src/com/intellij/conversion/impl/ConversionServiceImpl.java
@@ -172,18 +172,23 @@
     return converters;
   }
 
-  public static boolean isConversionNeeded(String projectPath) throws CannotConvertException {
-    final ConversionContextImpl context = new ConversionContextImpl(projectPath);
-    final List<ConversionRunner> runners = getSortedConverters(context);
-    if (runners.isEmpty()) {
-      return false;
-    }
-    for (ConversionRunner runner : runners) {
-      if (runner.isConversionNeeded()) {
-        return true;
+  public static boolean isConversionNeeded(String projectPath) {
+    try {
+      final ConversionContextImpl context = new ConversionContextImpl(projectPath);
+      final List<ConversionRunner> runners = getSortedConverters(context);
+      if (runners.isEmpty()) {
+        return false;
       }
+      for (ConversionRunner runner : runners) {
+        if (runner.isConversionNeeded()) {
+          return true;
+        }
+      }
+      saveConversionResult(context);
     }
-    saveConversionResult(context);
+    catch (CannotConvertException e) {
+      LOG.info("Cannot check whether conversion of project files is needed or not, conversion won't be performed", e);
+    }
     return false;
   }
 
diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleFoldingConfigurable.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleFoldingConfigurable.java
index a4a5f8f..bf1195b 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleFoldingConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleFoldingConfigurable.java
@@ -113,7 +113,7 @@
 
     @Nullable
     private String showEditDialog(final String initialValue) {
-      return Messages.showInputDialog(this, myQuery, "Folding pattern", Messages.getQuestionIcon(), initialValue, new InputValidatorEx() {
+      return Messages.showInputDialog(this, myQuery, "Folding Pattern", Messages.getQuestionIcon(), initialValue, new InputValidatorEx() {
         @Override
         public boolean checkInput(String inputString) {
            return !StringUtil.isEmpty(inputString);
diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java
index 25e7b12..d7d1ab8 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java
@@ -58,7 +58,6 @@
 
 import java.awt.event.KeyEvent;
 import java.io.*;
-import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.ListIterator;
@@ -78,20 +77,10 @@
   private final ModelHelper myHelper;
   private long myLastSaveStamp;
 
-  public ConsoleHistoryController(@NotNull final String type,
-                                  @Nullable final String persistenceId,
-                                  @NotNull final LanguageConsoleImpl console,
-                                  @NotNull final ConsoleHistoryModel model) {
-    this(type, persistenceId, console, model, Charset.defaultCharset());
-  }
-  public ConsoleHistoryController(@NotNull final String type,
-                                  @Nullable final String persistenceId,
-                                  @NotNull final LanguageConsoleImpl console,
-                                  @NotNull final ConsoleHistoryModel model,
-                                  @NotNull final Charset charset)
-  {
+  public ConsoleHistoryController(@NotNull String type, @Nullable String persistenceId,
+                                  @NotNull LanguageConsoleImpl console, @NotNull ConsoleHistoryModel model) {
     String id = persistenceId == null || StringUtil.isEmpty(persistenceId) ? console.getProject().getPresentableUrl() : persistenceId;
-    myHelper = new ModelHelper(type, id, model, charset);
+    myHelper = new ModelHelper(type, id, model);
     myConsole = console;
   }
 
@@ -358,14 +347,11 @@
     private final String myId;
     private final ConsoleHistoryModel myModel;
     private String myContent;
-    @NotNull
-    private final Charset myCharset;
 
-    public ModelHelper(String type, String id, ConsoleHistoryModel model, @NotNull Charset charset) {
+    public ModelHelper(String type, String id, ConsoleHistoryModel model) {
       myType = type;
       myId = id;
       myModel = model;
-      myCharset = charset;
     }
 
     public ConsoleHistoryModel getModel() {
@@ -395,7 +381,7 @@
       if (!file.exists()) return false;
       HierarchicalStreamReader xmlReader = null;
       try {
-        xmlReader = new XppReader(new InputStreamReader(new FileInputStream(file), myCharset));
+        xmlReader = new XppReader(new InputStreamReader(new FileInputStream(file), CharsetToolkit.UTF8));
         String text = loadHistory(xmlReader, id);
         if (text != null) {
           myContent = text;
@@ -430,7 +416,7 @@
         catch (Exception e) {
           // not recognized
         }
-        serializer.setOutput(os = new SafeFileOutputStream(file), myCharset.name());
+        serializer.setOutput(os = new SafeFileOutputStream(file), CharsetToolkit.UTF8);
         saveHistory(serializer);
       }
       catch (Exception ex) {
diff --git a/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java b/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java
index 3d5e57b..ad7ee68 100644
--- a/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java
@@ -31,6 +31,7 @@
 import com.intellij.openapi.module.ModuleType;
 import com.intellij.openapi.module.ProjectLoadingErrorsNotifier;
 import com.intellij.openapi.project.ProjectBundle;
+import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.UnknownFeaturesCollector;
 import com.intellij.openapi.util.*;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.messages.MessageBus;
@@ -176,6 +177,7 @@
       final FacetType<?,?> type = myFacetTypeRegistry.findFacetType(typeId);
       if (type == null) {
         addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.unknown.facet.type.0", typeId));
+        UnknownFeaturesCollector.getInstance(myModule.getProject()).registerUnknownFeature("com.intellij.facetType", typeId);
         continue;
       }
 
@@ -190,10 +192,6 @@
       FacetTypeId<?> underlyingTypeId = type.getUnderlyingFacetType();
       if (underlyingTypeId != null) {
         expectedUnderlyingType = myFacetTypeRegistry.findFacetType(underlyingTypeId);
-        if (expectedUnderlyingType == null) {
-          addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.cannot.find.underlying.facet.type.for.0", typeId));
-          continue;
-        }
       }
       FacetType actualUnderlyingType = underlyingFacet != null ? underlyingFacet.getType() : null;
       if (expectedUnderlyingType != null) {
@@ -220,7 +218,10 @@
     }
   }
 
-  private void addInvalidFacet(final FacetState state, ModifiableFacetModel model, final Facet underlyingFacet, final String errorMessage) {
+  private void addInvalidFacet(final FacetState state,
+                               ModifiableFacetModel model,
+                               final Facet underlyingFacet,
+                               final String errorMessage) {
     final InvalidFacetManager invalidFacetManager = InvalidFacetManager.getInstance(myModule.getProject());
     final InvalidFacetType type = InvalidFacetType.getInstance();
     final InvalidFacetConfiguration configuration = new InvalidFacetConfiguration(state, errorMessage);
diff --git a/platform/lang-impl/src/com/intellij/facet/impl/FacetTypeRegistryImpl.java b/platform/lang-impl/src/com/intellij/facet/impl/FacetTypeRegistryImpl.java
index f39cd26..3cee6a4 100644
--- a/platform/lang-impl/src/com/intellij/facet/impl/FacetTypeRegistryImpl.java
+++ b/platform/lang-impl/src/com/intellij/facet/impl/FacetTypeRegistryImpl.java
@@ -63,6 +63,7 @@
     myTypeIds.remove(stringId);
   }
 
+  @NotNull
   @Override
   public synchronized FacetTypeId[] getFacetTypeIds() {
     loadExtensions();
@@ -70,6 +71,7 @@
     return ids.toArray(new FacetTypeId[ids.size()]);
   }
 
+  @NotNull
   @Override
   public synchronized FacetType[] getFacetTypes() {
     loadExtensions();
@@ -79,6 +81,7 @@
     return facetTypes;
   }
 
+  @NotNull
   @Override
   public FacetType[] getSortedFacetTypes() {
     final FacetType[] types = getFacetTypes();
@@ -94,11 +97,13 @@
     return typeId == null ? null : myFacetTypes.get(typeId);
   }
 
+  @NotNull
   @Override
-  @Nullable
-  public synchronized <F extends Facet<C>, C extends FacetConfiguration> FacetType<F, C> findFacetType(FacetTypeId<F> typeId) {
+  public synchronized <F extends Facet<C>, C extends FacetConfiguration> FacetType<F, C> findFacetType(@NotNull FacetTypeId<F> typeId) {
     loadExtensions();
-    return myFacetTypes.get(typeId);
+    FacetType type = myFacetTypes.get(typeId);
+    LOG.assertTrue(type != null, "Cannot find facet by id '" + typeId + "'");
+    return type;
   }
 
   private void loadExtensions() {
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
index 41eb35d..5d45876 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
@@ -24,7 +24,6 @@
 import com.intellij.find.*;
 import com.intellij.find.findUsages.FindUsagesManager;
 import com.intellij.find.impl.livePreview.SearchResults;
-import com.intellij.ide.highlighter.custom.CustomFileHighlighter;
 import com.intellij.lang.Language;
 import com.intellij.lang.LanguageParserDefinitions;
 import com.intellij.lang.ParserDefinition;
@@ -45,10 +44,7 @@
 import com.intellij.openapi.editor.markup.RangeHighlighter;
 import com.intellij.openapi.fileEditor.FileEditor;
 import com.intellij.openapi.fileEditor.TextEditor;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.LanguageFileType;
-import com.intellij.openapi.fileTypes.SyntaxHighlighter;
-import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
+import com.intellij.openapi.fileTypes.*;
 import com.intellij.openapi.fileTypes.impl.AbstractFileType;
 import com.intellij.openapi.keymap.KeymapUtil;
 import com.intellij.openapi.project.Project;
@@ -408,6 +404,7 @@
     final VirtualFile lastFile;
     int startOffset = 0;
     final SyntaxHighlighter highlighter;
+    final Lexer highlightingLexer;
 
     TokenSet tokensOfInterest;
     final StringSearcher searcher;
@@ -422,6 +419,7 @@
       this.searcher = searcher;
       this.matcher = matcher;
       this.relevantLanguages = relevantLanguages;
+      highlightingLexer = highlighter.getHighlightingLexer();
     }
   }
 
@@ -441,12 +439,16 @@
 
     CommentsLiteralsSearchData data = model.getUserData(ourCommentsLiteralsSearchDataKey);
     if (data == null || !Comparing.equal(data.lastFile, file)) {
-      SyntaxHighlighter lexer;
+      SyntaxHighlighter highlighter = getHighlighter(file, lang);
+
+      if (highlighter == null) {
+        LOG.error("Syntax highlighter is null:"+file);
+        return NOT_FOUND_RESULT;
+      }
 
       TokenSet tokensOfInterest = TokenSet.EMPTY;
       Set<Language> relevantLanguages = null;
       if (lang != null) {
-        lexer = getHighlighter(file, lang);
         final Language finalLang = lang;
         relevantLanguages = ApplicationManager.getApplication().runReadAction(new Computable<Set<Language>>() {
           @Override
@@ -488,25 +490,23 @@
             tokensOfInterest = TokenSet.orSet(tokensOfInterest, TokenSet.create(convenienceXmlAttrType));
           }
         }
-      } else if (ftype instanceof AbstractFileType) {
+      } else {
+        LOG.assertTrue(ftype instanceof AbstractFileType, ftype);
         if (model.isInCommentsOnly()) {
           tokensOfInterest = TokenSet.create(CustomHighlighterTokenType.LINE_COMMENT, CustomHighlighterTokenType.MULTI_LINE_COMMENT);
         }
         if (model.isInStringLiteralsOnly()) {
           tokensOfInterest = TokenSet.orSet(tokensOfInterest, TokenSet.create(CustomHighlighterTokenType.STRING, CustomHighlighterTokenType.SINGLE_QUOTED_STRING));
         }
-        lexer = new CustomFileHighlighter(((AbstractFileType)ftype).getSyntaxTable());
-      } else {
-        return NOT_FOUND_RESULT;
       }
 
       Matcher matcher = model.isRegularExpressions() ? compileRegExp(model, ""):null;
       StringSearcher searcher = matcher != null ? null: createStringSearcher(model);
-      data = new CommentsLiteralsSearchData(file, relevantLanguages, lexer, tokensOfInterest, searcher, matcher);
+      data = new CommentsLiteralsSearchData(file, relevantLanguages, highlighter, tokensOfInterest, searcher, matcher);
       model.putUserData(ourCommentsLiteralsSearchDataKey, data);
     }
 
-    final Lexer lexer = data.highlighter.getHighlightingLexer();
+    final Lexer lexer = data.highlightingLexer;
     lexer.start(text, model.isForward() && data.startOffset < offset ? data.startOffset : 0, text.length(), 0);
 
     IElementType tokenType;
@@ -527,12 +527,22 @@
         ) {
 
         int start = lexer.getTokenStart();
+        int end = lexer.getTokenEnd();
+        if (model.isInStringLiteralsOnly()) { // skip literal quotes itself from matching
+          char c = text.charAt(start);
+          if (c == '"' || c == '\'') {
+            while (start < end && c == text.charAt(start)) {
+              ++start;
+              if (c == text.charAt(end - 1) && start < end) --end;
+            }
+          }
+        }
 
         while(true) {
           FindResultImpl findResult = null;
 
           if (data.searcher != null) {
-            int i = data.searcher.scan(text, textArray, start, lexer.getTokenEnd());
+            int i = data.searcher.scan(text, textArray, start, end);
 
             if (i != -1 && i >= start) {
               final int matchEnd = i + model.getStringToFind().length();
@@ -544,7 +554,7 @@
               }
             }
           } else {
-            data.matcher.reset(text.subSequence(start, lexer.getTokenEnd()));
+            data.matcher.reset(text.subSequence(start, end));
             if (data.matcher.find()) {
               final int matchEnd = start + data.matcher.end();
               if (start >= offset || !scanningForward) {
@@ -563,7 +573,7 @@
               return findResult;
             } else {
 
-              if (findResult.getStartOffset() >= offset) return prevFindResult;
+              if (findResult.getEndOffset() >= offset) return prevFindResult;
               prevFindResult = findResult;
               start = findResult.getEndOffset();
               continue;
@@ -621,9 +631,12 @@
     return tokensOfInterest;
   }
 
-  private static SyntaxHighlighter getHighlighter(VirtualFile file, Language lang) {
-    SyntaxHighlighter syntaxHighlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(lang, null, file);
-    assert syntaxHighlighter != null:"Syntax highlighter is null:"+file;
+  private static @Nullable SyntaxHighlighter getHighlighter(VirtualFile file, @Nullable Language lang) {
+    SyntaxHighlighter syntaxHighlighter = lang != null ? SyntaxHighlighterFactory.getSyntaxHighlighter(lang, null, file) : null;
+    if (lang == null || syntaxHighlighter instanceof PlainSyntaxHighlighter) {
+      syntaxHighlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(file.getFileType(), null, file);
+    }
+
     return syntaxHighlighter;
   }
 
diff --git a/platform/lang-impl/src/com/intellij/formatting/AlignmentImpl.java b/platform/lang-impl/src/com/intellij/formatting/AlignmentImpl.java
index a641c51..427fa18 100644
--- a/platform/lang-impl/src/com/intellij/formatting/AlignmentImpl.java
+++ b/platform/lang-impl/src/com/intellij/formatting/AlignmentImpl.java
@@ -161,18 +161,87 @@
     myOffsetRespBlocks.add(block);
   }
 
+  @Nullable
+  private AbstractBlockWrapper getLeftRespNeighbor(@NotNull AbstractBlockWrapper block) {
+    AbstractBlockWrapper nearLeft = null;
+    int distance = Integer.MAX_VALUE;
+    for (AbstractBlockWrapper offsetBlock : myOffsetRespBlocks) if (offsetBlock != null) {
+      int curDistance = block.getStartOffset() - offsetBlock.getStartOffset();
+      if (curDistance < distance && curDistance > 0) {
+        nearLeft = offsetBlock;
+        distance = curDistance;
+      }
+    }
+    return nearLeft;
+  }
+
+  @NotNull
+  private static AbstractBlockWrapper extendBlockFromStart(@NotNull AbstractBlockWrapper block) {
+    while (true) {
+      AbstractBlockWrapper parent = block.getParent();
+      if (parent != null && parent.getStartOffset() == block.getStartOffset()) {
+        block = parent;
+      }
+      else {
+        return block;
+      }
+    }
+  }
+
+  @NotNull
+  private static AbstractBlockWrapper extendBlockFromEnd(@NotNull AbstractBlockWrapper block) {
+    while (true) {
+      AbstractBlockWrapper parent = block.getParent();
+      if (parent != null && parent.getEndOffset() == block.getEndOffset()) {
+        block = parent;
+      }
+      else {
+        return block;
+      }
+    }
+  }
+
   private boolean continueOffsetResponsibleBlockRetrieval(@Nullable AbstractBlockWrapper block) {
     // We don't want to align block that doesn't start new line if it's not configured for 'by columns' alignment.
     if (!myAllowBackwardShift && block != null && !block.getWhiteSpace().containsLineFeeds()) {
       return false;
     }
-    for (AbstractBlockWrapper offsetBlock : myOffsetRespBlocks) {
-      if (offsetBlock == block) {
-        continue;
-      }
-      if (!onDifferentLines(offsetBlock, block) && block != null && offsetBlock.getStartOffset() < block.getStartOffset()) {
+
+    if (block != null) {
+      AbstractBlockWrapper prevAlignBlock = getLeftRespNeighbor(block);
+      if (!onDifferentLines(prevAlignBlock, block)) {
         return false;
       }
+
+      //blocks are on different lines
+      if (myAllowBackwardShift
+          && myAnchor == Anchor.RIGHT
+          && prevAlignBlock != null
+          && prevAlignBlock.getWhiteSpace().containsLineFeeds() // {prevAlignBlock} starts new indent => can be moved
+      ) {
+        // extend block on position for right align
+        prevAlignBlock = extendBlockFromStart(prevAlignBlock);
+
+        AbstractBlockWrapper current = block;
+        do {
+          if (current.getStartOffset() < prevAlignBlock.getEndOffset()) {
+            return false; //{prevAlignBlock{current}} | {current}{prevAlignBlock}, no new lines
+          }
+          if (current.getWhiteSpace().containsLineFeeds()) {
+            break; // correct new line was found
+          }
+          else {
+            AbstractBlockWrapper prev = current.getPreviousBlock();
+            if (prev != null) {
+                prev = extendBlockFromEnd(prev);
+            }
+            current = prev;
+          }
+        } while (current != null);
+        if (current == null) {
+          return false; //root block is the top
+        }
+      }
     }
     return myParentAlignment == null || myParentAlignment.continueOffsetResponsibleBlockRetrieval(block);
   }
diff --git a/platform/lang-impl/src/com/intellij/ide/FileIconPatcherImpl.java b/platform/lang-impl/src/com/intellij/ide/FileIconPatcherImpl.java
index e0fb470..64fce21 100644
--- a/platform/lang-impl/src/com/intellij/ide/FileIconPatcherImpl.java
+++ b/platform/lang-impl/src/com/intellij/ide/FileIconPatcherImpl.java
@@ -21,7 +21,7 @@
 
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiFileSystemItem;
 import com.intellij.psi.PsiManager;
 import com.intellij.util.PsiIconUtil;
 import org.jetbrains.annotations.NotNull;
@@ -33,9 +33,10 @@
   @Override
   @Nullable
   public Icon getIcon(@NotNull final VirtualFile file, final int flags, final Project project) {
-    if(project == null) return null;
+    if (project == null) return null;
 
-    final PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
+    final PsiFileSystemItem psiFile = file.isDirectory() ? PsiManager.getInstance(project).findDirectory(file)
+                                                         : PsiManager.getInstance(project).findFile(file);
     return psiFile == null ? null : PsiIconUtil.getProvidersIcon(psiFile, flags);
   }
 }
\ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/ide/NativeIconProvider.java b/platform/lang-impl/src/com/intellij/ide/NativeIconProvider.java
new file mode 100644
index 0000000..d709da6
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/NativeIconProvider.java
@@ -0,0 +1,162 @@
+/*
+ * 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.ide;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.INativeFileType;
+import com.intellij.openapi.fileTypes.UnknownFileType;
+import com.intellij.openapi.util.Iconable;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFileSystemItem;
+import com.intellij.psi.impl.ElementBase;
+import com.intellij.ui.DeferredIconImpl;
+import com.intellij.util.Function;
+import com.intellij.util.ui.update.ComparableObject;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.io.File;
+import java.util.*;
+
+/**
+ * @author yole
+ */
+public class NativeIconProvider extends IconProvider {
+  private final Map<Ext, Icon> myIconCache = new HashMap<Ext, Icon>();
+  // on Windows .exe and .ico files provide their own icons which can differ for each file, cache them by full file path
+  private final Set<Ext> myCustomIconExtensions =
+    SystemInfo.isWindows ? new HashSet<Ext>(Arrays.asList(new Ext("exe"), new Ext("ico"))) : new HashSet<Ext>();
+  private final Map<String, Icon> myCustomIconCache = new HashMap<String, Icon>();
+
+  private static final Ext NO_EXT = new Ext(null);
+
+  private static final Ext CLOSED_DIR = new Ext(null, 0);
+
+  @Nullable
+  @Override
+  public Icon getIcon(@NotNull PsiElement element, @Iconable.IconFlags int flags) {
+    if (element instanceof PsiFileSystemItem) {
+      VirtualFile file = ((PsiFileSystemItem)element).getVirtualFile();
+      return doGetIcon(file, flags);
+    }
+    return null;
+  }
+
+  @Nullable
+  private Icon doGetIcon(@NotNull VirtualFile file, final int flags) {
+    if (!isNativeFileType(file)) return null;
+
+    final Ext ext = getExtension(file, flags);
+    final String filePath = file.getPath();
+
+    Icon icon;
+    synchronized (myIconCache) {
+      if (!myCustomIconExtensions.contains(ext)) {
+        icon = ext != null ? myIconCache.get(ext) : null;
+      }
+      else {
+        icon = filePath != null ? myCustomIconCache.get(filePath) : null;
+      }
+    }
+    if (icon != null) {
+      return icon;
+    }
+    return new DeferredIconImpl<VirtualFile>(ElementBase.ICON_PLACEHOLDER.getValue(), file, false, new Function<VirtualFile, Icon>() {
+      @Override
+      public Icon fun(VirtualFile virtualFile) {
+        final File f = new File(filePath);
+        if (!f.exists()) {
+          return null;
+        }
+        Icon icon;
+        try { // VM will ensure lock to init -static final field--, note we should have no read access here, to avoid deadlock with EDT needed to init component
+          assert SwingComponentHolder.ourFileChooser != null || !ApplicationManager.getApplication().isReadAccessAllowed();
+          icon = getNativeIcon(f);
+        }
+        catch (Exception e) {      // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4854174
+          return null;
+        }
+        if (ext != null) {
+          synchronized (myIconCache) {
+            if (!myCustomIconExtensions.contains(ext)) {
+              myIconCache.put(ext, icon);
+            }
+            else if (filePath != null) {
+              myCustomIconCache.put(filePath, icon);
+            }
+          }
+        }
+        return icon;
+      }
+    });
+  }
+
+  @Nullable
+  public static Icon getNativeIcon(@Nullable File file) {
+    return file == null ? null : SwingComponentHolder.ourFileChooser.getIcon(file);
+  }
+
+  private static Ext getExtension(final VirtualFile file, final int flags) {
+    if (file.isDirectory()) {
+      if (file.getExtension() == null) {
+        return CLOSED_DIR;
+      } else {
+        return new Ext(file.getExtension(), flags);
+      }
+    }
+
+    return file.getExtension() != null ? new Ext(file.getExtension()) : NO_EXT;
+  }
+
+  static class SwingComponentHolder {
+    private static final JFileChooser ourFileChooser = new JFileChooser();
+  }
+
+  protected boolean isNativeFileType(VirtualFile file) {
+    FileType type = file.getFileType();
+
+    if (type instanceof INativeFileType) return ((INativeFileType)type).useNativeIcon();
+    return type instanceof UnknownFileType && !file.isDirectory();
+  }
+
+  private static class Ext extends ComparableObject.Impl {
+    private final Object[] myText;
+
+    private Ext(@Nullable String text) {
+      myText = new Object[] {text};
+    }
+
+    private Ext(@Nullable String text, final int flags) {
+      myText = new Object[] {text, flags};
+    }
+
+    @Override
+    @NotNull
+    public Object[] getEqualityObjects() {
+      return myText;
+    }
+
+    @Override
+    public String toString() {
+      return myText[0] != null ? myText[0].toString() : null;
+    }
+  }
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
index fb332bb..c54493b 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
@@ -34,6 +34,8 @@
 import com.intellij.openapi.actionSystem.impl.ActionManagerImpl;
 import com.intellij.openapi.application.AccessToken;
 import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.colors.EditorFontType;
 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
 import com.intellij.openapi.fileEditor.impl.EditorHistoryManager;
 import com.intellij.openapi.keymap.KeymapUtil;
@@ -71,6 +73,7 @@
 import com.intellij.ui.components.JBScrollPane;
 import com.intellij.ui.components.OnOffButton;
 import com.intellij.ui.popup.AbstractPopup;
+import com.intellij.ui.popup.PopupPositionManager;
 import com.intellij.util.Alarm;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.Consumer;
@@ -89,6 +92,8 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import static com.intellij.ui.popup.PopupPositionManager.Position.*;
+
 /**
  * @author Konstantin Bulenkov
  */
@@ -107,10 +112,15 @@
   private JBPopup myPopup;
   private int myLeftWidth;
   private SearchListModel myListModel = new SearchListModel();
+  private int myMoreClassesIndex = -1;
+  private int myMoreFilesIndex = -1;
+  private int myMoreActionsIndex = -1;
+  private int myMoreSettingsIndex = -1;
   private TitleIndexes myTitleIndexes;
   private Map<String, String> myConfigurables = new HashMap<String, String>();
 
   private Alarm myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, ApplicationManager.getApplication());
+  private Alarm myUpdateAlarm = new Alarm(ApplicationManager.getApplication());
   private JBList myList = new JBList(myListModel) {
     {
       setOpaque(false);
@@ -142,11 +152,9 @@
     }, null);
   }
 
-  private int myTopHitsCount;
-  private int myInitialWidth;
-  private int myInitialHeight;
   private Balloon myBalloon;
   private JLabel mySearchLabel;
+  private int myPopupActualWidth;
 
   public SearchEverywhereAction() {
     myContentPanel = new JPanel(new BorderLayout());
@@ -184,7 +192,7 @@
         final int i = myList.locationToIndex(e.getPoint());
         if (i != -1) {
           myList.setSelectedIndex(i);
-          doNavigate();
+          doNavigate(i);
         }
       }
     });
@@ -272,7 +280,7 @@
           focusManager.requestDefaultFocus(true);
         }
         else if (keyCode == KeyEvent.VK_ENTER) {
-          doNavigate();
+          doNavigate(myList.getSelectedIndex());
         }
       }
     });
@@ -291,7 +299,7 @@
           myCalcThread = null;
         }
         myAlarm.cancelAllRequests();
-        myListModel.clear();
+        clearModel();
         myContentPanel.remove(field);
         myContentPanel.add(mySearchLabel);
 
@@ -307,14 +315,37 @@
     });
   }
 
+  private void clearModel() {
+    myListModel.clear();
+    myMoreClassesIndex = -1;
+    myMoreFilesIndex = -1;
+    myMoreActionsIndex = -1;
+    myMoreSettingsIndex = -1;
+  }
+
   private SearchTextField getField() {
     return myBalloon != null ? myPopupField : field;
   }
 
-  private void doNavigate() {
+  private void doNavigate(int index) {
+    final Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(getField().getTextEditor()));
+    if (isMoreItem(index)) {
+      String actionId = null;
+      if (index == myMoreClassesIndex) actionId = "GotoClass";
+      else if (index == myMoreFilesIndex) actionId = "GotoFile";
+      else if (index == myMoreSettingsIndex) actionId = "ShowSettings";
+      else if (index == myMoreActionsIndex) actionId = "GotoAction";
+      if (actionId != null) {
+        final AnAction action = ActionManager.getInstance().getAction(actionId);
+        GotoActionAction.openOptionOrPerformAction(action, getField().getText(), project, getField(), myActionEvent);
+        if (myPopup != null && myPopup.isVisible()) {
+          myPopup.cancel();
+        }
+        return;
+      }
+    }
     final String pattern = getField().getText();
     final Object value = myList.getSelectedValue();
-    final Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(getField().getTextEditor()));
     IdeFocusManager focusManager = IdeFocusManager.findInstanceByComponent(field.getTextEditor());
     if (myPopup != null && myPopup.isVisible()) {
       myPopup.cancel();
@@ -356,6 +387,10 @@
     focusManager.requestDefaultFocus(true);
   }
 
+  private boolean isMoreItem(int index) {
+    return index == myMoreClassesIndex || index == myMoreFilesIndex || index == myMoreSettingsIndex || index == myMoreActionsIndex;
+  }
+
   private void rebuildList(final String pattern) {
     if (myCalcThread != null) {
       myCalcThread.cancel();
@@ -377,13 +412,16 @@
     myPopupField.setOpaque(true);
     initSearchField(myPopupField);
     myPopupField.getTextEditor().setColumns(25);
-    myBalloon = JBPopupFactory.getInstance().createBalloonBuilder(myPopupField)
+    final JPanel panel = new JPanel(new BorderLayout());
+    panel.add(new JLabel("Search Everywhere:"), BorderLayout.NORTH);
+    panel.add(myPopupField, BorderLayout.CENTER);
+    myBalloon = JBPopupFactory.getInstance().createBalloonBuilder(panel)
       .setShowCallout(false)
       .setHideOnKeyOutside(false)
       .setHideOnAction(true)
       .setAnimationCycle(0)
       .setDialogMode(false)
-      .setBorderColor(new JBColor(new Color(156, 192, 255), new Color(77, 77, 77)))
+      .setBorderColor(new JBColor(new Color(156, 192, 255), Gray._77))
       .setFillColor(new JBColor(new Color(77, 121, 231), new Color(60, 63, 65)))
       .createBalloon();
     myBalloon.show(JBPopupFactory.getInstance().guessBestPopupLocation(e.getDataContext()), Balloon.Position.below);
@@ -454,8 +492,10 @@
       Component cmp;
       PsiFile file;
       myLocationString = null;
-      if (value instanceof VirtualFile && myProject != null && (file = PsiManager.getInstance(myProject).findFile((VirtualFile)value)) != null) {
-          cmp = new GotoFileCellRenderer(list.getWidth()).getListCellRendererComponent(list, file, index, isSelected, cellHasFocus);
+      if (isMoreItem(index)) {
+        cmp = More.get(isSelected);
+      } else if (value instanceof VirtualFile && myProject != null && (file = PsiManager.getInstance(myProject).findFile((VirtualFile)value)) != null) {
+        cmp = new GotoFileCellRenderer(list.getWidth()).getListCellRendererComponent(list, file, index, isSelected, cellHasFocus);
       } else if (value instanceof PsiElement) {
         cmp = myPsiRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
       } else {
@@ -477,9 +517,12 @@
         cmp = panel;
       }
 
-      final Color bg = isSelected ? UIUtil.getListSelectionBackground() : getRightBackground();
-      cmp.setBackground(bg);
-      myMainPanel.setBorder(new CustomLineBorder(bg, 0, 0, 1, 0));
+      //cmp.setBackground(bg);
+      Color bg = cmp.getBackground();
+      if (bg == null) {
+        bg = UIUtil.getListBackground(isSelected);
+      }
+      myMainPanel.setBorder(new CustomLineBorder(bg, 0, 0, 2, 0));
       String title = myTitleIndexes.getTitle(index);
       myMainPanel.removeAll();
       if (title != null) {
@@ -487,6 +530,11 @@
         myMainPanel.add(SeparatorComponent.createLabeledLineSeparator(" " + title, getRightBackground()), BorderLayout.NORTH);
       }
       myMainPanel.add(cmp, BorderLayout.CENTER);
+      final int width = myMainPanel.getPreferredSize().width;
+      if (width > myPopupActualWidth) {
+        myPopupActualWidth = width;
+        schedulePopupUpdate();
+      }
       return myMainPanel;
     }
 
@@ -578,6 +626,16 @@
     }
   }
 
+  private void schedulePopupUpdate() {
+    myUpdateAlarm.cancelAllRequests();
+    myUpdateAlarm.addRequest(new Runnable() {
+      @Override
+      public void run() {
+        updatePopupBounds();
+      }
+    }, 50);
+  }
+
   private static JBColor getTitlePanelBackground() {
     return new JBColor(Gray._242, JBColor.background());
   }
@@ -620,7 +678,7 @@
         @Override
         public void run() {
           myTitleIndexes.clear();
-          myListModel.clear();
+          clearModel();
           myAlreadyAddedFiles.clear();
         }
       });
@@ -659,13 +717,13 @@
         Object[] objects = myActionModel.getElementsByName(o.elementName, true, pattern);
         for (Object object : objects) {
           myProgressIndicator.checkCanceled();
-          if (isSetting(object) && settings.size() < 15) {
+          if (isSetting(object) && settings.size() < 5) {
             settings.add(object);
           }
           else if (isToolWindowAction(object) && toolWindows.size() < 10) {
             toolWindows.add((AnAction)((Map.Entry)object).getKey());
           }
-          else if (isActionValue(object) && actions.size() < 15) {
+          else if (isActionValue(object) && actions.size() < 5) {
             actions.add((AnAction)((Map.Entry)object).getKey());
           }
         }
@@ -689,12 +747,14 @@
               myListModel.addElement(action);
             }
           }
+          myMoreActionsIndex = actions.size() >= 5 ? myListModel.size() - 1 : -1;
           if (settings.size() > 0) {
             myTitleIndexes.settings = myListModel.size();
             for (Object setting : settings) {
               myListModel.addElement(setting);
             }
           }
+          myMoreSettingsIndex = settings.size() >= 5 ? myListModel.size() - 1 : -1;
         }
       });
     }
@@ -719,7 +779,6 @@
               filesCounter++;
             }
           }
-          if (filesCounter > 15) break;
         }
       }
 
@@ -734,6 +793,7 @@
               for (Object file : files) {
                 myListModel.addElement(file);
               }
+              myMoreFilesIndex = files.size() >= 15 ? myListModel.size() - 1 : -1;
             }
           }
         });
@@ -780,6 +840,7 @@
               for (Object cls : classes) {
                 myListModel.addElement(cls);
               }
+              myMoreClassesIndex = classes.size() >= 15 ? myListModel.size() - 1 : -1;
             }
           }
         });
@@ -951,10 +1012,13 @@
 
           myRenderer.recalculateWidth();
           if (myPopup == null || !myPopup.isVisible()) {
+            final Font editorFont = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN);
+            myList.setFont(editorFont);
+            getField().getTextEditor().setFont(editorFont);
+            More.instance.label.setFont(editorFont);
             final ActionCallback callback = ListDelegationUtil.installKeyboardDelegation(getField().getTextEditor(), myList);
             final ComponentPopupBuilder builder = JBPopupFactory.getInstance()
               .createComponentPopupBuilder(new JBScrollPane(myList), null);
-            myInitialWidth = myInitialHeight = 0;
             myPopup = builder
               .setRequestFocus(false)
               .setCancelKeyEnabled(false)
@@ -997,29 +1061,16 @@
             //rebuildList("");
           }
           else {
-            final Dimension size = myList.getPreferredSize();
-            Dimension sz = new Dimension(Math.max(getField().getWidth(), size.width), size.height);
-            if (sz.width > 800 || sz.height > 800) {
-              final int extra = new JBScrollPane().getVerticalScrollBar().getWidth();
-              sz = new Dimension(Math.min(800, Math.max(getField().getWidth(), size.width + extra)), Math.min(800, size.height + extra));
-              sz.width += 16;
-            }
-            else {
-              sz.height++;
-              sz.height++;
-              sz.width++;
-              sz.width++;
-            }
-            myPopup.setSize(sz);
-            final Point screen = getField().getLocationOnScreen();
-            final int x;
-            if (getField() == field) {
-               x = screen.x + getField().getWidth() - myPopup.getSize().width;
-            } else {
-              x = screen.x - myLeftWidth - 5;
-            }
-
-            //myPopup.setLocation(new Point(x, myPopup.getLocationOnScreen().y));
+            updatePopupBounds();
+            //final Point screen = getField().getLocationOnScreen();
+            //final int x;
+            //if (getField() == field) {
+            //   x = screen.x + getField().getWidth() - myPopup.getSize().width;
+            //} else {
+            //  x = screen.x - myLeftWidth - 5;
+            //}
+            //
+            ////myPopup.setLocation(new Point(x, myPopup.getLocationOnScreen().y));
           }
         }
       });
@@ -1083,6 +1134,34 @@
     }
   }
 
+  private void updatePopupBounds() {
+    if (myPopup == null || !myPopup.isVisible()) {
+      return;
+    }
+    final Dimension size = myList.getPreferredSize();
+    if (size.width < myPopupActualWidth) {
+      size.width = myPopupActualWidth;
+    }
+    Dimension sz = new Dimension(Math.max(getField().getWidth(), size.width), size.height);
+    if (sz.width > 800 || sz.height > 800) {
+      final int extra = new JBScrollPane().getVerticalScrollBar().getWidth();
+      sz = new Dimension(Math.min(800, Math.max(getField().getWidth(), size.width + extra)), Math.min(800, size.height + extra));
+      sz.width += 16;
+    }
+    else {
+      sz.height++;
+      sz.height++;
+      sz.width++;
+      sz.width++;
+    }
+    myPopup.setSize(sz);
+    adjustPopup();
+  }
+
+  private void adjustPopup() {
+    new PopupPositionManager.PositionAdjuster(getField().getTextEditor().getParent()).adjust(myPopup, BOTTOM, RIGHT, LEFT, TOP);
+  }
+
   private static boolean isToolWindowAction(Object o) {
     return isActionValue(o) && (o instanceof Map.Entry && ((Map.Entry)o).getKey() instanceof ActivateToolWindowAction);
   }
@@ -1167,8 +1246,7 @@
       catch (NoSuchFieldException e) {
 
       }
-      catch (IllegalAccessException e) {
-        e.printStackTrace();
+      catch (IllegalAccessException ignore) {
       }
     }
 
@@ -1181,4 +1259,20 @@
       fireContentsChanged(this, 0, getSize() - 1);
     }
   }
+
+  static class More extends JPanel {
+    static final More instance = new More();
+    final JLabel label = new JLabel("    ... more");
+
+    private More() {
+      super(new BorderLayout());
+      add(label, BorderLayout.WEST);
+    }
+
+    static More get(boolean isSelected) {
+      instance.setBackground(UIUtil.getListBackground(isSelected));
+      instance.label.setForeground(UIUtil.getListForeground(isSelected));
+      return instance;
+    }
+  }
 }
diff --git a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeHighlighterProvider.java b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeHighlighterProvider.java
index 45b00de..cea90638 100644
--- a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeHighlighterProvider.java
+++ b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeHighlighterProvider.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.
@@ -24,6 +24,7 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.ide.highlighter.custom.CustomFileHighlighter;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -32,7 +33,7 @@
 public class CustomFileTypeHighlighterProvider implements SyntaxHighlighterProvider {
   @Override
   @Nullable
-  public SyntaxHighlighter create(final FileType fileType, @Nullable final Project project, @Nullable final VirtualFile file) {
+  public SyntaxHighlighter create(@NotNull final FileType fileType, @Nullable final Project project, @Nullable final VirtualFile file) {
     if (fileType instanceof AbstractFileType) {
       return new CustomFileHighlighter(((CustomSyntaxTableFileType) fileType).getSyntaxTable());
     }
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java
index 0f4e1c6..0a9679b 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java
@@ -64,6 +64,6 @@
 
   private static <P extends JpsElement> void addSourceFolder(VirtualFile vFile, ContentEntry entry,
                                                              JpsModuleSourceRootType<P> markAsRootType) {
-    entry.addSourceFolder(vFile, markAsRootType, ModuleSourceRootEditHandler.getEditHandler(markAsRootType).createDefaultProperties());
+    entry.addSourceFolder(vFile, markAsRootType, markAsRootType.createDefaultProperties());
   }
 }
diff --git a/platform/lang-impl/src/com/intellij/ide/todo/TodoConfiguration.java b/platform/lang-impl/src/com/intellij/ide/todo/TodoConfiguration.java
deleted file mode 100644
index c4ef507..0000000
--- a/platform/lang-impl/src/com/intellij/ide/todo/TodoConfiguration.java
+++ /dev/null
@@ -1,205 +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.ide.todo;
-
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.components.NamedComponent;
-import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.JDOMExternalizable;
-import com.intellij.openapi.util.WriteExternalException;
-import com.intellij.psi.search.*;
-import com.intellij.util.EventDispatcher;
-import com.intellij.util.messages.MessageBus;
-import org.jdom.Element;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * @author Vladimir Kondratyev
- */
-public class TodoConfiguration implements NamedComponent, JDOMExternalizable {
-  private TodoPattern[] myTodoPatterns;
-  private TodoFilter[] myTodoFilters;
-  private IndexPattern[] myIndexPatterns;
-
-  private final EventDispatcher<PropertyChangeListener> myPropertyChangeMulticaster = EventDispatcher.create(PropertyChangeListener.class);
-
-  @NonNls public static final String PROP_TODO_PATTERNS = "todoPatterns";
-  @NonNls public static final String PROP_TODO_FILTERS = "todoFilters";
-  @NonNls private static final String ELEMENT_PATTERN = "pattern";
-  @NonNls private static final String ELEMENT_FILTER = "filter";
-  private final MessageBus myMessageBus;
-
-  /**
-   * Invoked by reflection
-   */
-  TodoConfiguration(@NotNull MessageBus messageBus) {
-    myMessageBus = messageBus;
-    resetToDefaultTodoPatterns();
-  }
-
-  public void resetToDefaultTodoPatterns() {
-    myTodoPatterns = new TodoPattern[]{
-      new TodoPattern("\\btodo\\b.*", TodoAttributesUtil.createDefault(), false),
-      new TodoPattern("\\bfixme\\b.*", TodoAttributesUtil.createDefault(), false),
-    };
-    myTodoFilters = new TodoFilter[]{};
-    buildIndexPatterns();
-  }
-
-  private void buildIndexPatterns() {
-    myIndexPatterns = new IndexPattern[myTodoPatterns.length];
-    for(int i=0; i<myTodoPatterns.length; i++) {
-      myIndexPatterns [i] = myTodoPatterns [i].getIndexPattern();
-    }
-  }
-
-  public static TodoConfiguration getInstance() {
-    return ServiceManager.getService(TodoConfiguration.class);
-  }
-
-  @Override
-  @NotNull
-  public String getComponentName() {
-    return "TodoConfiguration";
-  }
-
-  @NotNull
-  public TodoPattern[] getTodoPatterns() {
-    return myTodoPatterns;
-  }
-
-  @NotNull
-  public IndexPattern[] getIndexPatterns() {
-    return myIndexPatterns;
-  }
-
-  public void setTodoPatterns(@NotNull TodoPattern[] todoPatterns) {
-    doSetTodoPatterns(todoPatterns, true);
-  }
-
-  private void doSetTodoPatterns(@NotNull TodoPattern[] todoPatterns, final boolean shouldNotifyIndices) {
-    TodoPattern[] oldTodoPatterns = myTodoPatterns;
-    IndexPattern[] oldIndexPatterns = myIndexPatterns;
-
-    myTodoPatterns = todoPatterns;
-    buildIndexPatterns();
-
-    // only trigger index refresh actual index patterns have changed
-    if (shouldNotifyIndices && !Arrays.deepEquals(myIndexPatterns, oldIndexPatterns)) {
-      final PropertyChangeEvent event =
-        new PropertyChangeEvent(this, IndexPatternProvider.PROP_INDEX_PATTERNS, oldTodoPatterns, todoPatterns);
-      myMessageBus.syncPublisher(IndexPatternProvider.INDEX_PATTERNS_CHANGED).propertyChange(event);
-    }
-
-    // only trigger gui and code daemon refresh when either the index patterns or presentation attributes have changed
-    if (!Arrays.deepEquals(myTodoPatterns, oldTodoPatterns)) {
-      final PropertyChangeListener multicaster = myPropertyChangeMulticaster.getMulticaster();
-      multicaster.propertyChange(new PropertyChangeEvent(this, PROP_TODO_PATTERNS, oldTodoPatterns, todoPatterns));
-    }
-  }
-
-  /**
-   * @return <code>TodoFilter</code> with specified <code>name</code>. Method returns
-   *         <code>null</code> if there is no filter with <code>name</code>.
-   */
-  public TodoFilter getTodoFilter(String name) {
-    for (TodoFilter filter : myTodoFilters) {
-      if (filter.getName().equals(name)) {
-        return filter;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * @return all <code>TodoFilter</code>s.
-   */
-  @NotNull
-  public TodoFilter[] getTodoFilters() {
-    return myTodoFilters;
-  }
-
-  public void setTodoFilters(@NotNull TodoFilter[] filters) {
-    TodoFilter[] oldFilters = myTodoFilters;
-    myTodoFilters = filters;
-    myPropertyChangeMulticaster.getMulticaster().propertyChange(new PropertyChangeEvent(this, PROP_TODO_FILTERS, oldFilters, filters));
-  }
-
-  public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {
-    myPropertyChangeMulticaster.addListener(listener);
-  }
-  public void addPropertyChangeListener(@NotNull PropertyChangeListener listener, @NotNull Disposable parentDisposable) {
-    myPropertyChangeMulticaster.addListener(listener,parentDisposable);
-  }
-  public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) {
-    myPropertyChangeMulticaster.removeListener(listener);
-  }
-
-  @Override
-  public void readExternal(Element element) throws InvalidDataException {
-    List<TodoPattern> patternsList = new ArrayList<TodoPattern>();
-    List<TodoFilter> filtersList = new ArrayList<TodoFilter>();
-    for (Object o : element.getChildren()) {
-      Element child = (Element)o;
-      if (ELEMENT_PATTERN.equals(child.getName())) {
-        TodoPattern pattern = new TodoPattern(TodoAttributesUtil.createDefault());
-        pattern.readExternal(child, TodoAttributesUtil.getDefaultColorSchemeTextAttributes());
-        patternsList.add(pattern);
-      }
-      else if (ELEMENT_FILTER.equals(child.getName())) {
-        TodoPattern[] patterns = patternsList.toArray(new TodoPattern[patternsList.size()]);
-        TodoFilter filter = new TodoFilter();
-        filter.readExternal(child, patterns);
-        filtersList.add(filter);
-      }
-    }
-    doSetTodoPatterns(patternsList.toArray(new TodoPattern[patternsList.size()]), false);
-    setTodoFilters(filtersList.toArray(new TodoFilter[filtersList.size()]));
-  }
-
-  @Override
-  public void writeExternal(Element element) throws WriteExternalException {
-    final TodoPattern[] todoPatterns = myTodoPatterns;
-    for (TodoPattern pattern : todoPatterns) {
-      Element child = new Element(ELEMENT_PATTERN);
-      pattern.writeExternal(child);
-      element.addContent(child);
-    }
-    for (TodoFilter filter : myTodoFilters) {
-      Element child = new Element(ELEMENT_FILTER);
-      filter.writeExternal(child, todoPatterns);
-      element.addContent(child);
-    }
-  }
-
-  public void colorSettingsChanged() {
-    for (TodoPattern pattern : myTodoPatterns) {
-      TodoAttributes attributes = pattern.getAttributes();
-      if (!attributes.shouldUseCustomTodoColor()) {
-        attributes.setUseCustomTodoColor(false, TodoAttributesUtil.getDefaultColorSchemeTextAttributes());
-      }
-    }
-  }
-}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
index dde9d2a..8de17ab 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
@@ -508,7 +508,7 @@
 
   @Nullable
   protected PsiFile getPsiFile(final Project project) {
-    return PsiDocumentManager.getInstance(project).getPsiFile(myEditor.getDocument());
+    return myEditor == null ? null : PsiDocumentManager.getInstance(project).getPsiFile(myEditor.getDocument());
   }
 
   @Override
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
index f4886f4..1970b47 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
@@ -798,18 +798,6 @@
     String[] cached = getNamesSync(checkboxState);
     if (cached != null) return cached;
 
-    Window window = (Window)SwingUtilities.getAncestorOfClass(Window.class, myTextField);
-    //LOG.assertTrue (myTextField != null);
-    //LOG.assertTrue (window != null);
-    Window ownerWindow = null;
-    if (window != null) {
-      window.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-      ownerWindow = window.getOwner();
-      if (ownerWindow != null) {
-        ownerWindow.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-      }
-    }
-
     if (checkboxState &&
         myModel instanceof ContributorsBasedGotoByModel &&
         ((ContributorsBasedGotoByModel)myModel).sameNamesForProjectAndLibraries() &&
@@ -825,12 +813,6 @@
     assert result != null : "Model "+myModel+ "("+myModel.getClass()+") returned null names";
     setNamesSync(checkboxState, result);
 
-    if (window != null) {
-      window.setCursor(Cursor.getDefaultCursor());
-      if (ownerWindow != null) {
-        ownerWindow.setCursor(Cursor.getDefaultCursor());
-      }
-    }
     return result;
   }
 
@@ -898,15 +880,6 @@
         cancelCalcElementsThread();
       }
     });
-    ApplicationManager.getApplication().addApplicationListener(new ApplicationAdapter() {
-      @Override
-      public void beforeWriteActionStart(Object action) {
-        CalcElementsThread prevThread = cancelCalcElementsThread();
-        if (prevThread != null) {
-          prevThread.scheduleRestart();
-        }
-      }
-    }, myTextPopup);
     myTextPopup.show(layeredPane);
   }
 
@@ -1503,7 +1476,7 @@
 
     private final Alarm myShowCardAlarm = new Alarm();
 
-    void scheduleRestart() {
+    private void scheduleRestart() {
       scheduleCalcElements(new CalcElementsThread(myPattern, myCheckboxState, myCallback, myModalityState, myCanCancel, myScopeExpanded));
     }
 
@@ -1520,6 +1493,15 @@
               ApplicationManager.getApplication().runReadAction(new Runnable() {
                 @Override
                 public void run() {
+                  ApplicationAdapter listener = new ApplicationAdapter() {
+                    @Override
+                    public void beforeWriteActionStart(Object action) {
+                      cancel();
+                      scheduleRestart();
+                      ApplicationManager.getApplication().removeApplicationListener(this);
+                    }
+                  };
+                  ApplicationManager.getApplication().addApplicationListener(listener);
                   try {
                     boolean everywhere = myCheckboxState;
                     if (!ourLoadNamesEachTime) ensureNamesLoaded(everywhere);
@@ -1528,6 +1510,9 @@
                   catch (ProcessCanceledException e) {
                     //OK
                   }
+                  finally {
+                    ApplicationManager.getApplication().removeApplicationListener(listener);
+                  }
                 }
               });
             }
diff --git a/platform/lang-impl/src/com/intellij/lexer/PrefixSuffixStripperLexer.java b/platform/lang-impl/src/com/intellij/lexer/PrefixSuffixStripperLexer.java
index 2a52a07..8bf8d3c 100644
--- a/platform/lang-impl/src/com/intellij/lexer/PrefixSuffixStripperLexer.java
+++ b/platform/lang-impl/src/com/intellij/lexer/PrefixSuffixStripperLexer.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.
@@ -21,6 +21,7 @@
 
 import com.intellij.psi.tree.IElementType;
 import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.NotNull;
 
 public class PrefixSuffixStripperLexer extends LexerBase {
   private CharSequence myBuffer;
@@ -49,7 +50,7 @@
   }
 
   @Override
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     myBuffer = buffer;
     myBufferArray = CharArrayUtil.fromSequenceWithoutCopying(buffer);
     myTokenStart = startOffset;
@@ -87,6 +88,7 @@
     return myBufferEnd;
   }
 
+  @NotNull
   @Override
   public CharSequence getBufferSequence() {
     return myBuffer;
diff --git a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java
index 75d9296..e353198 100644
--- a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java
+++ b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java
@@ -119,10 +119,8 @@
     public void load(@NotNull final Element rootElement) throws IOException {
       super.load(rootElement);
 
-      final List attributes = rootElement.getAttributes();
-      for (Object attribute : attributes) {
-        final Attribute attr = (Attribute)attribute;
-        myOptions.put(attr.getName(), attr.getValue());
+      for (Attribute attribute : rootElement.getAttributes()) {
+        myOptions.put(attribute.getName(), attribute.getValue());
       }
     }
 
diff --git a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java
index 6ac59b2..37e7089 100644
--- a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java
@@ -154,7 +154,7 @@
   @Override
   public boolean isModified() {
     if (!myManager.isIgnoredFilesListEqualToCurrent(myFileTypePanel.myIgnoreFilesField.getText())) return true;
-    HashSet types = new HashSet(Arrays.asList(getModifiableFileTypes()));
+    HashSet<FileType> types = new HashSet<FileType>(Arrays.asList(getModifiableFileTypes()));
     return !myTempPatternsTable.equals(myManager.getExtensionMap()) || !myTempFileTypes.equals(types) ||
            !myOriginalToEditedMap.isEmpty() ||
            !myTempTemplateDataLanguages.equals(TemplateDataLanguagePatterns.getInstance().getAssocTable());
diff --git a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java
deleted file mode 100644
index 9521bc7..0000000
--- a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java
+++ /dev/null
@@ -1,145 +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.openapi.fileTypes.impl;
-
-import com.intellij.ide.FileIconProvider;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.impl.ElementBase;
-import com.intellij.ui.DeferredIconImpl;
-import com.intellij.util.Function;
-import com.intellij.util.ui.update.ComparableObject;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.io.File;
-import java.util.*;
-
-/**
- * @author yole
- */
-public class NativeFileIconProvider implements FileIconProvider {
-  private final Map<Ext, Icon> myIconCache = new HashMap<Ext, Icon>();
-  // on Windows .exe and .ico files provide their own icons which can differ for each file, cache them by full file path
-  private final Set<Ext> myCustomIconExtensions =
-    SystemInfo.isWindows ? new HashSet<Ext>(Arrays.asList(new Ext("exe"), new Ext("ico"))) : new HashSet<Ext>();
-  private final Map<String, Icon> myCustomIconCache = new HashMap<String, Icon>();
-
-  private static final Ext NO_EXT = new Ext(null);
-
-  private static final Ext CLOSED_DIR = new Ext(null, 0);
-
-  @Override
-  public Icon getIcon(@NotNull VirtualFile file, final int flags, @Nullable Project project) {
-    if (!isNativeFileType(file)) return null;
-
-    final Ext ext = getExtension(file, flags);
-    final String filePath = file.getPath();
-
-    Icon icon;
-    synchronized (myIconCache) {
-      if (!myCustomIconExtensions.contains(ext)) {
-        icon = ext != null ? myIconCache.get(ext) : null;
-      }
-      else {
-        icon = filePath != null ? myCustomIconCache.get(filePath) : null;
-      }
-    }
-    if (icon != null) {
-      return icon;
-    }
-    return new DeferredIconImpl<VirtualFile>(ElementBase.ICON_PLACEHOLDER.getValue(), file, false, new Function<VirtualFile, Icon>() {
-      @Override
-      public Icon fun(VirtualFile virtualFile) {
-        final File f = new File(filePath);
-        if (!f.exists()) {
-          return null;
-        }
-        Icon icon;
-        try { // VM will ensure lock to init -static final field--, note we should have no read access here, to avoid deadlock with EDT needed to init component
-          assert SwingComponentHolder.ourFileChooser != null || !ApplicationManager.getApplication().isReadAccessAllowed();
-          icon = getNativeIcon(f);
-        }
-        catch (Exception e) {      // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4854174
-          return null;
-        }
-        if (ext != null) {
-          synchronized (myIconCache) {
-            if (!myCustomIconExtensions.contains(ext)) {
-              myIconCache.put(ext, icon);
-            }
-            else if (filePath != null) {
-              myCustomIconCache.put(filePath, icon);
-            }
-          }
-        }
-        return icon;
-      }
-    });
-  }
-
-  @Nullable
-  public static Icon getNativeIcon(@Nullable File file) {
-    return file == null ? null : SwingComponentHolder.ourFileChooser.getIcon(file);
-  }
-
-  private static Ext getExtension(final VirtualFile file, final int flags) {
-    if (file.isDirectory()) {
-      if (file.getExtension() == null) {
-        return CLOSED_DIR;
-      } else {
-        return new Ext(file.getExtension(), flags);
-      }
-    }
-
-    return file.getExtension() != null ? new Ext(file.getExtension()) : NO_EXT;
-  }
-
-  static class SwingComponentHolder {
-    private static final JFileChooser ourFileChooser = new JFileChooser();
-  }
-
-  protected boolean isNativeFileType(VirtualFile file) {
-    return ElementBase.isNativeFileType(file.getFileType());
-  }
-
-  private static class Ext extends ComparableObject.Impl {
-    private final Object[] myText;
-
-    private Ext(@Nullable String text) {
-      myText = new Object[] {text};
-    }
-
-    private Ext(@Nullable String text, final int flags) {
-      myText = new Object[] {text, flags};
-    }
-
-    @Override
-    @NotNull
-    public Object[] getEqualityObjects() {
-      return myText;
-    }
-
-    @Override
-    public String toString() {
-      return myText[0] != null ? myText[0].toString() : null;
-    }
-  }
-}
diff --git a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/ANSIColoredConsoleColorsPage.java b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/ANSIColoredConsoleColorsPage.java
index af7e2b9..3b3ebf3 100644
--- a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/ANSIColoredConsoleColorsPage.java
+++ b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/ANSIColoredConsoleColorsPage.java
@@ -35,6 +35,7 @@
     "<logExpired>An expired log entry</logExpired>\n" +
     "\n" +
     "# Process output highlighted using ANSI colors codes\n" +
+    "<black>ANSI: black</black>\n" +
     "<red>ANSI: red</red>\n" +
     "<green>ANSI: green</green>\n" +
     "<yellow>ANSI: yellow</yellow>\n" +
@@ -42,6 +43,14 @@
     "<magenta>ANSI: magenta</magenta>\n" +
     "<cyan>ANSI: cyan</cyan>\n" +
     "<gray>ANSI: gray</gray>\n" +
+    "<darkGray>ANSI: dark gray</darkGray>\n" +
+    "<redBright>ANSI: bright red</redBright>\n" +
+    "<greenBright>ANSI: bright green</greenBright>\n" +
+    "<yellowBright>ANSI: bright yellow</yellowBright>\n" +
+    "<blueBright>ANSI: bright blue</blueBright>\n" +
+    "<magentaBright>ANSI: bright magenta</magentaBright>\n" +
+    "<cyanBright>ANSI: bright cyan</cyanBright>\n" +
+    "<white>ANSI: white</white>\n" +
     "\n" +
     "<stdsys>Process finished with exit code 1</stdsys>\n";
 
@@ -55,6 +64,7 @@
     new AttributesDescriptor(OptionsBundle.message("options.general.color.descriptor.console.warning"), ConsoleViewContentType.LOG_WARNING_OUTPUT_KEY),
     new AttributesDescriptor(OptionsBundle.message("options.general.color.descriptor.console.expired"), ConsoleViewContentType.LOG_EXPIRED_ENTRY),
 
+    new AttributesDescriptor(OptionsBundle.message("color.settings.console.black"), ConsoleHighlighter.BLACK),
     new AttributesDescriptor(OptionsBundle.message("color.settings.console.red"), ConsoleHighlighter.RED),
     new AttributesDescriptor(OptionsBundle.message("color.settings.console.green"), ConsoleHighlighter.GREEN),
     new AttributesDescriptor(OptionsBundle.message("color.settings.console.yellow"), ConsoleHighlighter.YELLOW),
@@ -62,6 +72,15 @@
     new AttributesDescriptor(OptionsBundle.message("color.settings.console.magenta"), ConsoleHighlighter.MAGENTA),
     new AttributesDescriptor(OptionsBundle.message("color.settings.console.cyan"), ConsoleHighlighter.CYAN),
     new AttributesDescriptor(OptionsBundle.message("color.settings.console.gray"), ConsoleHighlighter.GRAY),
+
+    new AttributesDescriptor(OptionsBundle.message("color.settings.console.darkGray"), ConsoleHighlighter.DARKGRAY),
+    new AttributesDescriptor(OptionsBundle.message("color.settings.console.redBright"), ConsoleHighlighter.RED_BRIGHT),
+    new AttributesDescriptor(OptionsBundle.message("color.settings.console.greenBright"), ConsoleHighlighter.GREEN_BRIGHT),
+    new AttributesDescriptor(OptionsBundle.message("color.settings.console.yellowBright"), ConsoleHighlighter.YELLOW_BRIGHT),
+    new AttributesDescriptor(OptionsBundle.message("color.settings.console.blueBright"), ConsoleHighlighter.BLUE_BRIGHT),
+    new AttributesDescriptor(OptionsBundle.message("color.settings.console.magentaBright"), ConsoleHighlighter.MAGENTA_BRIGHT),
+    new AttributesDescriptor(OptionsBundle.message("color.settings.console.cyanBright"), ConsoleHighlighter.CYAN_BRIGHT),
+    new AttributesDescriptor(OptionsBundle.message("color.settings.console.white"), ConsoleHighlighter.WHITE),
   };
 
   private static final Map<String, TextAttributesKey> ADDITIONAL_HIGHLIGHT_DESCRIPTORS = new HashMap<String, TextAttributesKey>();
@@ -74,6 +93,7 @@
     ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("logWarning", ConsoleViewContentType.LOG_WARNING_OUTPUT_KEY);
     ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("logExpired", ConsoleViewContentType.LOG_EXPIRED_ENTRY);
 
+    ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("black", ConsoleHighlighter.BLACK);
     ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("red", ConsoleHighlighter.RED);
     ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("green", ConsoleHighlighter.GREEN);
     ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("yellow", ConsoleHighlighter.YELLOW);
@@ -81,6 +101,15 @@
     ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("magenta", ConsoleHighlighter.MAGENTA);
     ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("cyan", ConsoleHighlighter.CYAN);
     ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("gray", ConsoleHighlighter.GRAY);
+
+    ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("darkGray", ConsoleHighlighter.DARKGRAY);
+    ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("redBright", ConsoleHighlighter.RED_BRIGHT);
+    ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("greenBright", ConsoleHighlighter.GREEN_BRIGHT);
+    ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("yellowBright", ConsoleHighlighter.YELLOW_BRIGHT);
+    ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("blueBright", ConsoleHighlighter.BLUE_BRIGHT);
+    ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("magentaBright", ConsoleHighlighter.MAGENTA_BRIGHT);
+    ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("cyanBright", ConsoleHighlighter.CYAN_BRIGHT);
+    ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("white", ConsoleHighlighter.WHITE);
   }
 
   private static final ColorDescriptor[] COLORS = {
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/AttachRootButtonDescriptor.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/AttachRootButtonDescriptor.java
index 2b72f74..cad5f60 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/AttachRootButtonDescriptor.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/AttachRootButtonDescriptor.java
@@ -30,10 +30,25 @@
 public abstract class AttachRootButtonDescriptor {
   private final OrderRootType myOrderRootType;
   protected final String myButtonText;
+  private final Icon myToolbarIcon;
 
+  /**
+   * Creates a descriptor for 'attach' button shown in popup when user click on '+' button.
+   * Consider using {@link #AttachRootButtonDescriptor(com.intellij.openapi.roots.OrderRootType, javax.swing.Icon, String)} instead.
+   */
   protected AttachRootButtonDescriptor(@NotNull OrderRootType orderRootType, @NotNull String buttonText) {
     myOrderRootType = orderRootType;
     myButtonText = buttonText;
+    myToolbarIcon = null;
+  }
+
+  /**
+   * Creates a descriptor for 'attach' button shown in toolbar of a library editor
+   */
+  protected AttachRootButtonDescriptor(@NotNull OrderRootType orderRootType, @NotNull Icon toolbarIcon, @NotNull String description) {
+    myOrderRootType = orderRootType;
+    myButtonText = description;
+    myToolbarIcon = toolbarIcon;
   }
 
   public abstract VirtualFile[] selectFiles(@NotNull JComponent parent, @Nullable VirtualFile initialSelection,
@@ -55,4 +70,9 @@
   public VirtualFile[] scanForActualRoots(@NotNull VirtualFile[] rootCandidates, JComponent parent) {
     return rootCandidates;
   }
+
+  @Nullable
+  public Icon getToolbarIcon() {
+    return myToolbarIcon;
+  }
 }
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/LibraryRootsComponentDescriptor.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/LibraryRootsComponentDescriptor.java
index 5936a7d..fd75cc3 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/LibraryRootsComponentDescriptor.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/LibraryRootsComponentDescriptor.java
@@ -76,7 +76,7 @@
   }
 
   /**
-   * @return descriptors for 'Attach' buttons in the library roots editor
+   * @return descriptors for additional 'Attach' buttons in the library roots editor
    */
   @NotNull
   public abstract List<? extends AttachRootButtonDescriptor> createAttachButtons();
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/RootDetectionUtil.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/RootDetectionUtil.java
index 620eb8c..d96b400 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/RootDetectionUtil.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/RootDetectionUtil.java
@@ -15,6 +15,8 @@
  */
 package com.intellij.openapi.roots.libraries.ui.impl;
 
+import com.intellij.ide.util.ChooseElementsDialog;
+import com.intellij.openapi.application.ApplicationNamesInfo;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.progress.ProgressIndicator;
@@ -26,13 +28,13 @@
 import com.intellij.openapi.roots.libraries.ui.LibraryRootsComponentDescriptor;
 import com.intellij.openapi.roots.libraries.ui.LibraryRootsDetector;
 import com.intellij.openapi.roots.libraries.ui.OrderRoot;
-import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.ArrayUtil;
+import com.intellij.xml.util.XmlStringUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import javax.swing.*;
 import java.awt.*;
 import java.util.*;
 import java.util.List;
@@ -116,12 +118,19 @@
         }
       }
       LOG.assertTrue(!types.isEmpty(), "No allowed root types found for " + detector);
-      List<String> sortedNames = new ArrayList<String>(types.keySet());
-      Collections.sort(sortedNames, String.CASE_INSENSITIVE_ORDER);
-      final int i = Messages.showChooseDialog("Choose category for selected files:", "Attach Files",
-                                              ArrayUtil.toStringArray(sortedNames), sortedNames.get(0), null);
-      if (i != -1) {
-        final Pair<OrderRootType, Boolean> pair = types.get(sortedNames.get(i));
+      List<String> names = new ArrayList<String>(types.keySet());
+      String title = "Choose Categories of Selected Files";
+      String description = XmlStringUtil.wrapInHtml(ApplicationNamesInfo.getInstance().getProductName() + " cannot determine what kind of files the chosen items contain.<br>" +
+                           "Choose the appropriate categories from the list.");
+      ChooseElementsDialog<String> dialog;
+      if (parentComponent != null) {
+        dialog = new ChooseRootTypeElementsDialog(parentComponent, names, title, description);
+      }
+      else {
+        dialog = new ChooseRootTypeElementsDialog(project, names, title, description);
+      }
+      for (String rootType : dialog.showAndGetResult()) {
+        final Pair<OrderRootType, Boolean> pair = types.get(rootType);
         for (VirtualFile candidate : rootCandidates) {
           result.add(new OrderRoot(candidate, pair.getFirst(), pair.getSecond()));
         }
@@ -139,4 +148,25 @@
     }
     return true;
   }
+
+  private static class ChooseRootTypeElementsDialog extends ChooseElementsDialog<String> {
+    public ChooseRootTypeElementsDialog(Project project, List<String> names, String title, String description) {
+      super(project, names, title, description, true);
+    }
+
+    private ChooseRootTypeElementsDialog(Component parent, List<String> names, String title, String description) {
+      super(parent, names, title, description, true);
+    }
+
+    @Override
+    protected String getItemText(String item) {
+      return item;
+    }
+
+    @Nullable
+    @Override
+    protected Icon getItemIcon(String item) {
+      return null;
+    }
+  }
 }
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootEditHandlerBase.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootEditHandlerBase.java
index a2aa899..e17d4c5 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootEditHandlerBase.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootEditHandlerBase.java
@@ -22,7 +22,6 @@
 import com.intellij.ui.roots.IconActionComponent;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
-import org.jetbrains.jps.model.JpsElementFactory;
 import org.jetbrains.jps.model.JpsSimpleElement;
 import org.jetbrains.jps.model.java.JavaSourceRootProperties;
 import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
@@ -38,12 +37,6 @@
     super(rootType);
   }
 
-  @NotNull
-  @Override
-  public JpsSimpleElement<JavaSourceRootProperties> createDefaultProperties() {
-    return JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties());
-  }
-
   @Nullable
   @Override
   public String getPropertiesString(@NotNull JpsSimpleElement<JavaSourceRootProperties> properties) {
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleSourceRootEditHandler.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleSourceRootEditHandler.java
index fae804f..069ca2d 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleSourceRootEditHandler.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleSourceRootEditHandler.java
@@ -83,9 +83,6 @@
   @NotNull
   public abstract String getUnmarkRootButtonText();
 
-  @NotNull
-  public abstract P createDefaultProperties();
-
   @Nullable
   public String getPropertiesString(@NotNull P properties) {
     return null;
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java
index 9abe519..edb911b 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java
@@ -18,9 +18,9 @@
 
 import com.intellij.ide.DeleteProvider;
 import com.intellij.ide.TitledHandler;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.actionSystem.LangDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.module.ModifiableModuleModel;
@@ -36,7 +36,6 @@
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.projectImport.ProjectAttachProcessor;
-import com.intellij.util.ArrayUtil;
 import com.intellij.util.ArrayUtilRt;
 import com.intellij.util.Function;
 import com.intellij.util.PlatformUtils;
@@ -75,7 +74,8 @@
   public void deleteElement(@NotNull DataContext dataContext) {
     final Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext);
     assert modules != null;
-    final Project project = PlatformDataKeys.PROJECT.getData(dataContext);
+    final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+    assert project != null;
     String names = StringUtil.join(Arrays.asList(modules), new Function<Module, String>() {
       @Override
       public String fun(final Module module) {
@@ -115,7 +115,7 @@
 
   private static String getConfirmationText(Module[] modules, String names) {
     if (ProjectAttachProcessor.canAttachToProject()) {
-      return "Would you like to detach the project" + (modules.length > 1 ? "s " : " ") +  names + "?";
+      return ProjectBundle.message("project.remove.confirmation.prompt", names, modules.length);
     }
     return ProjectBundle.message("module.remove.confirmation.prompt", names, modules.length);
   }
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java
index e7e68c3..62159b6 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java
@@ -66,7 +66,7 @@
       final SourceFolder sourceFolder = contentEntryEditor.getSourceFolder(selectedFile);
       if (isSelected) {
         if (sourceFolder == null) { // not marked yet
-          P properties = myEditHandler.createDefaultProperties();
+          P properties = myEditHandler.getRootType().createDefaultProperties();
           contentEntryEditor.addSourceFolder(selectedFile, myEditHandler.getRootType(), properties);
         }
         else if (!myEditHandler.getRootType().equals(sourceFolder.getRootType())) {
@@ -75,7 +75,7 @@
             properties = (P)((SourceFolderImpl)sourceFolder).getJpsElement().getProperties().getBulkModificationSupport().createCopy();
           }
           else {
-            properties = myEditHandler.createDefaultProperties();
+            properties = myEditHandler.getRootType().createDefaultProperties();
           }
           contentEntryEditor.removeSourceFolder(sourceFolder);
           contentEntryEditor.addSourceFolder(selectedFile, myEditHandler.getRootType(), properties);
diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java
index b0c22a6..5bf8b52 100644
--- a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java
+++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java
@@ -639,6 +639,10 @@
       }
     }
 
+    /**
+     * @return position <code>x</code> for which <code>myDocument.getText().substring(x, startOffset)</code> contains
+     * <code>blankLinesNumber</code> line feeds and <code>myDocument.getText.charAt(x-1) == '\n'</code>
+     */
     private int getBlankLineOffset(int blankLinesNumber, int startOffset) {
       int startLine = myDocument.getLineNumber(startOffset);
       if (startLine <= 0) {
diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java
index a801774..158c559 100644
--- a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java
+++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java
@@ -119,25 +119,17 @@
 
   @SuppressWarnings("AssignmentToForLoopParameter")
   public void updateBlankLines(@NotNull Document document) {
-    int startLine = document.getLineNumber(getStartOffset());
     myBlankLinesBefore = 0;
-    if (startLine <= 0) {
-      return;
-    }
-    
+    int lineFeeds = 0;
     CharSequence text = document.getCharsSequence();
-    int lastLineFeed = document.getLineStartOffset(startLine) - 1;
-    for (int i = lastLineFeed - 1; i >= 0; i--) {
-      i = CharArrayUtil.shiftBackward(text, i, " \t");
-      if (text.charAt(i) == '\n') {
-        ++myBlankLinesBefore;
-      }
-      else {
-        break;
-      }
+    for (int current = getStartOffset() - 1; current >= 0; current--) {
+      current = CharArrayUtil.shiftBackward(text, current, " \t");
+      if (text.charAt(current) == '\n') lineFeeds++;
+      else break;
     }
+    if (lineFeeds > 0) myBlankLinesBefore = lineFeeds - 1;
   }
-  
+
   public void setNext(@Nullable ArrangementEntryWrapper<E> next) {
     myNext = next;
   }
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java
deleted file mode 100644
index 15224f5..0000000
--- a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java
+++ /dev/null
@@ -1,255 +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 com.intellij.psi.impl.cache.impl.id;
-
-import com.intellij.ide.highlighter.HighlighterFactory;
-import com.intellij.lang.Language;
-import com.intellij.lang.LanguageParserDefinitions;
-import com.intellij.lang.ParserDefinition;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
-import com.intellij.openapi.editor.highlighter.EditorHighlighter;
-import com.intellij.openapi.editor.highlighter.HighlighterIterator;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.FileTypes;
-import com.intellij.openapi.fileTypes.LanguageFileType;
-import com.intellij.openapi.fileTypes.StdFileTypes;
-import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.CustomHighlighterTokenType;
-import com.intellij.psi.impl.cache.impl.BaseFilterLexer;
-import com.intellij.psi.impl.cache.CacheUtil;
-import com.intellij.psi.impl.cache.impl.IndexPatternUtil;
-import com.intellij.psi.impl.cache.impl.OccurrenceConsumer;
-import com.intellij.psi.impl.cache.impl.todo.TodoIndexEntry;
-import com.intellij.psi.impl.cache.impl.todo.TodoIndexers;
-import com.intellij.psi.search.IndexPattern;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.tree.TokenSet;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.indexing.DataIndexer;
-import com.intellij.util.indexing.FileBasedIndexImpl;
-import com.intellij.util.indexing.FileContent;
-import com.intellij.util.indexing.SubstitutedFileType;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Author: dmitrylomov
- */
-public abstract class PlatformIdTableBuilding {
-  static final HashMap<FileType, DataIndexer<TodoIndexEntry, Integer, FileContent>> ourTodoIndexers =
-    new HashMap<FileType, DataIndexer<TodoIndexEntry, Integer, FileContent>>();
-  private static final TokenSet ABSTRACT_FILE_COMMENT_TOKENS =
-    TokenSet.create(CustomHighlighterTokenType.LINE_COMMENT, CustomHighlighterTokenType.MULTI_LINE_COMMENT);
-
-  private PlatformIdTableBuilding() {}
-
-  @Nullable
-  public static DataIndexer<TodoIndexEntry, Integer, FileContent> getTodoIndexer(FileType fileType, final VirtualFile virtualFile) {
-    final DataIndexer<TodoIndexEntry, Integer, FileContent> indexer = ourTodoIndexers.get(fileType);
-
-    if (indexer != null) {
-      return indexer;
-    }
-
-    final DataIndexer<TodoIndexEntry, Integer, FileContent> extIndexer;
-    if (fileType instanceof SubstitutedFileType && !((SubstitutedFileType)fileType).isSameFileType()) {
-      SubstitutedFileType sft = (SubstitutedFileType)fileType;
-      extIndexer =
-        new CompositeTodoIndexer(getTodoIndexer(sft.getOriginalFileType(), virtualFile), getTodoIndexer(sft.getFileType(), virtualFile));
-    }
-    else {
-      extIndexer = TodoIndexers.INSTANCE.forFileType(fileType);
-    }
-    if (extIndexer != null) {
-      return extIndexer;
-    }
-
-    if (fileType instanceof LanguageFileType) {
-      final Language lang = ((LanguageFileType)fileType).getLanguage();
-      final ParserDefinition parserDef = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
-      final TokenSet commentTokens = parserDef != null ? parserDef.getCommentTokens() : null;
-      if (commentTokens != null) {
-        return new TokenSetTodoIndexer(commentTokens, virtualFile);
-      }
-    }
-
-    if (fileType instanceof CustomSyntaxTableFileType) {
-      return new TokenSetTodoIndexer(ABSTRACT_FILE_COMMENT_TOKENS, virtualFile);
-    }
-
-    return null;
-  }
-
-  public static boolean checkCanUseCachedEditorHighlighter(final CharSequence chars, final EditorHighlighter editorHighlighter) {
-    assert editorHighlighter instanceof LexerEditorHighlighter;
-    final boolean b = ((LexerEditorHighlighter)editorHighlighter).checkContentIsEqualTo(chars);
-    if (!b) {
-      final Logger logger = Logger.getInstance(IdTableBuilding.class.getName());
-      logger.warn("Unexpected mismatch of editor highlighter content with indexing content");
-    }
-    return b;
-  }
-
-  @Deprecated
-  public static void registerTodoIndexer(FileType fileType, DataIndexer<TodoIndexEntry, Integer, FileContent> indexer) {
-    ourTodoIndexers.put(fileType, indexer);
-  }
-
-  public static boolean isTodoIndexerRegistered(FileType fileType) {
-    return ourTodoIndexers.containsKey(fileType) || TodoIndexers.INSTANCE.forFileType(fileType) != null;
-  }
-
-  private static class CompositeTodoIndexer implements DataIndexer<TodoIndexEntry, Integer, FileContent> {
-
-    private final DataIndexer<TodoIndexEntry, Integer, FileContent>[] indexers;
-
-    public CompositeTodoIndexer(DataIndexer<TodoIndexEntry, Integer, FileContent>... indexers) {
-      this.indexers = indexers;
-    }
-
-    @NotNull
-    @Override
-    public Map<TodoIndexEntry, Integer> map(FileContent inputData) {
-      Map<TodoIndexEntry, Integer> result = ContainerUtil.newTroveMap();
-      for (DataIndexer<TodoIndexEntry, Integer, FileContent> indexer : indexers) {
-        for (Map.Entry<TodoIndexEntry, Integer> entry : indexer.map(inputData).entrySet()) {
-          TodoIndexEntry key = entry.getKey();
-          if (result.containsKey(key)) {
-            result.put(key, result.get(key) + entry.getValue());
-          } else {
-            result.put(key, entry.getValue());
-          }
-        }
-      }
-      return result;
-    }
-  }
-
-  private static class TokenSetTodoIndexer implements DataIndexer<TodoIndexEntry, Integer, FileContent> {
-    @NotNull private final TokenSet myCommentTokens;
-    private final VirtualFile myFile;
-
-    public TokenSetTodoIndexer(@NotNull final TokenSet commentTokens, @NotNull final VirtualFile file) {
-      myCommentTokens = commentTokens;
-      myFile = file;
-    }
-
-    @Override
-    @NotNull
-    public Map<TodoIndexEntry, Integer> map(final FileContent inputData) {
-      if (IndexPatternUtil.getIndexPatternCount() > 0) {
-        final CharSequence chars = inputData.getContentAsText();
-        final OccurrenceConsumer occurrenceConsumer = new OccurrenceConsumer(null, true);
-        EditorHighlighter highlighter;
-
-        final EditorHighlighter editorHighlighter = inputData.getUserData(FileBasedIndexImpl.EDITOR_HIGHLIGHTER);
-        if (editorHighlighter != null && checkCanUseCachedEditorHighlighter(chars, editorHighlighter)) {
-          highlighter = editorHighlighter;
-        }
-        else {
-          highlighter = HighlighterFactory.createHighlighter(null, myFile);
-          highlighter.setText(chars);
-        }
-
-        final int documentLength = chars.length();
-        BaseFilterLexer.TodoScanningData[] todoScanningDatas = null;
-        final HighlighterIterator iterator = highlighter.createIterator(0);
-
-        while (!iterator.atEnd()) {
-          final IElementType token = iterator.getTokenType();
-
-          if (myCommentTokens.contains(token) || CacheUtil.isInComments(token)) {
-            int start = iterator.getStart();
-            if (start >= documentLength) break;
-            int end = iterator.getEnd();
-
-            todoScanningDatas = BaseFilterLexer.advanceTodoItemsCount(
-              chars.subSequence(start, Math.min(end, documentLength)),
-              occurrenceConsumer,
-              todoScanningDatas
-            );
-            if (end > documentLength) break;
-          }
-          iterator.advance();
-        }
-        final Map<TodoIndexEntry, Integer> map = new HashMap<TodoIndexEntry, Integer>();
-        for (IndexPattern pattern : IndexPatternUtil.getIndexPatterns()) {
-          final int count = occurrenceConsumer.getOccurrenceCount(pattern);
-          if (count > 0) {
-            map.put(new TodoIndexEntry(pattern.getPatternString(), pattern.isCaseSensitive()), count);
-          }
-        }
-        return map;
-      }
-      return Collections.emptyMap();
-    }
-  }
-
-  public static class PlainTextTodoIndexer implements DataIndexer<TodoIndexEntry, Integer, FileContent> {
-    @Override
-    @NotNull
-    public Map<TodoIndexEntry, Integer> map(final FileContent inputData) {
-      String chars = inputData.getContentAsText().toString(); // matching strings is faster than HeapCharBuffer
-
-      final IndexPattern[] indexPatterns = IndexPatternUtil.getIndexPatterns();
-      if (indexPatterns.length <= 0) {
-        return Collections.emptyMap();
-      }
-      OccurrenceConsumer occurrenceConsumer = new OccurrenceConsumer(null, true);
-      for (IndexPattern indexPattern : indexPatterns) {
-        Pattern pattern = indexPattern.getPattern();
-        if (pattern != null) {
-          Matcher matcher = pattern.matcher(chars);
-          while (matcher.find()) {
-            if (matcher.start() != matcher.end()) {
-              occurrenceConsumer.incTodoOccurrence(indexPattern);
-            }
-          }
-        }
-      }
-      Map<TodoIndexEntry, Integer> map = new HashMap<TodoIndexEntry, Integer>();
-      for (IndexPattern indexPattern : indexPatterns) {
-        final int count = occurrenceConsumer.getOccurrenceCount(indexPattern);
-        if (count > 0) {
-          map.put(new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), count);
-        }
-      }
-      return map;
-    }
-
-  }
-
-  static {
-    IdTableBuilding.registerIdIndexer(FileTypes.PLAIN_TEXT, new IdTableBuilding.PlainTextIndexer());
-    registerTodoIndexer(FileTypes.PLAIN_TEXT, new PlainTextTodoIndexer());
-
-    IdTableBuilding.registerIdIndexer(StdFileTypes.IDEA_MODULE, null);
-    IdTableBuilding.registerIdIndexer(StdFileTypes.IDEA_WORKSPACE, null);
-    IdTableBuilding.registerIdIndexer(StdFileTypes.IDEA_PROJECT, null);
-
-    registerTodoIndexer(StdFileTypes.IDEA_MODULE, null);
-    registerTodoIndexer(StdFileTypes.IDEA_WORKSPACE, null);
-    registerTodoIndexer(StdFileTypes.IDEA_PROJECT, null);
-  }
-}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java
deleted file mode 100644
index 7ddbf02..0000000
--- a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java
+++ /dev/null
@@ -1,170 +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.psi.impl.cache.impl.todo;
-
-import com.intellij.lang.Language;
-import com.intellij.lang.LanguageParserDefinitions;
-import com.intellij.lang.ParserDefinition;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.LanguageFileType;
-import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
-import com.intellij.openapi.project.ProjectCoreUtil;
-import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding;
-import com.intellij.psi.search.IndexPatternProvider;
-import com.intellij.psi.tree.TokenSet;
-import com.intellij.util.indexing.*;
-import com.intellij.util.io.DataExternalizer;
-import com.intellij.util.io.KeyDescriptor;
-import com.intellij.util.messages.MessageBus;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * @author Eugene Zhuravlev
- *         Date: Jan 20, 2008
- */
-public class TodoIndex extends FileBasedIndexExtension<TodoIndexEntry, Integer> {
-  @NonNls public static final ID<TodoIndexEntry, Integer> NAME = ID.create("TodoIndex");
-
-  public TodoIndex(MessageBus messageBus) {
-    messageBus.connect().subscribe(IndexPatternProvider.INDEX_PATTERNS_CHANGED, new PropertyChangeListener() {
-      @Override
-      public void propertyChange(PropertyChangeEvent evt) {
-        FileBasedIndex.getInstance().requestRebuild(NAME);
-      }
-    });
-  }
-
-  private final KeyDescriptor<TodoIndexEntry> myKeyDescriptor = new KeyDescriptor<TodoIndexEntry>() {
-    @Override
-    public int getHashCode(final TodoIndexEntry value) {
-      return value.hashCode();
-    }
-
-    @Override
-    public boolean isEqual(final TodoIndexEntry val1, final TodoIndexEntry val2) {
-      return val1.equals(val2);
-    }
-
-    @Override
-    public void save(final DataOutput out, final TodoIndexEntry value) throws IOException {
-      out.writeUTF(value.pattern);
-      out.writeBoolean(value.caseSensitive);
-    }
-
-    @Override
-    public TodoIndexEntry read(final DataInput in) throws IOException {
-      final String pattern = in.readUTF();
-      final boolean caseSensitive = in.readBoolean();
-      return new TodoIndexEntry(pattern, caseSensitive);
-    }
-  };
-  
-  private final DataExternalizer<Integer> myValueExternalizer = new DataExternalizer<Integer>() {
-    @Override
-    public void save(final DataOutput out, final Integer value) throws IOException {
-      out.writeInt(value.intValue());
-    }
-
-    @Override
-    public Integer read(final DataInput in) throws IOException {
-      return Integer.valueOf(in.readInt());
-    }
-  };
-
-  private final DataIndexer<TodoIndexEntry, Integer, FileContent> myIndexer = new DataIndexer<TodoIndexEntry, Integer, FileContent>() {
-    @Override
-    @NotNull
-    public Map<TodoIndexEntry,Integer> map(final FileContent inputData) {
-      final VirtualFile file = inputData.getFile();
-      final DataIndexer<TodoIndexEntry, Integer, FileContent> indexer = PlatformIdTableBuilding
-        .getTodoIndexer(inputData.getFileType(), file);
-      if (indexer != null) {
-        return indexer.map(inputData);
-      }
-      return Collections.emptyMap();
-    }
-  };
-  
-  private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() {
-    @Override
-    public boolean acceptInput(final VirtualFile file) {
-      if (!(file.getFileSystem() instanceof LocalFileSystem)) {
-        return false; // do not index TODOs in library sources
-      }
-
-      final FileType fileType = file.getFileType();
-
-      if (fileType instanceof LanguageFileType) {
-        final Language lang = ((LanguageFileType)fileType).getLanguage();
-        final ParserDefinition parserDef = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
-        final TokenSet commentTokens = parserDef != null ? parserDef.getCommentTokens() : null;
-        return commentTokens != null;
-      }
-      
-      return PlatformIdTableBuilding.isTodoIndexerRegistered(fileType) ||
-             fileType instanceof CustomSyntaxTableFileType;
-    }
-  };
-
-  @Override
-  public int getVersion() {
-    return 4;
-  }
-
-  @Override
-  public boolean dependsOnFileContent() {
-    return true;
-  }
-
-  @NotNull
-  @Override
-  public ID<TodoIndexEntry, Integer> getName() {
-    return NAME;
-  }
-
-  @NotNull
-  @Override
-  public DataIndexer<TodoIndexEntry, Integer, FileContent> getIndexer() {
-    return myIndexer;
-  }
-
-  @Override
-  public KeyDescriptor<TodoIndexEntry> getKeyDescriptor() {
-    return myKeyDescriptor;
-  }
-
-  @Override
-  public DataExternalizer<Integer> getValueExternalizer() {
-    return myValueExternalizer;
-  }
-
-  @Override
-  public FileBasedIndex.InputFilter getInputFilter() {
-    return myInputFilter;
-  }
-}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternBuilder.java b/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternBuilder.java
deleted file mode 100644
index 65e8712..0000000
--- a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternBuilder.java
+++ /dev/null
@@ -1,38 +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.psi.impl.search;
-
-import com.intellij.lexer.Lexer;
-import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.tree.TokenSet;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author yole
- */
-public interface IndexPatternBuilder {
-  ExtensionPointName<IndexPatternBuilder> EP_NAME = ExtensionPointName.create("com.intellij.indexPatternBuilder");
-
-  @Nullable
-  Lexer getIndexingLexer(PsiFile file);
-  @Nullable
-  TokenSet getCommentTokenSet(PsiFile file);
-  int getCommentStartDelta(IElementType tokenType);
-  int getCommentEndDelta(IElementType tokenType);
-}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java b/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java
deleted file mode 100644
index 26004ca..0000000
--- a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java
+++ /dev/null
@@ -1,268 +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.psi.impl.search;
-
-import com.intellij.lang.Language;
-import com.intellij.lang.LanguageParserDefinitions;
-import com.intellij.lang.ParserDefinition;
-import com.intellij.lexer.Lexer;
-import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.SyntaxHighlighter;
-import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
-import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
-import com.intellij.psi.impl.cache.TodoCacheManager;
-import com.intellij.psi.search.IndexPattern;
-import com.intellij.psi.search.IndexPatternOccurrence;
-import com.intellij.psi.search.IndexPatternProvider;
-import com.intellij.psi.search.searches.IndexPatternSearch;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.tree.TokenSet;
-import com.intellij.util.Processor;
-import com.intellij.util.QueryExecutor;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.text.CharSequenceSubSequence;
-import gnu.trove.TIntArrayList;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * @author yole
- */
-public class IndexPatternSearcher implements QueryExecutor<IndexPatternOccurrence, IndexPatternSearch.SearchParameters> {
-  @Override
-  public boolean execute(@NotNull final IndexPatternSearch.SearchParameters queryParameters,
-                         @NotNull final Processor<IndexPatternOccurrence> consumer) {
-    final PsiFile file = queryParameters.getFile();
-    VirtualFile virtualFile = file.getVirtualFile();
-    if (file instanceof PsiBinaryFile || file instanceof PsiCompiledElement || virtualFile == null) {
-      return true;
-    }
-
-    final TodoCacheManager cacheManager = TodoCacheManager.SERVICE.getInstance(file.getProject());
-    final IndexPatternProvider patternProvider = queryParameters.getPatternProvider();
-    int count = patternProvider != null
-                ? cacheManager.getTodoCount(virtualFile, patternProvider)
-                : cacheManager.getTodoCount(virtualFile, queryParameters.getPattern());
-    return count == 0 || executeImpl(queryParameters, consumer);
-  }
-
-  protected static boolean executeImpl(IndexPatternSearch.SearchParameters queryParameters,
-                                       Processor<IndexPatternOccurrence> consumer) {
-    final IndexPatternProvider patternProvider = queryParameters.getPatternProvider();
-    final PsiFile file = queryParameters.getFile();
-    TIntArrayList commentStarts = new TIntArrayList();
-    TIntArrayList commentEnds = new TIntArrayList();
-
-    final CharSequence chars = file.getViewProvider().getContents();
-    findCommentTokenRanges(file, chars, queryParameters.getRange(), commentStarts, commentEnds);
-
-    for (int i = 0; i < commentStarts.size(); i++) {
-      int commentStart = commentStarts.get(i);
-      int commentEnd = commentEnds.get(i);
-
-      if (patternProvider != null) {
-        for (final IndexPattern pattern : patternProvider.getIndexPatterns()) {
-          if (!collectPatternMatches(pattern, chars, commentStart, commentEnd, file, queryParameters.getRange(), consumer)) {
-            return false;
-          }
-        }
-      }
-      else {
-        if (!collectPatternMatches(queryParameters.getPattern(), chars, commentStart, commentEnd, file, queryParameters.getRange(),
-                                   consumer)) {
-          return false;
-        }
-      }
-    }
-
-    return true;
-  }
-
-
-  private static final TokenSet COMMENT_TOKENS =
-    TokenSet.create(CustomHighlighterTokenType.LINE_COMMENT, CustomHighlighterTokenType.MULTI_LINE_COMMENT);
-
-  private static void findCommentTokenRanges(final PsiFile file,
-                                             final CharSequence chars,
-                                             final TextRange range,
-                                             final TIntArrayList commentStarts,
-                                             final TIntArrayList commentEnds) {
-    if (file instanceof PsiPlainTextFile) {
-      FileType fType = file.getFileType();
-      if (fType instanceof CustomSyntaxTableFileType) {
-        Lexer lexer = SyntaxHighlighterFactory.getSyntaxHighlighter(fType, file.getProject(), file.getVirtualFile()).getHighlightingLexer();
-        findComments(lexer, chars, range, COMMENT_TOKENS, commentStarts, commentEnds, null);
-      }
-      else {
-        commentStarts.add(0);
-        commentEnds.add(file.getTextLength());
-      }
-    }
-    else {
-      final FileViewProvider viewProvider = file.getViewProvider();
-      final Set<Language> relevantLanguages = viewProvider.getLanguages();
-      for (Language lang : relevantLanguages) {
-        final TIntArrayList commentStartsList = new TIntArrayList();
-        final TIntArrayList commentEndsList = new TIntArrayList();
-
-        final SyntaxHighlighter syntaxHighlighter =
-          SyntaxHighlighterFactory.getSyntaxHighlighter(lang, file.getProject(), file.getVirtualFile());
-        Lexer lexer = syntaxHighlighter.getHighlightingLexer();
-        TokenSet commentTokens = null;
-        IndexPatternBuilder builderForFile = null;
-        for (IndexPatternBuilder builder : Extensions.getExtensions(IndexPatternBuilder.EP_NAME)) {
-          Lexer lexerFromBuilder = builder.getIndexingLexer(file);
-          if (lexerFromBuilder != null) {
-            lexer = lexerFromBuilder;
-            commentTokens = builder.getCommentTokenSet(file);
-            builderForFile = builder;
-          }
-        }
-        if (builderForFile == null) {
-          final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
-          if (parserDefinition != null) {
-            commentTokens = parserDefinition.getCommentTokens();
-          }
-        }
-
-        if (commentTokens != null) {
-          findComments(lexer, chars, range, commentTokens, commentStartsList, commentEndsList, builderForFile);
-          mergeCommentLists(commentStarts, commentEnds, commentStartsList, commentEndsList);
-        }
-      }
-    }
-  }
-
-  private static void mergeCommentLists(TIntArrayList commentStarts,
-                                        TIntArrayList commentEnds,
-                                        TIntArrayList commentStartsList,
-                                        TIntArrayList commentEndsList) {
-    if (commentStarts.isEmpty() && commentEnds.isEmpty()) {
-      commentStarts.add(commentStartsList.toNativeArray());
-      commentEnds.add(commentEndsList.toNativeArray());
-      return;
-    }
-
-    ContainerUtil.mergeSortedArrays(commentStarts, commentEnds, commentStartsList, commentEndsList);
-  }
-
-  private static void findComments(final Lexer lexer,
-                                   final CharSequence chars,
-                                   final TextRange range,
-                                   final TokenSet commentTokens,
-                                   final TIntArrayList commentStarts,
-                                   final TIntArrayList commentEnds,
-                                   final IndexPatternBuilder builderForFile) {
-    for (lexer.start(chars); ; lexer.advance()) {
-      IElementType tokenType = lexer.getTokenType();
-      if (tokenType == null) break;
-
-      if (range != null) {
-        if (lexer.getTokenEnd() <= range.getStartOffset()) continue;
-        if (lexer.getTokenStart() >= range.getEndOffset()) break;
-      }
-
-      boolean isComment = commentTokens.contains(tokenType);
-      if (!isComment) {
-        final Language commentLang = tokenType.getLanguage();
-        final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(commentLang);
-        if (parserDefinition != null) {
-          final TokenSet langCommentTokens = parserDefinition.getCommentTokens();
-          isComment = langCommentTokens.contains(tokenType);
-        }
-      }
-
-      if (isComment) {
-        final int startDelta = builderForFile != null ? builderForFile.getCommentStartDelta(lexer.getTokenType()) : 0;
-        final int endDelta = builderForFile != null ? builderForFile.getCommentEndDelta(lexer.getTokenType()) : 0;
-
-        int start = lexer.getTokenStart() + startDelta;
-        int end = lexer.getTokenEnd() - endDelta;
-        assert start <= end : "Invalid comment range: " +
-                              new TextRange(start, end) +
-                              "; lexer token range=" +
-                              new TextRange(lexer.getTokenStart(), lexer.getTokenEnd()) +
-                              "; delta=" +
-                              new TextRange(startDelta, endDelta) +
-                              "; lexer=" +
-                              lexer +
-                              "; builder=" +
-                              builderForFile +
-                              "; chars length:" +
-                              chars.length();
-        assert end <= chars.length() : "Invalid comment end: " +
-                                       new TextRange(start, end) +
-                                       "; lexer token range=" +
-                                       new TextRange(lexer.getTokenStart(), lexer.getTokenEnd()) +
-                                       "; delta=" +
-                                       new TextRange(startDelta, endDelta) +
-                                       "; lexer=" +
-                                       lexer +
-                                       "; builder=" +
-                                       builderForFile +
-                                       "; chars length:" +
-                                       chars.length();
-        commentStarts.add(start);
-        commentEnds.add(end);
-      }
-    }
-  }
-
-  private static boolean collectPatternMatches(IndexPattern indexPattern,
-                                               CharSequence chars,
-                                               int commentStart,
-                                               int commentEnd,
-                                               PsiFile file,
-                                               TextRange range,
-                                               Processor<IndexPatternOccurrence> consumer) {
-    Pattern pattern = indexPattern.getPattern();
-    if (pattern != null) {
-      ProgressManager.checkCanceled();
-
-      CharSequence input = new CharSequenceSubSequence(chars, commentStart, commentEnd);
-      Matcher matcher = pattern.matcher(input);
-      while (true) {
-        //long time1 = System.currentTimeMillis();
-        boolean found = matcher.find();
-        //long time2 = System.currentTimeMillis();
-        //System.out.println("scanned text of length " + (lexer.getTokenEnd() - lexer.getTokenStart() + " in " + (time2 - time1) + " ms"));
-
-        if (!found) break;
-        int start = matcher.start() + commentStart;
-        int end = matcher.end() + commentStart;
-        if (start != end) {
-          if (range == null || range.getStartOffset() <= start && end <= range.getEndOffset()) {
-            if (!consumer.process(new IndexPatternOccurrenceImpl(file, start, end, indexPattern))) {
-              return false;
-            }
-          }
-        }
-
-        ProgressManager.checkCanceled();
-      }
-    }
-    return true;
-  }
-}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/TodoItemImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/search/TodoItemImpl.java
deleted file mode 100644
index 708a20f..0000000
--- a/platform/lang-impl/src/com/intellij/psi/impl/search/TodoItemImpl.java
+++ /dev/null
@@ -1,71 +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.psi.impl.search;
-
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.search.TodoItem;
-import com.intellij.psi.search.TodoPattern;
-import org.jetbrains.annotations.NotNull;
-
-public class TodoItemImpl implements TodoItem {
-  private final PsiFile myFile;
-  private final int myStartOffset;
-  private final int myEndOffset;
-  private final TodoPattern myPattern;
-
-  public TodoItemImpl(@NotNull PsiFile file, int startOffset, int endOffset, @NotNull TodoPattern pattern) {
-    myFile = file;
-    myStartOffset = startOffset;
-    myEndOffset = endOffset;
-    myPattern = pattern;
-  }
-
-  @NotNull
-  @Override
-  public PsiFile getFile() {
-    return myFile;
-  }
-
-  @NotNull
-  @Override
-  public TextRange getTextRange() {
-    return new TextRange(myStartOffset, myEndOffset);
-  }
-
-  @NotNull
-  @Override
-  public TodoPattern getPattern() {
-    return myPattern;
-  }
-
-  public int hashCode(){
-    return myFile.hashCode()+myStartOffset+myEndOffset+myPattern.hashCode();
-  }
-
-  public boolean equals(Object obj){
-    if(!(obj instanceof TodoItemImpl)){
-      return false;
-    }
-    TodoItemImpl todoItem=(TodoItemImpl)obj;
-    return myFile.equals(todoItem.myFile) &&
-           myStartOffset == todoItem.myStartOffset &&
-           myEndOffset == todoItem.myEndOffset &&
-           myPattern.equals(todoItem.myPattern);
-  }
-}
\ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateBlackAndWhiteLexer.java b/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateBlackAndWhiteLexer.java
index 081e11e..c7d3dce 100644
--- a/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateBlackAndWhiteLexer.java
+++ b/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateBlackAndWhiteLexer.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.
@@ -22,6 +22,7 @@
 import com.intellij.lexer.Lexer;
 import com.intellij.lexer.LexerPosition;
 import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public class TemplateBlackAndWhiteLexer extends Lexer {
@@ -39,11 +40,12 @@
   }
 
   @Override
-  public void start(final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
+  public void start(@NotNull final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
     myBaseLexer.start(buffer, startOffset, endOffset, initialState);
     setupTemplateToken();
   }
 
+  @NotNull
   @Override
   public CharSequence getBufferSequence() {
     return myBaseLexer.getBufferSequence();
@@ -139,13 +141,14 @@
     }
   }
 
+  @NotNull
   @Override
   public LexerPosition getCurrentPosition() {
     return new Position(myTemplateLexer.getCurrentPosition(), myBaseLexer.getCurrentPosition());
   }
 
   @Override
-  public void restore(LexerPosition position) {
+  public void restore(@NotNull LexerPosition position) {
     final Position p = (Position)position;
     myBaseLexer.restore(p.getBasePosition());
     final LexerPosition templatePos = p.getTemplatePosition();
diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleDuplicatesFinder.java b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleDuplicatesFinder.java
index e87dc3c..6c067e5 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleDuplicatesFinder.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleDuplicatesFinder.java
@@ -13,6 +13,7 @@
 import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 
@@ -23,10 +24,12 @@
   private final ArrayList<PsiElement> myPattern;
   private final Set<String> myParameters;
   public static final Key<PsiElement> PARAMETER = Key.create("PARAMETER");
+  private final Collection<String> myOutputVariables;
 
   public SimpleDuplicatesFinder(@NotNull final PsiElement statement1,
                                 @NotNull final PsiElement statement2,
-                                AbstractVariableData[] variableData) {
+                                AbstractVariableData[] variableData, Collection<String> variables) {
+    myOutputVariables = variables;
     myParameters = new HashSet<String>();
     for (AbstractVariableData data : variableData) {
       myParameters.add(data.getOriginalName());
@@ -117,13 +120,17 @@
     return match;
   }
 
-  private static boolean matchPattern(@Nullable final PsiElement pattern,
+  private boolean matchPattern(@Nullable final PsiElement pattern,
                                       @Nullable final PsiElement candidate,
                                       @NotNull final SimpleMatch match) {
     ProgressManager.checkCanceled();
     if (pattern == null || candidate == null) return pattern == candidate;
     final PsiElement[] children1 = PsiEquivalenceUtil.getFilteredChildren(pattern, null, true);
     final PsiElement[] children2 = PsiEquivalenceUtil.getFilteredChildren(candidate, null, true);
+    if (pattern.getUserData(PARAMETER) != null && pattern.getParent().getClass() == candidate.getParent().getClass()) {
+      match.changeParameter(pattern.getText(), candidate.getText());
+      return true;
+    }
     if (children1.length != children2.length) return false;
 
     for (int i = 0; i < children1.length; i++) {
@@ -137,7 +144,13 @@
         match.changeParameter(pattern.getText(), candidate.getText());
         return true;
       }
-      if (!pattern.textMatches(candidate)) return false;
+      if (myOutputVariables.contains(pattern.getText())) {
+        match.changeOutput(candidate.getText());
+        return true;
+      }
+      if (!pattern.textMatches(candidate)) {
+        return false;
+      }
     }
 
     return true;
diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleMatch.java b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleMatch.java
index c1e967e9..623af56 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleMatch.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleMatch.java
@@ -13,6 +13,8 @@
   PsiElement myStartElement;
   PsiElement myEndElement;
   private final Map<String, String> myChangedParameters;
+  private String myChangedOutput;
+
   public SimpleMatch(@NotNull final PsiElement start, @NotNull final PsiElement endElement) {
     myStartElement = start;
     myEndElement = endElement;
@@ -34,4 +36,13 @@
   public void changeParameter(@NotNull final String from, @NotNull final String to) {
     myChangedParameters.put(from, to);
   }
+
+  public void changeOutput(@NotNull final String to) {
+    myChangedOutput = to;
+  }
+
+  public String getChangedOutput() {
+    return myChangedOutput;
+  }
+
 }
diff --git a/platform/lang-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialogBase.java b/platform/lang-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialogBase.java
new file mode 100644
index 0000000..e923abb
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialogBase.java
@@ -0,0 +1,150 @@
+/*
+ * 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.refactoring.memberPullUp;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.classMembers.AbstractMemberInfoStorage;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+import com.intellij.refactoring.classMembers.MemberInfoChange;
+import com.intellij.refactoring.classMembers.MemberInfoModel;
+import com.intellij.refactoring.ui.AbstractMemberSelectionTable;
+import com.intellij.refactoring.ui.MemberSelectionPanelBase;
+import com.intellij.refactoring.ui.RefactoringDialog;
+import com.intellij.usageView.UsageViewUtil;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Max Medvedev
+ */
+public abstract class PullUpDialogBase<Storage extends AbstractMemberInfoStorage<Member, Class, MemberInfo>,
+                              MemberInfo extends MemberInfoBase<Member>,
+                              Member extends PsiElement,
+                              Class extends PsiElement> extends RefactoringDialog {
+  protected MemberSelectionPanelBase<Member, MemberInfo, AbstractMemberSelectionTable<Member, MemberInfo>> myMemberSelectionPanel;
+  protected MemberInfoModel<Member, MemberInfo> myMemberInfoModel;
+  protected final Class myClass;
+  protected final List<Class> mySuperClasses;
+  protected final Storage myMemberInfoStorage;
+  protected List<MemberInfo> myMemberInfos;
+  private JComboBox myClassCombo;
+
+  public PullUpDialogBase(Project project, Class aClass, List<Class> superClasses, Storage memberInfoStorage, String title) {
+    super(project, true);
+    myClass = aClass;
+    mySuperClasses = superClasses;
+    myMemberInfoStorage = memberInfoStorage;
+    myMemberInfos = myMemberInfoStorage.getClassMemberInfos(aClass);
+
+    setTitle(title);
+  }
+
+  @Nullable
+  public Class getSuperClass() {
+    if (myClassCombo != null) {
+      return (Class) myClassCombo.getSelectedItem();
+    }
+    else {
+      return null;
+    }
+  }
+
+  public List<MemberInfo> getSelectedMemberInfos() {
+    ArrayList<MemberInfo> list = new ArrayList<MemberInfo>(myMemberInfos.size());
+    for (MemberInfo info : myMemberInfos) {
+      if (info.isChecked() && myMemberInfoModel.isMemberEnabled(info)) {
+        list.add(info);
+      }
+    }
+    return list;
+  }
+
+  protected JComponent createNorthPanel() {
+    JPanel panel = new JPanel();
+
+    panel.setLayout(new GridBagLayout());
+    GridBagConstraints gbConstraints = new GridBagConstraints();
+
+    gbConstraints.insets = new Insets(4, 0, 4, 8);
+    gbConstraints.weighty = 1;
+    gbConstraints.weightx = 1;
+    gbConstraints.gridy = 0;
+    gbConstraints.gridwidth = GridBagConstraints.REMAINDER;
+    gbConstraints.fill = GridBagConstraints.BOTH;
+    gbConstraints.anchor = GridBagConstraints.WEST;
+    final JLabel classComboLabel = new JLabel();
+    panel.add(classComboLabel, gbConstraints);
+
+    myClassCombo = new JComboBox(mySuperClasses.toArray());
+    initClassCombo(myClassCombo);
+    classComboLabel.setText(RefactoringBundle.message("pull.up.members.to", UsageViewUtil.getLongName(myClass)));
+    classComboLabel.setLabelFor(myClassCombo);
+    final Class preselection = getPreselection();
+    int indexToSelect = 0;
+    if (preselection != null) {
+      indexToSelect = mySuperClasses.indexOf(preselection);
+    }
+    myClassCombo.setSelectedIndex(indexToSelect);
+    myClassCombo.addItemListener(new ItemListener() {
+      public void itemStateChanged(ItemEvent e) {
+        if (e.getStateChange() == ItemEvent.SELECTED) {
+          updateMemberInfo();
+        }
+      }
+    });
+    gbConstraints.gridy++;
+    panel.add(myClassCombo, gbConstraints);
+
+    return panel;
+  }
+
+  protected abstract void initClassCombo(JComboBox classCombo);
+
+  protected abstract Class getPreselection();
+
+  private void updateMemberInfo() {
+    final Class targetClass = (Class) myClassCombo.getSelectedItem();
+    myMemberInfos = myMemberInfoStorage.getIntermediateMemberInfosList(targetClass);
+  }
+
+  protected JComponent createCenterPanel() {
+    JPanel panel = new JPanel(new BorderLayout());
+    myMemberSelectionPanel = new MemberSelectionPanelBase<Member, MemberInfo, AbstractMemberSelectionTable<Member, MemberInfo>>(RefactoringBundle.message("members.to.be.pulled.up"), createMemberSelectionTable(myMemberInfos));
+    myMemberInfoModel = createMemberInfoModel();
+    myMemberInfoModel.memberInfoChanged(new MemberInfoChange<Member, MemberInfo>(myMemberInfos));
+    myMemberSelectionPanel.getTable().setMemberInfoModel(myMemberInfoModel);
+    myMemberSelectionPanel.getTable().addMemberInfoChangeListener(myMemberInfoModel);
+    panel.add(myMemberSelectionPanel, BorderLayout.CENTER);
+
+    addCustomElementsToCentralPanel(panel);
+
+    return panel;
+  }
+
+  protected void addCustomElementsToCentralPanel(JPanel panel) { }
+
+  protected abstract AbstractMemberSelectionTable<Member,MemberInfo> createMemberSelectionTable(List<MemberInfo> infos);
+
+  protected abstract MemberInfoModel<Member, MemberInfo> createMemberInfoModel();
+}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java b/platform/lang-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java
new file mode 100644
index 0000000..af9b30d
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java
@@ -0,0 +1,29 @@
+/*
+ * 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.refactoring.ui;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+
+import javax.swing.*;
+
+/**
+ * Nikolay.Tropin
+ * 8/20/13
+ */
+public abstract class AbstractMemberSelectionPanel<T extends PsiElement, M extends MemberInfoBase<T>> extends JPanel {
+  public abstract AbstractMemberSelectionTable<T, M> getTable();
+}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/ui/MemberSelectionPanelBase.java b/platform/lang-impl/src/com/intellij/refactoring/ui/MemberSelectionPanelBase.java
new file mode 100644
index 0000000..4ac3c97
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/refactoring/ui/MemberSelectionPanelBase.java
@@ -0,0 +1,51 @@
+/*
+ * 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.refactoring.ui;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+import com.intellij.ui.ScrollPaneFactory;
+import com.intellij.ui.SeparatorFactory;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author Max Medvedev
+ */
+public class MemberSelectionPanelBase<Member extends PsiElement,
+                                      MemberInfo extends MemberInfoBase<Member>,
+                                      Table extends AbstractMemberSelectionTable<Member, MemberInfo>> extends AbstractMemberSelectionPanel<Member, MemberInfo> {
+  private final Table myTable;
+
+  /**
+   * @param title if title contains 'm' - it would look and feel as mnemonic
+   */
+  public MemberSelectionPanelBase(String title, Table table) {
+    super();
+    setLayout(new BorderLayout());
+
+    myTable = table;
+    JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable);
+    add(SeparatorFactory.createSeparator(title, myTable), BorderLayout.NORTH);
+    add(scrollPane, BorderLayout.CENTER);
+  }
+
+  public Table getTable() {
+    return myTable;
+  }
+}
+
diff --git a/platform/lang-impl/src/com/intellij/tools/Tool.java b/platform/lang-impl/src/com/intellij/tools/Tool.java
index ab59802..23f4d78 100644
--- a/platform/lang-impl/src/com/intellij/tools/Tool.java
+++ b/platform/lang-impl/src/com/intellij/tools/Tool.java
@@ -19,6 +19,7 @@
 import com.intellij.execution.ExecutionException;
 import com.intellij.execution.RunnerRegistry;
 import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.execution.configurations.PathEnvironmentVariableUtil;
 import com.intellij.execution.executors.DefaultRunExecutor;
 import com.intellij.execution.process.OSProcessHandler;
 import com.intellij.execution.process.ProcessHandler;
@@ -341,6 +342,7 @@
         commandLine.getParametersList().prependAll("-a", exePath);
       }
       else {
+        exePath = PathEnvironmentVariableUtil.findAbsolutePathOnMac(exePath);
         commandLine.setExePath(exePath);
       }
     }
diff --git a/platform/lang-impl/src/com/intellij/ui/popup/PopupPositionManager.java b/platform/lang-impl/src/com/intellij/ui/popup/PopupPositionManager.java
index f2e23ea..f9a43f9 100644
--- a/platform/lang-impl/src/com/intellij/ui/popup/PopupPositionManager.java
+++ b/platform/lang-impl/src/com/intellij/ui/popup/PopupPositionManager.java
@@ -1,3 +1,18 @@
+/*
+ * 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.ui.popup;
 
 import com.intellij.codeInsight.lookup.LookupAdapter;
@@ -18,16 +33,22 @@
 
 import javax.swing.*;
 import java.awt.*;
-import java.util.*;
-import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 
 /**
  * @author pegov
+ * @author Konstantin Bulenkov
  */
 public class PopupPositionManager {
   private PopupPositionManager() {
   }
 
+  public enum Position {
+    TOP, BOTTOM, LEFT, RIGHT
+  }
+
   public static void positionPopupInBestPosition(final JBPopup hint,
                                                  @Nullable final Editor editor,
                                                  @Nullable DataContext dataContext) {
@@ -113,7 +134,7 @@
     }
   }
 
-  private static class PositionAdjuster {
+  public static class PositionAdjuster {
     private static final int GAP = 5;
 
     private final Component myRelativeTo;
@@ -157,32 +178,25 @@
      * @param popup
      */
     public void adjust(final JBPopup popup) {
+      adjust(popup, Position.RIGHT, Position.LEFT, Position.TOP, Position.BOTTOM);
+    }
+
+    public void adjust(final JBPopup popup, Position... traversalPolicy) {
       final Dimension d = getPopupSize(popup);
 
       Rectangle popupRect = null;
-      Rectangle r = positionRight(d);
-      if (myScreenRect.contains(r)) {
-        popupRect = r;
-      }
+      Rectangle r = null;
 
-      if (popupRect == null) {
-        r = positionLeft(d);
-        if (myScreenRect.contains(r)) {
-          popupRect = r;
+      for (Position position : traversalPolicy) {
+        switch (position) {
+          case TOP:    r = positionAbove(d); break;
+          case BOTTOM: r = positionUnder(d); break;
+          case LEFT:   r = positionLeft(d);  break;
+          case RIGHT:  r = positionRight(d); break;
         }
-      }
-
-      if (popupRect == null) {
-        r = positionAbove(d);
         if (myScreenRect.contains(r)) {
           popupRect = r;
-        }
-      }
-
-      if (popupRect == null) {
-        r = positionUnder(d);
-        if (myScreenRect.contains(r)) {
-          popupRect = r;
+          break;
         }
       }
 
@@ -197,7 +211,7 @@
       }
       else {
         // ok, popup does not fit, will try to resize it
-        final List<Rectangle> boxes = new ArrayList<Rectangle>();
+        final java.util.List<Rectangle> boxes = new ArrayList<Rectangle>();
         // right
         boxes.add(crop(myScreenRect, new Rectangle(myRelativeOnScreen.x + myRelativeTo.getWidth() + GAP, myRelativeOnScreen.y,
                                                    myScreenRect.width, myScreenRect.height)));
diff --git a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailController.java b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailController.java
index 235bda0..d8325bb 100644
--- a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailController.java
+++ b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailController.java
@@ -19,16 +19,13 @@
 import com.intellij.util.Alarm;
 
 import javax.swing.*;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-import javax.swing.event.TreeSelectionEvent;
-import javax.swing.event.TreeSelectionListener;
 import java.io.File;
 
-public class DetailController implements TreeSelectionListener, ListSelectionListener {
+public class DetailController {
   private final MasterController myMasterController;
   private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
   private DetailView myDetailView;
+  private ItemWrapper mySelectedItem;
 
   public DetailController(MasterController myMasterController) {
     this.myMasterController = myMasterController;
@@ -61,7 +58,11 @@
     return myMasterController.getPathLabel();
   }
 
-  void doUpdateDetailView() {
+  public ItemWrapper getSelectedItem() {
+    return mySelectedItem;
+  }
+
+  public void doUpdateDetailView(boolean now) {
     final Object[] values = myMasterController.getSelectedItems();
     ItemWrapper wrapper = null;
     if (values != null && values.length == 1) {
@@ -71,35 +72,30 @@
     else {
       getLabel().setText(" ");
     }
-    final ItemWrapper wrapper1 = wrapper;
+    mySelectedItem = wrapper;
     myUpdateAlarm.cancelAllRequests();
-    myUpdateAlarm.addRequest(new Runnable() {
-      @Override
-      public void run() {
-        doUpdateDetailViewWithItem(wrapper1);
-      }
-    }, 100);
+    if (now) {
+      doUpdateDetailViewWithItem(mySelectedItem);
+    }
+    else {
+      myUpdateAlarm.addRequest(new Runnable() {
+        @Override
+        public void run() {
+          doUpdateDetailViewWithItem(mySelectedItem);
+          myUpdateAlarm.cancelAllRequests();
+        }
+      }, 100);
+    }
   }
 
-  public void selectionChanged() {
-    SwingUtilities.invokeLater(new Runnable() {
-      @Override
-      public void run() {
-        doUpdateDetailView();
-      }
-    });
-  }
-
-  public void setTree(final JTree tree) {
-    tree.getSelectionModel().addTreeSelectionListener(this);
+  public void updateDetailView() {
+    doUpdateDetailView(false);
   }
 
   public void setList(final JBList list) {
     final ListSelectionModel listSelectionModel = list.getSelectionModel();
     listSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 
-    listSelectionModel.addListSelectionListener(this);
-
     if (list.getModel().getSize() == 0) {
       list.clearSelection();
     }
@@ -108,14 +104,4 @@
   public void setDetailView(DetailView detailView) {
     myDetailView = detailView;
   }
-
-  @Override
-  public void valueChanged(TreeSelectionEvent event) {
-    selectionChanged();
-  }
-
-  @Override
-  public void valueChanged(ListSelectionEvent event) {
-    selectionChanged();
-  }
 }
\ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java b/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java
index 8cd75d8..c3f71bd 100644
--- a/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java
+++ b/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java
@@ -30,6 +30,8 @@
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
 import java.awt.*;
 import java.awt.event.*;
 
@@ -348,15 +350,15 @@
     return this;
   }
 
-  public MasterDetailPopupBuilder setTree(final JTree tree) {
-    setChooser(tree);
-    myDetailController.setTree(tree);
-    return this;
-  }
-
   public MasterDetailPopupBuilder setList(final JBList list) {
     setChooser(list);
     myDetailController.setList(list);
+    list.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+      @Override
+      public void valueChanged(ListSelectionEvent event) {
+        myDetailController.updateDetailView();
+      }
+    });
     return this;
   }
 
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
index eb1a7e8..436fdb9 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
@@ -30,7 +30,6 @@
 import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.highlighter.EditorHighlighter;
 import com.intellij.openapi.editor.impl.EditorHighlighterCache;
 import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -57,6 +56,7 @@
 import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.PsiDocumentTransactionListener;
+import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding;
 import com.intellij.psi.impl.source.PsiFileImpl;
 import com.intellij.psi.search.EverythingGlobalScope;
 import com.intellij.psi.search.GlobalSearchScope;
@@ -1551,7 +1551,7 @@
         initFileContent(newFc, project, dominantContentFile);
 
         if (content instanceof AuthenticContent) {
-          newFc.putUserData(EDITOR_HIGHLIGHTER, EditorHighlighterCache.getEditorHighlighterForCachesBuilding(document));
+          newFc.putUserData(PlatformIdTableBuilding.EDITOR_HIGHLIGHTER, EditorHighlighterCache.getEditorHighlighterForCachesBuilding(document));
         }
 
         final int inputId = Math.abs(getFileId(vFile));
@@ -1571,8 +1571,6 @@
 
   private final TaskQueue myContentlessIndicesUpdateQueue = new TaskQueue(10000);
 
-  public static final Key<EditorHighlighter> EDITOR_HIGHLIGHTER = new Key<EditorHighlighter>("Editor");
-
   @Nullable
   private PsiFile findDominantPsiForDocument(@NotNull Document document, @Nullable Project project) {
     synchronized (myTransactionMap) {
diff --git a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java
index 7ad2905..7e879f4 100644
--- a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java
+++ b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java
@@ -71,7 +71,7 @@
    * @param fileBaseName file base name
    * @return {@code File} instance or null if not found
    */
-  public static File findInOriginalPath(@NotNull String fileBaseName) {
+  private static File findInOriginalPath(@NotNull String fileBaseName) {
     String originalPath;
     if (SystemInfo.isMac) {
       originalPath = System.getenv(PATH_ENV_VAR_NAME);
@@ -135,4 +135,30 @@
     }
     return result;
   }
+
+  /**
+   * Finds the absolute path of an executable file in PATH by the given relative path.
+   * This method makes sense for Mac only, because other OSs pass correct environment variables to IDE process
+   * letting {@link ProcessBuilder#start} sees correct PATH environment variable.
+   *
+   * @param exePath String relative path (or just a base name)
+   * @return the absolute path if the executable file found, and the given {@code exePath} otherwise
+   */
+  @NotNull
+  public static String findAbsolutePathOnMac(@NotNull String exePath) {
+    if (SystemInfo.isMac) {
+      if (!exePath.contains(File.separator)) {
+        File originalResolvedExeFile = findInOriginalPath(exePath);
+        // don't modify exePath if the absolute path can be found in the original PATH
+        if (originalResolvedExeFile == null) {
+          File resolvedExeFile = findInPath(exePath);
+          if (resolvedExeFile != null) {
+            exePath = resolvedExeFile.getAbsolutePath();
+          }
+        }
+      }
+    }
+    return exePath;
+  }
+
 }
diff --git a/platform/platform-api/src/com/intellij/execution/process/ColoredOutputTypeRegistry.java b/platform/platform-api/src/com/intellij/execution/process/ColoredOutputTypeRegistry.java
index 85eea8a..7fff038 100644
--- a/platform/platform-api/src/com/intellij/execution/process/ColoredOutputTypeRegistry.java
+++ b/platform/platform-api/src/com/intellij/execution/process/ColoredOutputTypeRegistry.java
@@ -7,7 +7,6 @@
 import com.intellij.openapi.editor.markup.EffectType;
 import com.intellij.openapi.editor.markup.TextAttributes;
 import com.intellij.openapi.util.Key;
-import com.intellij.ui.JBColor;
 import org.jetbrains.annotations.NonNls;
 
 import java.awt.*;
@@ -24,10 +23,24 @@
 
   private final Map<String, Key> myRegisteredKeys = new HashMap<String, Key>();
 
-  private final TextAttributesKey[] myAnsiColorKeys = new TextAttributesKey[] {
-    ConsoleViewContentType.NORMAL_OUTPUT_KEY,
-    ConsoleHighlighter.RED, ConsoleHighlighter.GREEN, ConsoleHighlighter.YELLOW, ConsoleHighlighter.BLUE,
-    ConsoleHighlighter.MAGENTA, ConsoleHighlighter.CYAN
+  private static final TextAttributesKey[] myAnsiColorKeys = new TextAttributesKey[]{
+    ConsoleHighlighter.BLACK,
+    ConsoleHighlighter.RED,
+    ConsoleHighlighter.GREEN,
+    ConsoleHighlighter.YELLOW,
+    ConsoleHighlighter.BLUE,
+    ConsoleHighlighter.MAGENTA,
+    ConsoleHighlighter.CYAN,
+    ConsoleHighlighter.GRAY,
+
+    ConsoleHighlighter.DARKGRAY,
+    ConsoleHighlighter.RED_BRIGHT,
+    ConsoleHighlighter.GREEN_BRIGHT,
+    ConsoleHighlighter.YELLOW_BRIGHT,
+    ConsoleHighlighter.BLUE_BRIGHT,
+    ConsoleHighlighter.MAGENTA_BRIGHT,
+    ConsoleHighlighter.CYAN_BRIGHT,
+    ConsoleHighlighter.WHITE,
   };
 
   /*
@@ -73,7 +86,7 @@
       attribute = attribute.substring(1);
     }
     if (attribute.endsWith("m")) {
-      attribute = attribute.substring(0, attribute.length()-1);
+      attribute = attribute.substring(0, attribute.length() - 1);
     }
     if (attribute.equals("0")) {
       return ProcessOutputTypes.STDOUT;
@@ -88,25 +101,43 @@
       catch (NumberFormatException e) {
         continue;
       }
-      if (value == 4) {
+      if (value == 1) {
+        attrs.setFontType(Font.BOLD);
+      }
+      else if (value == 4) {
         attrs.setEffectType(EffectType.LINE_UNDERSCORE);
       }
-      else if (value == 1) {
-        attrs.setFontType(Font.BOLD);
+      else if (value == 22) {
+        attrs.setFontType(Font.PLAIN);
+      }
+      else if (value == 24) {  //not underlined
+        attrs.setEffectType(null);
       }
       else if (value >= 30 && value <= 37) {
         attrs.setForegroundColor(getAnsiColor(value - 30));
       }
+      else if (value == 38) {
+        //TODO: 256 colors foreground
+      }
+      else if (value == 39) {
+        attrs.setForegroundColor(getColorByKey(ConsoleViewContentType.NORMAL_OUTPUT_KEY));
+      }
       else if (value >= 40 && value <= 47) {
         attrs.setBackgroundColor(getAnsiColor(value - 40));
       }
-      else if (value == 90) {
-        // black, high intensity
-        attrs.setForegroundColor(EditorColorsManager.getInstance().getGlobalScheme().getAttributes(ConsoleHighlighter.GRAY).getForegroundColor());
+      else if (value == 48) {
+        //TODO: 256 colors background
       }
-      else if (value >= 91 && value < 96) {
-        // TODO separate colors for high intensity?
-        attrs.setForegroundColor(EditorColorsManager.getInstance().getGlobalScheme().getAttributes(myAnsiColorKeys [value-90]).getForegroundColor());
+      else if (value == 49) {
+        attrs.setBackgroundColor(getColorByKey(ConsoleViewContentType.NORMAL_OUTPUT_KEY));
+      }
+      else if (value >= 90 && value <= 97) {
+        attrs.setForegroundColor(
+          getAnsiColor(value - 82));
+      }
+      else if (value >= 100 && value <= 107) {
+        attrs.setBackgroundColor(
+          getAnsiColor(value - 92));
       }
     }
     if (attrs.getEffectType() == EffectType.LINE_UNDERSCORE) {
@@ -119,10 +150,18 @@
     return newKey;
   }
 
-  private Color getAnsiColor(final int value) {
-    if (value == 7) {
-      return JBColor.WHITE;
+  private static Color getAnsiColor(final int value) {
+    return getColorByKey(getAnsiColorKey(value));
+  }
+
+  private static Color getColorByKey(TextAttributesKey colorKey) {
+    return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(colorKey).getForegroundColor();
+  }
+
+  public static TextAttributesKey getAnsiColorKey(int value) {
+    if (value >= 16) {
+      return ConsoleViewContentType.NORMAL_OUTPUT_KEY;
     }
-    return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(myAnsiColorKeys[value]).getForegroundColor();
+    return myAnsiColorKeys[value];
   }
 }
diff --git a/platform/platform-api/src/com/intellij/execution/process/ConsoleHighlighter.java b/platform/platform-api/src/com/intellij/execution/process/ConsoleHighlighter.java
index 9f32da4..014e218 100644
--- a/platform/platform-api/src/com/intellij/execution/process/ConsoleHighlighter.java
+++ b/platform/platform-api/src/com/intellij/execution/process/ConsoleHighlighter.java
@@ -15,52 +15,64 @@
  */
 package com.intellij.execution.process;
 
-import com.intellij.openapi.editor.HighlighterColors;
+import com.intellij.execution.ui.ConsoleViewContentType;
 import com.intellij.openapi.editor.colors.TextAttributesKey;
-import com.intellij.openapi.editor.markup.TextAttributes;
-import com.intellij.ui.JBColor;
-import com.intellij.util.ui.PlatformColors;
 import org.jetbrains.annotations.NonNls;
 
-import java.awt.*;
-
 /**
  * @author oleg
  */
 public class ConsoleHighlighter {
+  @NonNls static final String BLACK_ID = "CONSOLE_BLACK_OUTPUT";
   @NonNls static final String RED_ID = "CONSOLE_RED_OUTPUT";
   @NonNls static final String GREEN_ID = "CONSOLE_GREEN_OUTPUT";
   @NonNls static final String YELLOW_ID = "CONSOLE_YELLOW_OUTPUT";
   @NonNls static final String BLUE_ID = "CONSOLE_BLUE_OUTPUT";
   @NonNls static final String MAGENTA_ID = "CONSOLE_MAGENTA_OUTPUT";
   @NonNls static final String CYAN_ID = "CONSOLE_CYAN_OUTPUT";
-  @NonNls static final String GRAY_ID = "CONSOLE_GRAY_OUTPUT";
+  @NonNls static final String GRAY_ID = "CONSOLE_GRAY_OUTPUT"; //ISO white
 
-  public static final TextAttributes RED_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
-  public static final TextAttributes GREEN_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
-  public static final TextAttributes YELLOW_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
-  public static final TextAttributes BLUE_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
-  public static final TextAttributes MAGENTA_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
-  public static final TextAttributes CYAN_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
-  public static final TextAttributes GRAY_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
 
-  static {
-    RED_DEFAULT_ATTRS.setForegroundColor(JBColor.RED);
-    GREEN_DEFAULT_ATTRS.setForegroundColor(new Color(0, 128, 0));
-    YELLOW_DEFAULT_ATTRS.setForegroundColor(new Color(255, 204, 0));
-    BLUE_DEFAULT_ATTRS.setForegroundColor(PlatformColors.BLUE);
-    MAGENTA_DEFAULT_ATTRS.setForegroundColor(JBColor.MAGENTA);
-    CYAN_DEFAULT_ATTRS.setForegroundColor(JBColor.CYAN.darker());
-    GRAY_DEFAULT_ATTRS.setForegroundColor(JBColor.GRAY.darker());
-  }
+  @NonNls static final String DARKGRAY_ID = "CONSOLE_DARKGRAY_OUTPUT";
+  @NonNls static final String RED_BRIGHT_ID = "CONSOLE_RED_BRIGHT_OUTPUT";
+  @NonNls static final String GREEN_BRIGHT_ID = "CONSOLE_GREEN_BRIGHT_OUTPUT";
+  @NonNls static final String YELLOW_BRIGHT_ID = "CONSOLE_YELLOW_BRIGHT_OUTPUT";
+  @NonNls static final String BLUE_BRIGHT_ID = "CONSOLE_BLUE_BRIGHT_OUTPUT";
+  @NonNls static final String MAGENTA_BRIGHT_ID = "CONSOLE_MAGENTA_BRIGHT_OUTPUT";
+  @NonNls static final String CYAN_BRIGHT_ID = "CONSOLE_CYAN_BRIGHT_OUTPUT";
+  @NonNls static final String WHITE_ID = "CONSOLE_WHITE_OUTPUT"; //ISO bright white
 
-  public static final TextAttributesKey RED = TextAttributesKey.createTextAttributesKey(RED_ID, RED_DEFAULT_ATTRS);
-  public static final TextAttributesKey GREEN = TextAttributesKey.createTextAttributesKey(GREEN_ID, GREEN_DEFAULT_ATTRS);
-  public static final TextAttributesKey YELLOW = TextAttributesKey.createTextAttributesKey(YELLOW_ID, YELLOW_DEFAULT_ATTRS);
-  public static final TextAttributesKey BLUE = TextAttributesKey.createTextAttributesKey(BLUE_ID, BLUE_DEFAULT_ATTRS);
-  public static final TextAttributesKey MAGENTA = TextAttributesKey.createTextAttributesKey(MAGENTA_ID, MAGENTA_DEFAULT_ATTRS);
-  public static final TextAttributesKey CYAN = TextAttributesKey.createTextAttributesKey(CYAN_ID, CYAN_DEFAULT_ATTRS);
-  public static final TextAttributesKey GRAY = TextAttributesKey.createTextAttributesKey(GRAY_ID, GRAY_DEFAULT_ATTRS);
+  public static final TextAttributesKey BLACK =
+    TextAttributesKey.createTextAttributesKey(BLACK_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+  public static final TextAttributesKey RED = TextAttributesKey.createTextAttributesKey(RED_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+  public static final TextAttributesKey GREEN =
+    TextAttributesKey.createTextAttributesKey(GREEN_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+  public static final TextAttributesKey YELLOW =
+    TextAttributesKey.createTextAttributesKey(YELLOW_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+  public static final TextAttributesKey BLUE = TextAttributesKey.createTextAttributesKey(BLUE_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+  public static final TextAttributesKey MAGENTA =
+    TextAttributesKey.createTextAttributesKey(MAGENTA_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+  public static final TextAttributesKey CYAN = TextAttributesKey.createTextAttributesKey(CYAN_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+  public static final TextAttributesKey GRAY = TextAttributesKey.createTextAttributesKey(GRAY_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+
+
+  public static final TextAttributesKey DARKGRAY =
+    TextAttributesKey.createTextAttributesKey(DARKGRAY_ID, GRAY);
+  public static final TextAttributesKey RED_BRIGHT =
+    TextAttributesKey.createTextAttributesKey(RED_BRIGHT_ID, RED);
+  public static final TextAttributesKey GREEN_BRIGHT =
+    TextAttributesKey.createTextAttributesKey(GREEN_BRIGHT_ID, GREEN);
+  public static final TextAttributesKey YELLOW_BRIGHT =
+    TextAttributesKey.createTextAttributesKey(YELLOW_BRIGHT_ID, YELLOW);
+  public static final TextAttributesKey BLUE_BRIGHT =
+    TextAttributesKey.createTextAttributesKey(BLUE_BRIGHT_ID, BLUE);
+  public static final TextAttributesKey MAGENTA_BRIGHT =
+    TextAttributesKey.createTextAttributesKey(MAGENTA_BRIGHT_ID, MAGENTA);
+  public static final TextAttributesKey CYAN_BRIGHT =
+    TextAttributesKey.createTextAttributesKey(CYAN_BRIGHT_ID, CYAN);
+  public static final TextAttributesKey WHITE =
+    TextAttributesKey.createTextAttributesKey(WHITE_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+
 
   private ConsoleHighlighter() {
   }
diff --git a/platform/platform-api/src/com/intellij/execution/util/ExecUtil.java b/platform/platform-api/src/com/intellij/execution/util/ExecUtil.java
index 5047c58..dc27fa2 100644
--- a/platform/platform-api/src/com/intellij/execution/util/ExecUtil.java
+++ b/platform/platform-api/src/com/intellij/execution/util/ExecUtil.java
@@ -23,14 +23,13 @@
 import com.intellij.openapi.util.NotNullLazyValue;
 import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.Function;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.io.*;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 public class ExecUtil {
   private static final NotNullLazyValue<Boolean> hasGkSudo = new NotNullLazyValue<Boolean>() {
@@ -167,18 +166,93 @@
     return null;
   }
 
+  /**
+   * Run the command with superuser privileges using safe escaping and quoting.
+   *
+   * No shell substitutions, input/output redirects, etc. in the command are applied.
+   *
+   * @param command the command and its arguments, can contain any characters
+   * @param prompt the prompt string for the users
+   * @param workDir working directory
+   * @return the results of running the process
+   */
   @NotNull
-  public static ProcessOutput sudoAndGetOutput(@NotNull final String scriptPath,
-                                               @NotNull final String prompt) throws IOException, ExecutionException {
+  public static ProcessOutput sudoAndGetOutput(@NotNull List<String> command,
+                                               @NotNull String prompt,
+                                               @Nullable String workDir) throws IOException, ExecutionException {
+    if (SystemInfo.isMac) {
+      final String escapedCommandLine = StringUtil.join(command, new Function<String, String>() {
+        @Override
+        public String fun(String s) {
+          return escapeAppleScriptArgument(s);
+        }
+      }, " & \" \" & ");
+      final String escapedScript = "do shell script " + escapedCommandLine + " with administrator privileges";
+      return execAndGetOutput(Arrays.asList(getOsascriptPath(), "-e", escapedScript), workDir);
+    }
+    else if ("root".equals(System.getenv("USER"))) {
+      return execAndGetOutput(command, workDir);
+    }
+    else if (hasGkSudo.getValue()) {
+      final List<String> sudoCommand = new ArrayList<String>();
+      sudoCommand.add("gksudo");
+      sudoCommand.add("--message");
+      sudoCommand.add(prompt);
+      sudoCommand.add("--");
+      sudoCommand.addAll(command);
+      return execAndGetOutput(sudoCommand, workDir);
+    }
+    else if (hasKdeSudo.getValue()) {
+      final List<String> sudoCommand = new ArrayList<String>();
+      sudoCommand.add("kdesudo");
+      sudoCommand.add("--comment");
+      sudoCommand.add(prompt);
+      sudoCommand.add("--");
+      sudoCommand.addAll(command);
+      return execAndGetOutput(sudoCommand, workDir);
+    }
+    else if (SystemInfo.isUnix && hasTerminalApp()) {
+      final String escapedCommandLine = StringUtil.join(command, new Function<String, String>() {
+        @Override
+        public String fun(String s) {
+          return escapeUnixShellArgument(s);
+        }
+      }, " ");
+      final File script = createTempExecutableScript(
+        "sudo", ".sh",
+        "#!/bin/sh\n" +
+        "echo " + escapeUnixShellArgument(prompt) + "\n" +
+        "echo\n" +
+        "sudo -- " + escapedCommandLine + "\n" +
+        "STATUS=$?\n" +
+        "echo\n" +
+        "read -p \"Press Enter to close this window...\" TEMP\n" +
+        "exit $STATUS\n");
+      return execAndGetOutput(getTerminalCommand("Install", script.getAbsolutePath()), workDir);
+    }
+    throw new UnsupportedSystemException();
+  }
+
+  @NotNull
+  private static String escapeAppleScriptArgument(@NotNull String arg) {
+    return "quoted form of \"" + arg.replace("\"", "\\\"") + "\"";
+  }
+
+  @NotNull
+  private static String escapeUnixShellArgument(@NotNull String arg) {
+    return "'" + arg.replace("'", "\\'") + "'";
+  }
+
+  /** @deprecated relies on platform-dependent escaping, use {@link #sudoAndGetOutput(List, String, String)} instead (to remove in IDEA 14) */
+  @SuppressWarnings({"UnusedDeclaration", "deprecation"})
+  public static ProcessOutput sudoAndGetOutput(@NotNull String scriptPath, @NotNull String prompt) throws IOException, ExecutionException {
     return sudoAndGetOutput(scriptPath, prompt, null);
   }
 
-  /**
-   * @param scriptPath is already escaped file path
-   */
+  /** @deprecated relies on platform-dependent escaping, use {@link #sudoAndGetOutput(List, String, String)} instead (to remove in IDEA 14) */
   @NotNull
-  public static ProcessOutput sudoAndGetOutput(@NotNull final String scriptPath,
-                                               @NotNull final String prompt,
+  public static ProcessOutput sudoAndGetOutput(@NotNull String scriptPath,
+                                               @NotNull String prompt,
                                                @Nullable String workDir) throws IOException, ExecutionException {
     if (SystemInfo.isMac) {
       final String script = "do shell script \"" + scriptPath + "\" with administrator privileges";
@@ -209,9 +283,10 @@
     throw new UnsupportedSystemException();
   }
 
-  public static int sudoAndGetResult(@NotNull final String scriptPath,
-                                     @NotNull final String prompt) throws IOException, ExecutionException {
-    return sudoAndGetOutput(scriptPath, prompt).getExitCode();
+  /** @deprecated relies on platform-dependent escaping, use {@link #sudoAndGetOutput(List, String, String)} instead (to remove in IDEA 14) */
+  @SuppressWarnings({"UnusedDeclaration", "deprecation"})
+  public static int sudoAndGetResult(@NotNull String scriptPath, @NotNull String prompt) throws IOException, ExecutionException {
+    return sudoAndGetOutput(scriptPath, prompt, null).getExitCode();
   }
 
   public static boolean hasTerminalApp() {
diff --git a/platform/platform-api/src/com/intellij/ide/highlighter/HighlighterFactory.java b/platform/platform-api/src/com/intellij/ide/highlighter/HighlighterFactory.java
deleted file mode 100644
index 8371c4a..0000000
--- a/platform/platform-api/src/com/intellij/ide/highlighter/HighlighterFactory.java
+++ /dev/null
@@ -1,57 +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.ide.highlighter;
-
-import com.intellij.openapi.editor.colors.EditorColorsScheme;
-import com.intellij.openapi.editor.highlighter.EditorHighlighter;
-import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.SyntaxHighlighter;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-
-public class HighlighterFactory {
-  private HighlighterFactory() {}
-
-  public static EditorHighlighter createHighlighter(SyntaxHighlighter highlighter, EditorColorsScheme settings) {
-    return EditorHighlighterFactory.getInstance().createEditorHighlighter(highlighter, settings);
-  }
-
-  public static EditorHighlighter createHighlighter(Project project, String fileName) {
-    return EditorHighlighterFactory.getInstance().createEditorHighlighter(project, fileName);
-  }
-
-  public static EditorHighlighter createHighlighter(Project project, VirtualFile file) {
-    return EditorHighlighterFactory.getInstance().createEditorHighlighter(project, file);
-  }
-
-  public static EditorHighlighter createHighlighter(Project project, FileType fileType) {
-    return EditorHighlighterFactory.getInstance().createEditorHighlighter(project, fileType);
-  }
-
-  public static EditorHighlighter createHighlighter(EditorColorsScheme settings, String fileName, Project project) {
-    return EditorHighlighterFactory.getInstance().createEditorHighlighter(settings, fileName, project);
-  }
-
-  public static EditorHighlighter createHighlighter(FileType fileType, EditorColorsScheme settings, Project project) {
-    return EditorHighlighterFactory.getInstance().createEditorHighlighter(fileType, settings, project);
-  }
-
-  public static EditorHighlighter createHighlighter(@NotNull VirtualFile vFile, EditorColorsScheme settings, Project project) {
-    return EditorHighlighterFactory.getInstance().createEditorHighlighter(vFile, settings, project);
-  }
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/ide/highlighter/WorkspaceFileType.java b/platform/platform-api/src/com/intellij/ide/highlighter/WorkspaceFileType.java
index d2d44ef..0b30e86 100644
--- a/platform/platform-api/src/com/intellij/ide/highlighter/WorkspaceFileType.java
+++ b/platform/platform-api/src/com/intellij/ide/highlighter/WorkspaceFileType.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.
@@ -29,33 +29,40 @@
   @NonNls public static final String DEFAULT_EXTENSION = "iws";
   @NonNls public static final String DOT_DEFAULT_EXTENSION = "." + DEFAULT_EXTENSION;
 
+  @Override
   @NotNull
   public String getName() {
     return "IDEA_WORKSPACE";
   }
 
+  @Override
   @NotNull
   public String getDescription() {
     return IdeBundle.message("filetype.description.idea.workspace");
   }
 
+  @Override
   @NotNull
   public String getDefaultExtension() {
     return DEFAULT_EXTENSION;
   }
 
+  @Override
   public Icon getIcon() {
     return AllIcons.Nodes.IdeaWorkspace;
   }
 
+  @Override
   public boolean isBinary() {
     return false;
   }
 
+  @Override
   public boolean isReadOnly() {
     return true;
   }
 
+  @Override
   public String getCharset(@NotNull VirtualFile file, final byte[] content) {
     return CharsetToolkit.UTF8;
   }
diff --git a/platform/platform-api/src/com/intellij/ide/util/PropertiesComponent.java b/platform/platform-api/src/com/intellij/ide/util/PropertiesComponent.java
index 92f1e6b..f3b883d 100644
--- a/platform/platform-api/src/com/intellij/ide/util/PropertiesComponent.java
+++ b/platform/platform-api/src/com/intellij/ide/util/PropertiesComponent.java
@@ -35,6 +35,11 @@
 
   public abstract void setValue(@NonNls String name, String value);
 
+  /**
+   * Set value or unset if equals to default value
+   */
+  public abstract void setValue(@NotNull String name, @NotNull String value, @NotNull String defaultValue);
+
   public abstract String[] getValues(@NonNls String name);
 
   public abstract void setValues(@NonNls String name, String[] values);
diff --git a/platform/platform-api/src/com/intellij/ide/wizard/AbstractWizard.java b/platform/platform-api/src/com/intellij/ide/wizard/AbstractWizard.java
index 6288409..7c379da 100644
--- a/platform/platform-api/src/com/intellij/ide/wizard/AbstractWizard.java
+++ b/platform/platform-api/src/com/intellij/ide/wizard/AbstractWizard.java
@@ -299,7 +299,11 @@
   }
 
   public void addStep(@NotNull final T step) {
-    mySteps.add(step);
+    addStep(step, mySteps.size());
+  }
+
+  public void addStep(@NotNull final T step, int index) {
+    mySteps.add(index, step);
 
     if (step instanceof StepAdapter) {
       ((StepAdapter)step).registerStepListener(myStepListener);
@@ -451,7 +455,7 @@
   @Nullable
   @Override
   public JComponent getPreferredFocusedComponent() {
-    JComponent component = mySteps.get(myCurrentStep).getPreferredFocusedComponent();
+    JComponent component = getCurrentStepObject().getPreferredFocusedComponent();
     return component == null ? super.getPreferredFocusedComponent() : component;
   }
 
diff --git a/platform/platform-api/src/com/intellij/lexer/DummyLexer.java b/platform/platform-api/src/com/intellij/lexer/DummyLexer.java
deleted file mode 100644
index e20f4e5..0000000
--- a/platform/platform-api/src/com/intellij/lexer/DummyLexer.java
+++ /dev/null
@@ -1,70 +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.lexer;
-
-import com.intellij.psi.tree.IElementType;
-
-public class DummyLexer extends LexerBase {
-  private CharSequence myBuffer;
-  private int myStartOffset;
-  private int myEndOffset;
-  private final IElementType myTokenType;
-
-  public DummyLexer(IElementType type) {
-    myTokenType = type;
-  }
-
-  public void start(final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
-    myBuffer = buffer;
-    myStartOffset = startOffset;
-    myEndOffset = endOffset;
-  }
-
-  public CharSequence getBufferSequence() {
-    return myBuffer;
-  }
-
-  public int getState() {
-    return 0;
-  }
-
-  public IElementType getTokenType() {
-    return (myStartOffset < myEndOffset ? myTokenType : null);
-  }
-
-  public int getTokenStart() {
-    return myStartOffset;
-  }
-
-  public int getTokenEnd() {
-    return myEndOffset;
-  }
-
-  public void advance() {
-    myStartOffset = myEndOffset;
-  }
-
-  public LexerPosition getCurrentPosition() {
-    return new LexerPositionImpl(0, getState());
-  }
-
-  public void restore(LexerPosition position) {
-  }
-
-  public int getBufferEnd() {
-    return myEndOffset;
-  }
-}
diff --git a/platform/platform-api/src/com/intellij/lexer/LookAheadLexer.java b/platform/platform-api/src/com/intellij/lexer/LookAheadLexer.java
index 17c9bd6..d2b081d 100644
--- a/platform/platform-api/src/com/intellij/lexer/LookAheadLexer.java
+++ b/platform/platform-api/src/com/intellij/lexer/LookAheadLexer.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.
@@ -18,6 +18,7 @@
 import com.intellij.psi.tree.IElementType;
 import com.intellij.util.containers.ImmutableUserMap;
 import com.intellij.util.containers.Queue;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * @author peter
@@ -73,6 +74,7 @@
     assert !myTypeCache.isEmpty();
   }
 
+  @NotNull
   public CharSequence getBufferSequence() {
     return myBaseLexer.getBufferSequence();
   }
@@ -109,11 +111,12 @@
     return myTokenStart;
   }
 
+  @NotNull
   public LookAheadLexerPosition getCurrentPosition() {
     return new LookAheadLexerPosition(this, ImmutableUserMap.EMPTY);
   }
 
-  public final void restore(final LexerPosition _position) {
+  public final void restore(@NotNull final LexerPosition _position) {
     restore((LookAheadLexerPosition) _position);
   }
 
@@ -129,7 +132,7 @@
   }
 
   @Override
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     myBaseLexer.start(buffer, startOffset, endOffset, initialState & 0xFFFF);
     myTokenStart = startOffset;
     myTypeCache.clear();
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/CheckboxAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/CheckboxAction.java
index 6f1c4ecf..5f179ba 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/CheckboxAction.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/CheckboxAction.java
@@ -48,6 +48,7 @@
     checkBox.setToolTipText(presentation.getDescription());
     checkBox.setMnemonic(presentation.getMnemonic());
     checkBox.setDisplayedMnemonicIndex(presentation.getDisplayedMnemonicIndex());
+    checkBox.setSelected(Boolean.TRUE.equals(presentation.getClientProperty(SELECTED_PROPERTY)));
 
     checkBox.addActionListener(new ActionListener() {
       @Override
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactory.java b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactory.java
deleted file mode 100644
index 597b20a..0000000
--- a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactory.java
+++ /dev/null
@@ -1,49 +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.openapi.editor.highlighter;
-
-import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.editor.colors.EditorColorsScheme;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.SyntaxHighlighter;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author yole
- */
-public abstract class EditorHighlighterFactory {
-
-  public static EditorHighlighterFactory getInstance() {
-    return ServiceManager.getService(EditorHighlighterFactory.class);
-  }
-
-  public abstract EditorHighlighter createEditorHighlighter(final SyntaxHighlighter syntaxHighlighter, final EditorColorsScheme colors);
-
-  public abstract EditorHighlighter createEditorHighlighter(final FileType fileType, final EditorColorsScheme settings, final Project project);
-
-  public abstract EditorHighlighter createEditorHighlighter(final Project project, final FileType fileType);
-
-  public abstract EditorHighlighter createEditorHighlighter(@NotNull final VirtualFile file, final EditorColorsScheme globalScheme, @Nullable final Project project);
-
-  public abstract EditorHighlighter createEditorHighlighter(final Project project, final VirtualFile file);
-
-  public abstract EditorHighlighter createEditorHighlighter(final Project project, final String fileName);
-
-  public abstract EditorHighlighter createEditorHighlighter(final EditorColorsScheme settings, final String fileName, @Nullable final Project project);
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionFactory.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionFactory.java
deleted file mode 100644
index da2268b..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionFactory.java
+++ /dev/null
@@ -1,35 +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.
- */
-
-/*
- * @author max
- */
-package com.intellij.openapi.fileTypes;
-
-import com.intellij.openapi.util.KeyedExtensionFactory;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-
-public class FileTypeExtensionFactory<T> extends KeyedExtensionFactory<T, FileType> {
-  public FileTypeExtensionFactory(@NotNull final Class<T> interfaceClass, @NonNls @NotNull final String epName) {
-    super(interfaceClass, epName);
-  }
-
-  @Override
-  public String getKey(@NotNull final FileType key) {
-    return key.getName();
-  }
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/LanguageFileTypeHighlighterProvider.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/LanguageFileTypeHighlighterProvider.java
index ad7ae09..40fdece 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/LanguageFileTypeHighlighterProvider.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileTypes/LanguageFileTypeHighlighterProvider.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.
@@ -17,6 +17,7 @@
 
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -24,7 +25,7 @@
  */
 public class LanguageFileTypeHighlighterProvider implements SyntaxHighlighterProvider {
   @Nullable
-  public SyntaxHighlighter create(final FileType fileType, @Nullable final Project project, @Nullable final VirtualFile file) {
+  public SyntaxHighlighter create(@NotNull final FileType fileType, @Nullable final Project project, @Nullable final VirtualFile file) {
     if (fileType instanceof LanguageFileType) {
       return SyntaxHighlighterFactory.getSyntaxHighlighter(((LanguageFileType)fileType).getLanguage(), project, file);
     }
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighter.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighter.java
deleted file mode 100644
index 08a8000..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighter.java
+++ /dev/null
@@ -1,37 +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.openapi.fileTypes;
-
-import com.intellij.lexer.EmptyLexer;
-import com.intellij.lexer.Lexer;
-import com.intellij.openapi.editor.HighlighterColors;
-import com.intellij.openapi.editor.colors.TextAttributesKey;
-import com.intellij.psi.tree.IElementType;
-import org.jetbrains.annotations.NotNull;
-
-public class PlainSyntaxHighlighter implements SyntaxHighlighter {
-  private static final TextAttributesKey[] ATTRS = new TextAttributesKey[] {HighlighterColors.TEXT};
-
-  @NotNull
-  public Lexer getHighlightingLexer() {
-    return new EmptyLexer();
-  }
-
-  @NotNull
-  public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
-    return ATTRS;
-  }
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighterFactory.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighterFactory.java
deleted file mode 100644
index b19651c..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighterFactory.java
+++ /dev/null
@@ -1,31 +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.
- */
-
-/*
- * @author max
- */
-package com.intellij.openapi.fileTypes;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-
-public class PlainSyntaxHighlighterFactory extends SyntaxHighlighterFactory {
-  @NotNull
-  public SyntaxHighlighter getSyntaxHighlighter(final Project project, final VirtualFile virtualFile) {
-    return new PlainSyntaxHighlighter();
-  }
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java
deleted file mode 100644
index a6cf7a3..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.openapi.fileTypes;
-
-import com.intellij.lexer.Lexer;
-import com.intellij.openapi.editor.colors.TextAttributesKey;
-import com.intellij.psi.tree.IElementType;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Controls the syntax highlighting of a file.
- *
- * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
- * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.lang.Language, com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
- */
-public interface SyntaxHighlighter {
-  /**
-   * @deprecated
-   * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
-   * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.lang.Language, com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
-   */
-  SyntaxHighlighterProvider PROVIDER =
-    new FileTypeExtensionFactory<SyntaxHighlighterProvider>(SyntaxHighlighterProvider.class, "com.intellij.syntaxHighlighter").get();
-
-  /**
-   * Returns the lexer used for highlighting the file. The lexer is invoked incrementally when the file is changed, so it must be
-   * capable of saving/restoring state and resuming lexing from the middle of the file.
-   *
-   * @return The lexer implementation.
-   */
-  @NotNull
-  Lexer getHighlightingLexer();
-
-  /**
-   * Returns the list of text attribute keys used for highlighting the specified token type. The attributes of all attribute keys
-   * returned for the token type are successively merged to obtain the color and attributes of the token.
-   *
-   * @param tokenType The token type for which the highlighting is requested.
-   * @return The array of text attribute keys.
-   */
-  @NotNull
-  TextAttributesKey[] getTokenHighlights(IElementType tokenType);
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java
deleted file mode 100644
index ad697f9..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.openapi.fileTypes;
-
-import com.intellij.lang.Language;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author max
- */
-public abstract class SyntaxHighlighterFactory {
-  public static final SyntaxHighlighterLanguageFactory LANGUAGE_FACTORY = new SyntaxHighlighterLanguageFactory();
-
-  /**
-   * Returns syntax highlighter for the given language.
-   *
-   * @param language a {@code Language} to get highlighter for
-   * @param project  might be necessary to gather various project settings from
-   * @param file     might be necessary to collect file specific settings
-   * @return {@code SyntaxHighlighter} interface implementation for the given file type
-   */
-  public static SyntaxHighlighter getSyntaxHighlighter(@NotNull Language language, @Nullable Project project, @Nullable VirtualFile file) {
-    return LANGUAGE_FACTORY.forLanguage(language).getSyntaxHighlighter(project, file);
-  }
-
-  /**
-   * Returns syntax highlighter for the given file type.
-   * Note: it is recommended to use {@link #getSyntaxHighlighter(Language, Project, VirtualFile)} in most cases,
-   * and use this method only when you are do not know the language you use.
-   *
-   * @param fileType a file type to use to select appropriate highlighter
-   * @param project  might be necessary to gather various project settings from
-   * @param file     might be necessary to collect file specific settings
-   * @return {@code SyntaxHighlighter} interface implementation for the given file type
-   */
-  @Nullable
-  public static SyntaxHighlighter getSyntaxHighlighter(FileType fileType, @Nullable Project project, @Nullable VirtualFile file) {
-    return SyntaxHighlighter.PROVIDER.create(fileType, project, file);
-  }
-
-  /**
-   * Override this method to provide syntax highlighting (coloring) capabilities for your language implementation.
-   * By syntax highlighting we mean highlighting of keywords, comments, braces etc. where lexing the file content is enough
-   * to identify proper highlighting attributes.
-   * <p/>
-   * Default implementation doesn't highlight anything.
-   *
-   * @param project     might be necessary to gather various project settings from.
-   * @param virtualFile might be necessary to collect file specific settings
-   * @return <code>SyntaxHighlighter</code> interface implementation for this particular language.
-   */
-  @NotNull
-  public abstract SyntaxHighlighter getSyntaxHighlighter(@Nullable Project project, @Nullable VirtualFile virtualFile);
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterLanguageFactory.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterLanguageFactory.java
deleted file mode 100644
index a223fa0..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterLanguageFactory.java
+++ /dev/null
@@ -1,28 +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.
- */
-
-/*
- * @author max
- */
-package com.intellij.openapi.fileTypes;
-
-import com.intellij.lang.LanguageExtension;
-
-public class SyntaxHighlighterLanguageFactory extends LanguageExtension<SyntaxHighlighterFactory> {
-  SyntaxHighlighterLanguageFactory() {
-    super("com.intellij.lang.syntaxHighlighterFactory", new PlainSyntaxHighlighterFactory());
-  }
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterProvider.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterProvider.java
deleted file mode 100644
index 6317dd7..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterProvider.java
+++ /dev/null
@@ -1,32 +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.
- */
-
-/*
- * Created by IntelliJ IDEA.
- * User: yole
- * Date: 06.11.2007
- * Time: 19:49:57
- */
-package com.intellij.openapi.fileTypes;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.Nullable;
-
-public interface SyntaxHighlighterProvider {
-  @Nullable
-  SyntaxHighlighter create(FileType fileType, @Nullable Project project, @Nullable VirtualFile file);
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/options/SchemeImportException.java b/platform/platform-api/src/com/intellij/openapi/options/SchemeImportException.java
new file mode 100644
index 0000000..96835f1
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/openapi/options/SchemeImportException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.openapi.options;
+
+/**
+ * Thrown from SchemeImporter when a scheme can't be read for some reason.
+ * 
+ * @see com.intellij.openapi.options.SchemeImporter
+ * @author Rustam Vishnyakov
+ */
+public class SchemeImportException extends Exception {
+  public SchemeImportException(String message) {
+    super(message);
+  }
+
+  public SchemeImportException(Throwable cause) {
+    super(cause);
+  }
+}
diff --git a/platform/platform-api/src/com/intellij/openapi/options/SchemeImporter.java b/platform/platform-api/src/com/intellij/openapi/options/SchemeImporter.java
new file mode 100644
index 0000000..8bb8456
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/openapi/options/SchemeImporter.java
@@ -0,0 +1,39 @@
+package com.intellij.openapi.options;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.InputStream;
+
+/**
+ * Provides functionality to import a scheme from another non-IntelliJ IDEA format.
+ * 
+ * @author Rustam Vishnyakov
+ */
+public interface SchemeImporter <T extends Scheme> {
+
+  /**
+   * @return An extension of a source file which can be imported, for example, "xml".
+   */
+  String getSourceExtension();
+
+  /**
+   * Attempts to read scheme names from the given stream. The stream may contain several schemes in which case all the available
+   * names are returned.
+   *
+   * @param inputStream The input stream to read the name from.
+   * @return Either scheme name or null if the scheme doesn't have a name.
+   * @throws SchemeImportException
+   */
+  @NotNull
+  String[] readSchemeNames(@NotNull InputStream inputStream) throws SchemeImportException;
+
+  /**
+   * Import a scheme from the given stream and source scheme name.
+   *
+   * @param inputStream  The input stream to import from.
+   * @param sourceScheme The source scheme name (one of returned by <code>readSchemeNames</code> method).
+   * @param scheme       The target scheme receiving data.
+   */
+  void importScheme(@NotNull InputStream inputStream, @Nullable String sourceScheme, T scheme) throws SchemeImportException;
+}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/JBPopupListener.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/JBPopupListener.java
index 2964c19..1f004c7 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/popup/JBPopupListener.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/JBPopupListener.java
@@ -21,12 +21,13 @@
 
   void onClosed(LightweightWindowEvent event);
 
-  class Adapter implements JBPopupListener{
+  class Adapter implements JBPopupListener {
+    @Override
     public void beforeShown(LightweightWindowEvent event) {
     }
 
+    @Override
     public void onClosed(LightweightWindowEvent event) {
     }
   }
-
 }
diff --git a/platform/platform-api/src/com/intellij/openapi/util/DimensionService.java b/platform/platform-api/src/com/intellij/openapi/util/DimensionService.java
index de2bd4b..b9ee6c0 100644
--- a/platform/platform-api/src/com/intellij/openapi/util/DimensionService.java
+++ b/platform/platform-api/src/com/intellij/openapi/util/DimensionService.java
@@ -22,6 +22,7 @@
 import com.intellij.openapi.project.ProjectManager;
 import com.intellij.openapi.wm.WindowManager;
 import com.intellij.ui.ScreenUtil;
+import com.intellij.util.containers.hash.LinkedHashMap;
 import gnu.trove.TObjectIntHashMap;
 import org.jdom.Element;
 import org.jetbrains.annotations.NonNls;
@@ -30,23 +31,20 @@
 
 import javax.swing.*;
 import java.awt.*;
-import java.util.HashMap;
 import java.util.Map;
 
 /**
  * This class represents map between strings and rectangles. It's intended to store
  * sizes of window, dialogs, etc.
  */
-@SuppressWarnings({"NonPrivateFieldAccessedInSynchronizedContext"})
 @State(
-    name = "DimensionService",
-    storages = {@Storage(
-        file = StoragePathMacros.APP_CONFIG + "/options.xml")})
+  name = "DimensionService",
+  storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/options.xml")})
 public class DimensionService implements PersistentStateComponent<Element>, ApplicationComponent {
   private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.DimensionService");
 
-  private final Map<String,Point> myKey2Location;
-  private final Map<String,Dimension> myKey2Size;
+  private final Map<String, Point> myKey2Location;
+  private final Map<String, Dimension> myKey2Size;
   private final TObjectIntHashMap<String> myKey2ExtendedState;
   @NonNls private static final String EXTENDED_STATE = "extendedState";
   @NonNls private static final String KEY = "key";
@@ -62,24 +60,30 @@
     return ApplicationManager.getApplication().getComponent(DimensionService.class);
   }
 
-  /** Invoked by reflection */
-  private DimensionService(){
-    myKey2Location=new HashMap<String, Point>();
-    myKey2Size=new HashMap<String, Dimension>();
+  /**
+   * Invoked by reflection
+   */
+  private DimensionService() {
+    myKey2Location = new LinkedHashMap<String, Point>();
+    myKey2Size = new LinkedHashMap<String, Dimension>();
     myKey2ExtendedState = new TObjectIntHashMap<String>();
   }
 
-  public void initComponent() {}
+  @Override
+  public void initComponent() {
+  }
 
-  public void disposeComponent() {}
+  @Override
+  public void disposeComponent() {
+  }
 
   /**
+   * @param key a String key to perform a query for.
    * @return point stored under the specified <code>key</code>. The method returns
    * <code>null</code> if there is no stored value under the <code>key</code>. If point
    * is outside of current screen bounds then the method returns <code>null</code>. It
    * properly works in multi-monitor configuration.
-   * @exception java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
-   * @param key a String key to perform a query for.
+   * @throws java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
    */
   @Nullable
   public synchronized Point getLocation(String key) {
@@ -88,47 +92,41 @@
 
   @Nullable
   public synchronized Point getLocation(@NotNull String key, Project project) {
-    key = realKey(key, project);
-
-    Point point = myKey2Location.get(key);
-    if (point != null) {
-      if (!ScreenUtil.getScreenRectangle(point).contains(point)){
-        point = null;
-      }
+    Point point = myKey2Location.get(realKey(key, project));
+    if (point != null && !ScreenUtil.getScreenRectangle(point).contains(point)) {
+      point = null;
     }
-    if(point!=null){
-      return (Point)point.clone();
-    }else{
-      return null;
-    }
+    return point != null ? (Point)point.clone() : null;
   }
 
   /**
    * Store specified <code>point</code> under the <code>key</code>. If <code>point</code> is
    * <code>null</code> then the value stored under <code>key</code> will be removed.
-   * @param key a String key to store location for.
+   *
+   * @param key   a String key to store location for.
    * @param point location to save.
-   * @exception java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
+   * @throws java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
    */
-  public synchronized void setLocation(String key, Point point){
+  public synchronized void setLocation(String key, Point point) {
     setLocation(key, point, guessProject());
   }
 
-  public synchronized void setLocation(@NotNull String key, Point point, Project project){
+  public synchronized void setLocation(@NotNull String key, Point point, Project project) {
     key = realKey(key, project);
 
     if (point != null) {
       myKey2Location.put(key, (Point)point.clone());
-    }else {
+    }
+    else {
       myKey2Location.remove(key);
     }
   }
 
   /**
+   * @param key a String key to perform a query for.
    * @return point stored under the specified <code>key</code>. The method returns
    * <code>null</code> if there is no stored value under the <code>key</code>.
-   * @param key a String key to perform a query for.
-   * @exception java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
+   * @throws java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
    */
   @Nullable
   public synchronized Dimension getSize(@NotNull @NonNls String key) {
@@ -137,37 +135,34 @@
 
   @Nullable
   public synchronized Dimension getSize(@NotNull @NonNls String key, Project project) {
-    key = realKey(key, project);
-
-    Dimension size=myKey2Size.get(key);
-    if(size!=null){
-      return (Dimension)size.clone();
-    }else{
-      return null;
-    }
+    Dimension size = myKey2Size.get(realKey(key, project));
+    return size != null ? (Dimension)size.clone() : null;
   }
 
   /**
    * Store specified <code>size</code> under the <code>key</code>. If <code>size</code> is
    * <code>null</code> then the value stored under <code>key</code> will be removed.
-   * @param key a String key to to save size for.
+   *
+   * @param key  a String key to to save size for.
    * @param size a Size to save.
-   * @exception java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
+   * @throws java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
    */
-  public synchronized void setSize(@NotNull @NonNls String key, Dimension size){
+  public synchronized void setSize(@NotNull @NonNls String key, Dimension size) {
     setSize(key, size, guessProject());
   }
 
-  public synchronized void setSize(@NotNull @NonNls String key, Dimension size, Project project){
+  public synchronized void setSize(@NotNull @NonNls String key, Dimension size, Project project) {
     key = realKey(key, project);
 
     if (size != null) {
       myKey2Size.put(key, (Dimension)size.clone());
-    }else {
+    }
+    else {
       myKey2Size.remove(key);
     }
   }
 
+  @Override
   public Element getState() {
     Element element = new Element("state");
     // Save locations
@@ -203,20 +198,19 @@
     return element;
   }
 
+  @Override
   public void loadState(final Element element) {
     myKey2Location.clear();
     myKey2Size.clear();
     myKey2ExtendedState.clear();
 
-    for (final Object o : element.getChildren()) {
-      Element e = (Element)o;
+    for (Element e : element.getChildren()) {
       if (ELEMENT_LOCATION.equals(e.getName())) {
         try {
           myKey2Location.put(e.getAttributeValue(KEY), new Point(Integer.parseInt(e.getAttributeValue(ATTRIBUTE_X)),
                                                                  Integer.parseInt(e.getAttributeValue(ATTRIBUTE_Y))));
         }
         catch (NumberFormatException ignored) {
-          // ignored
         }
       }
       else if (ELEMENT_SIZE.equals(e.getName())) {
@@ -225,7 +219,6 @@
                                                                  Integer.parseInt(e.getAttributeValue(ATTRIBUTE_HEIGHT))));
         }
         catch (NumberFormatException ignored) {
-          // ignored
         }
       }
       else if (EXTENDED_STATE.equals(e.getName())) {
@@ -233,12 +226,12 @@
           myKey2ExtendedState.put(e.getAttributeValue(KEY), Integer.parseInt(e.getAttributeValue(STATE)));
         }
         catch (NumberFormatException ignored) {
-          // ignored
         }
       }
     }
   }
 
+  @Override
   @NotNull
   public String getComponentName() {
     return "DimensionService";
diff --git a/platform/platform-api/src/com/intellij/openapi/util/KeyedExtensionFactory.java b/platform/platform-api/src/com/intellij/openapi/util/KeyedExtensionFactory.java
deleted file mode 100644
index 9827e2f..0000000
--- a/platform/platform-api/src/com/intellij/openapi/util/KeyedExtensionFactory.java
+++ /dev/null
@@ -1,107 +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.openapi.util;
-
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.extensions.KeyedFactoryEPBean;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-/**
- * @author yole
- */
-public abstract class KeyedExtensionFactory<T, KeyT> {
-  private final Class<T> myInterfaceClass;
-  private final ExtensionPointName<KeyedFactoryEPBean> myEpName;
-
-  public KeyedExtensionFactory(@NotNull final Class<T> interfaceClass, @NonNls @NotNull final String epName) {
-    myInterfaceClass = interfaceClass;
-    myEpName = new ExtensionPointName<KeyedFactoryEPBean>(epName);
-  }
-
-  @NotNull
-  public T get() {
-    final KeyedFactoryEPBean[] epBeans = Extensions.getExtensions(myEpName);
-    InvocationHandler handler = new InvocationHandler() {
-      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-        //noinspection unchecked
-        KeyT keyArg = (KeyT) args [0];
-        String key = getKey(keyArg);
-        Object result = getByKey(epBeans, key, method, args);
-        if (result == null) {
-          result = getByKey(epBeans, null, method, args);
-        }
-        return result;
-      }
-    };
-    //noinspection unchecked
-    return (T)Proxy.newProxyInstance(myInterfaceClass.getClassLoader(), new Class<?>[] { myInterfaceClass }, handler );
-  }
-
-  public T getByKey(@NotNull KeyT key) {
-    final KeyedFactoryEPBean[] epBeans = Extensions.getExtensions(myEpName);
-    for (KeyedFactoryEPBean epBean : epBeans) {
-      if (Comparing.strEqual(getKey(key), epBean.key)) {
-        try {
-          if (epBean.implementationClass != null) {
-            return (T)epBean.instantiate(epBean.implementationClass, ApplicationManager.getApplication().getPicoContainer());
-          }
-        }
-        catch (Exception e) {
-          throw new RuntimeException(e);
-        }
-      }
-    }
-    return null;
-  }
-
-  private T getByKey(final KeyedFactoryEPBean[] epBeans, final String key, final Method method, final Object[] args) {
-    Object result = null;
-    for(KeyedFactoryEPBean epBean: epBeans) {
-      if (Comparing.strEqual(epBean.key, key, true)) {
-        try {
-          if (epBean.implementationClass != null) {
-            result = epBean.instantiate(epBean.implementationClass, ApplicationManager.getApplication().getPicoContainer());
-          }
-          else {
-            Object factory = epBean.instantiate(epBean.factoryClass, ApplicationManager.getApplication().getPicoContainer());
-            result = method.invoke(factory, args);
-          }
-          if (result != null) {
-            break;
-          }
-        }
-        catch (RuntimeException e) {
-          throw e;
-        }
-        catch (Exception e) {
-          throw new RuntimeException(e);
-        }
-      }
-    }
-    //noinspection ConstantConditions
-    return (T)result;
-  }
-
-  public abstract String getKey(@NotNull KeyT key);
-}
-
diff --git a/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java
index 18f59ed..c5dcc9e 100644
--- a/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java
+++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java
@@ -192,6 +192,10 @@
 
   }
 
+  protected void nodeStateWillChange(CheckedTreeNode node) {
+
+  }
+
   protected void adjustParentsAndChildren(final CheckedTreeNode node, final boolean checked) {
     changeNodeState(node, checked);
     if (!checked) {
@@ -230,6 +234,7 @@
 
   private void changeNodeState(final CheckedTreeNode node, final boolean checked) {
     if (node.isChecked() != checked) {
+      nodeStateWillChange(node);
       node.setChecked(checked);
       onNodeStateChanged(node);
     }
diff --git a/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java b/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java
index 28c71db..168f4ee 100644
--- a/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java
+++ b/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java
@@ -44,6 +44,7 @@
   protected JTree myTree;
 
   private boolean myOpaque = true;
+  @Override
   public final Component getTreeCellRendererComponent(
     JTree tree,
     Object value,
@@ -137,6 +138,7 @@
     return myTree.hasFocus();
   }
 
+  @Override
   public void setOpaque(boolean isOpaque) {
     myOpaque = isOpaque;
     super.setOpaque(isOpaque);
@@ -157,6 +159,7 @@
    * When the item is selected then we use default tree's selection foreground.
    * It guaranties readability of selected text in any LAF.
    */
+  @Override
   public void append(@NotNull @Nls String fragment, @NotNull SimpleTextAttributes attributes, boolean isMainText) {
     if (mySelected && isFocused()) {
       super.append(fragment, new SimpleTextAttributes(attributes.getStyle(), UIUtil.getTreeSelectionForeground()), isMainText);
diff --git a/platform/platform-api/src/com/intellij/ui/PrepareTreeRenderer.java b/platform/platform-api/src/com/intellij/ui/PrepareTreeRenderer.java
deleted file mode 100644
index ad4c0da..0000000
--- a/platform/platform-api/src/com/intellij/ui/PrepareTreeRenderer.java
+++ /dev/null
@@ -1,79 +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 com.intellij.ui;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 6/12/12
- * Time: 4:40 PM
- */
-public class PrepareTreeRenderer {
-/*  public static void prepare(final JTree tree, final JComponent component, final boolean selected, final boolean hasFocus) {
-    final boolean treeFocused = tree.hasFocus();
-    // We paint background if and only if tree path is selected and tree has focus.
-    // If path is selected and tree is not focused then we just paint focused border.
-    if (UIUtil.isFullRowSelectionLAF()) {
-        component.setBackground(selected ? UIUtil.getTreeSelectionBackground() : null);
-    }
-    else if (UIUtil.isUnderAquaLookAndFeel() && tree.getUI() instanceof MacTreeUI && ((MacTreeUI)tree.getUI()).isWideSelection()) {
-      component.setPaintFocusBorder(false);
-      //setBackground(selected ? UIUtil.getTreeSelectionBackground() : null);
-    }
-    else {
-      if (selected) {
-        component.setPaintFocusBorder(true);
-        if (treeFocused) {
-          component.setBackground(UIUtil.getTreeSelectionBackground());
-        }
-        else {
-          component.setBackground(null);
-        }
-      }
-      else {
-        component.setBackground(null);
-      }
-    }
-
-    component.setForeground(tree.getForeground());
-    component.setIcon(null);
-
-    if (UIUtil.isUnderGTKLookAndFeel()){
-      component.setOpaque(false);  // avoid nasty background
-      component.setIconOpaque(false);
-    }
-    else if (UIUtil.isUnderNimbusLookAndFeel() && selected && hasFocus) {
-      component.setOpaque(false);  // avoid erasing Nimbus focus frame
-      component.setIconOpaque(false);
-    }
-    else if (UIUtil.isUnderAquaLookAndFeel() && tree.getUI() instanceof MacTreeUI && ((MacTreeUI)tree.getUI()).isWideSelection()) {
-      component.setOpaque(false);  // avoid erasing Nimbus focus frame
-      component.setIconOpaque(false);
-    }
-    else {
-      component.setOpaque(myOpaque || selected && hasFocus || selected && treeFocused); // draw selection background even for non-opaque tree
-    }
-
-    if (tree.getUI() instanceof MacTreeUI) {
-      component.setMyBorder(null);
-      component.setIpad(new Insets(0, 2,  0, 2));
-    }
-
-    if (component.getFont() == null) {
-      component.setFont(tree.getFont());
-    }
-  }      */
-}
diff --git a/platform/platform-api/src/com/intellij/ui/TextComponentUndoProvider.java b/platform/platform-api/src/com/intellij/ui/TextComponentUndoProvider.java
index ce95057..0fe7e6e 100644
--- a/platform/platform-api/src/com/intellij/ui/TextComponentUndoProvider.java
+++ b/platform/platform-api/src/com/intellij/ui/TextComponentUndoProvider.java
@@ -37,6 +37,7 @@
     myTextComponent = textComponent;
 
     myUndoableEditListener = new UndoableEditListener() {
+      @Override
       public void undoableEditHappened(UndoableEditEvent e) {
         myUndoManager.addEdit(e.getEdit());
       }
@@ -96,6 +97,7 @@
     }
   }
 
+  @Override
   public void dispose() {
     if (myUndoableEditListener != null) {
       myTextComponent.getDocument().removeUndoableEditListener(myUndoableEditListener);
diff --git a/platform/platform-api/src/com/intellij/ui/table/TableView.java b/platform/platform-api/src/com/intellij/ui/table/TableView.java
index ad76c90..889c496 100644
--- a/platform/platform-api/src/com/intellij/ui/table/TableView.java
+++ b/platform/platform-api/src/com/intellij/ui/table/TableView.java
@@ -112,8 +112,12 @@
       final ColumnInfo columnInfo = columns[i];
       final TableColumn column = getColumnModel().getColumn(i);
 
-      final Component headerComponent = defaultRenderer == null? null :
-        defaultRenderer.getTableCellRendererComponent(this, column.getHeaderValue(), false, false, 0, 0);
+      TableCellRenderer columnHeaderRenderer = column.getHeaderRenderer();
+      if (columnHeaderRenderer == null) {
+        columnHeaderRenderer = defaultRenderer;
+      }
+      final Component headerComponent = columnHeaderRenderer == null? null :
+        columnHeaderRenderer.getTableCellRendererComponent(this, column.getHeaderValue(), false, false, 0, i);
 
       if (headerComponent != null) {
         headers[i] = headerComponent.getPreferredSize().width;
diff --git a/platform/platform-api/src/com/intellij/util/PlatformUtils.java b/platform/platform-api/src/com/intellij/util/PlatformUtils.java
index e71e70b..b4e9228 100644
--- a/platform/platform-api/src/com/intellij/util/PlatformUtils.java
+++ b/platform/platform-api/src/com/intellij/util/PlatformUtils.java
@@ -59,7 +59,8 @@
   }
 
   public static boolean isPyCharm() {
-    return PYCHARM_PREFIX.equals(getPlatformPrefix());
+    String prefix = getPlatformPrefix();
+    return PYCHARM_PREFIX.equals(prefix) || (prefix != null && prefix.startsWith(PYCHARM_PREFIX2));
   }
 
   public static boolean isPhpStorm() {
diff --git a/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java b/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java
index a58aaa1..cf95958 100644
--- a/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java
+++ b/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java
@@ -24,7 +24,6 @@
 import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.Conditions;
 import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.CharsetToolkit;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -34,7 +33,6 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.io.File;
 import java.nio.charset.Charset;
 
 /**
@@ -114,18 +112,7 @@
                                          @Nullable VirtualFile scriptFile,
                                          String[] parameters,
                                          @Nullable Charset charset) throws ExecutionException {
-    if (SystemInfo.isMac) {
-      File exeFile = new File(exePath);
-      if (!exeFile.isAbsolute() && !exePath.contains(File.separator)) {
-        File originalResolvedExeFile = PathEnvironmentVariableUtil.findInOriginalPath(exePath);
-        if (originalResolvedExeFile == null) {
-          File resolvedExeFile = PathEnvironmentVariableUtil.findInPath(exePath);
-          if (resolvedExeFile != null) {
-            exePath = resolvedExeFile.getAbsolutePath();
-          }
-        }
-      }
-    }
+    exePath = PathEnvironmentVariableUtil.findAbsolutePathOnMac(exePath);
     return doExecute(exePath, workingDirectory, scriptFile, parameters, charset);
   }
 
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
index c84f7e2..5f259bf 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.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.
@@ -211,7 +211,8 @@
                          "xdg-desktop-menu forceupdate --mode system\n" +
                          "exit $RV\n");
         script.deleteOnExit();
-        final int result = ExecUtil.sudoAndGetResult(script.getAbsolutePath(), ApplicationBundle.message("desktop.entry.sudo.prompt"));
+        final String prompt = ApplicationBundle.message("desktop.entry.sudo.prompt");
+        final int result = ExecUtil.sudoAndGetOutput(asList(script.getPath()), prompt, null).getExitCode();
         if (result != 0) throw new RuntimeException("'" + script.getAbsolutePath() + "' : " + result);
       }
       else {
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java
index 8644cd5..315e3ad 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.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.
@@ -112,8 +112,8 @@
           // copy file and change ownership to root (UID 0 = root, GID 0 = root (wheel on Macs))
           "install -g 0 -o 0 \"" + scriptFile.getCanonicalPath() + "\" \"" + pathName + "\"";
         final File installationScript = ExecUtil.createTempExecutableScript("launcher_installer", ".sh", installationScriptSrc);
-        ExecUtil.sudoAndGetResult(installationScript.getAbsolutePath(),
-                                  ApplicationBundle.message("launcher.script.sudo.prompt", launcherScriptContainingDirPath));
+        final String prompt = ApplicationBundle.message("launcher.script.sudo.prompt", launcherScriptContainingDirPath);
+        ExecUtil.sudoAndGetOutput(asList(installationScript.getPath()), prompt, null);
       }
     }
     catch (Exception e) {
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java
index 5dcf70e..7a15f84 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java
@@ -22,6 +22,7 @@
 import com.intellij.ide.IdeBundle;
 import com.intellij.ide.plugins.IdeaPluginDescriptor;
 import com.intellij.ide.plugins.PluginManager;
+import com.intellij.ide.plugins.PluginManagerCore;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.application.ApplicationManager;
@@ -44,7 +45,6 @@
 import java.util.jar.JarOutputStream;
 
 public class ExportSettingsAction extends AnAction implements DumbAware {
-
   public void actionPerformed(AnActionEvent e) {
     Project project = getEventProject(e);
     List<ExportableComponent> exportableComponents = new ArrayList<ExportableComponent>();
@@ -57,11 +57,12 @@
     dialog.show();
     if (!dialog.isOK()) return;
     Set<ExportableComponent> markedComponents = dialog.getExportableComponents();
-    if (markedComponents.size() == 0) return;
+    if (markedComponents.isEmpty()) {
+      return;
+    }
     Set<File> exportFiles = new HashSet<File>();
     for (final ExportableComponent markedComponent : markedComponents) {
-      final File[] files = markedComponent.getExportFiles();
-      ContainerUtil.addAll(exportFiles, files);
+      ContainerUtil.addAll(exportFiles, markedComponent.getExportFiles());
     }
 
     ApplicationManager.getApplication().saveSettings();
@@ -107,7 +108,7 @@
 
   private static void exportInstalledPlugins(File saveFile, JarOutputStream output, HashSet<String> writtenItemRelativePaths) throws IOException {
     final List<String> oldPlugins = new ArrayList<String>();
-    for (IdeaPluginDescriptor descriptor : PluginManager.getPlugins()) {
+    for (IdeaPluginDescriptor descriptor : PluginManagerCore.getPlugins()) {
       if (!descriptor.isBundled() && descriptor.isEnabled()) {
         oldPlugins.add(descriptor.getPluginId().getIdString());
       }
@@ -115,7 +116,7 @@
     if (!oldPlugins.isEmpty()) {
       final File tempFile = File.createTempFile("installed", "plugins");
       tempFile.deleteOnExit();
-      PluginManager.savePluginsList(oldPlugins, false, tempFile);
+      PluginManagerCore.savePluginsList(oldPlugins, false, tempFile);
       ZipUtil.addDirToZipRecursively(output, saveFile, tempFile, "/" + PluginManager.INSTALLED_TXT, null, writtenItemRelativePaths);
     }
   }
@@ -129,8 +130,7 @@
 
     for (ExportableComponent component : components) {
       exportableComponents.add(component);
-      final File[] exportFiles = component.getExportFiles();
-      for (File exportFile : exportFiles) {
+      for (File exportFile : component.getExportFiles()) {
         Set<ExportableComponent> componentsTied = fileToComponents.get(exportFile);
         if (componentsTied == null) {
           componentsTied = new HashSet<ExportableComponent>();
@@ -141,5 +141,4 @@
     }
     return fileToComponents;
   }
-
 }
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/MaintenanceAction.java b/platform/platform-impl/src/com/intellij/ide/actions/MaintenanceAction.java
index b42a9a1..df99af2 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/MaintenanceAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/MaintenanceAction.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,9 +19,10 @@
 import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.ui.popup.JBPopupFactory;
 
-public class MaintenanceAction extends AnAction {
+public class MaintenanceAction extends AnAction implements DumbAware {
 
   public MaintenanceAction() {
     super("Maintenance");
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java b/platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java
index c1e32c6..2ba9f1a 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java
@@ -36,9 +36,10 @@
 
   public static void launchBrowser() {
     final ApplicationInfoEx appInfo = ApplicationInfoEx.getInstanceEx();
-    String urlTemplate = appInfo.isEAP() ? appInfo.getEAPFeedbackUrl() : appInfo.getReleaseFeedbackUrl();
+    boolean eap = appInfo.isEAP();
+    String urlTemplate = eap ? appInfo.getEAPFeedbackUrl() : appInfo.getReleaseFeedbackUrl();
     urlTemplate = urlTemplate
-      .replace("$BUILD", appInfo.getBuild().asString())
+      .replace("$BUILD", eap ? appInfo.getBuild().asStringWithoutProductCode() : appInfo.getBuild().asString())
       .replace("$TIMEZONE", System.getProperty("user.timezone"))
       .replace("$EVAL", isEvaluationLicense() ? "true" : "false");
     BrowserUtil.launchBrowser(urlTemplate);
diff --git a/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java b/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java
index b20c113..0c14e13 100644
--- a/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java
+++ b/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.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.
@@ -71,6 +71,7 @@
     myCommentAtLineStart.setEnabled(false);
   }
 
+  @Override
   public void resetEditorFrom(AbstractFileType fileType) {
     myFileTypeName.setText(fileType.getName());
     myFileTypeDescr.setText(fileType.getDescription());
@@ -106,6 +107,7 @@
     }
   }
 
+  @Override
   public void applyEditorTo(AbstractFileType type) throws ConfigurationException {
     if (myFileTypeName.getText().trim().length() == 0) {
       throw new ConfigurationException(IdeBundle.message("error.name.cannot.be.empty"),
@@ -119,6 +121,7 @@
     type.setSyntaxTable(getSyntaxTable());
   }
 
+  @Override
   @NotNull
   public JComponent createEditor() {
     JComponent panel = createCenterPanel();
diff --git a/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.java b/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.java
index 400c67a..bed9d53 100644
--- a/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.java
+++ b/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.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.
@@ -41,6 +41,7 @@
     myKeywordName.setText(initialValue);
   }
 
+  @Override
   protected JComponent createNorthPanel() {
     JPanel panel = new JPanel(new GridBagLayout());
     GridBagConstraints gc = new GridBagConstraints();
@@ -64,10 +65,12 @@
     return panel;
   }
 
+  @Override
   protected JComponent createCenterPanel() {
     return null;
   }
 
+  @Override
   protected void doOKAction() {
     final String keywordName = myKeywordName.getText().trim();
     if (keywordName.length() == 0) {
@@ -83,6 +86,7 @@
     super.doOKAction();
   }
 
+  @Override
   public JComponent getPreferredFocusedComponent() {
     return myKeywordName;
   }
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
index 95bbfdc..4037066 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
@@ -27,6 +27,7 @@
 import com.intellij.openapi.components.ComponentConfig;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.extensions.PluginId;
+import com.intellij.openapi.extensions.impl.PicoPluginExtensionInitializationException;
 import com.intellij.openapi.options.ShowSettingsUtil;
 import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.util.Comparing;
@@ -99,6 +100,9 @@
     if (t instanceof StartupAbortedException) {
       se = (StartupAbortedException)t;
     }
+    else if (t.getCause() instanceof StartupAbortedException) {
+      se = (StartupAbortedException)t.getCause();
+    }
     else if (!IdeaApplication.isLoaded()) {
       se = new StartupAbortedException(t);
     }
@@ -196,7 +200,18 @@
       throw (StartupAbortedException)t;
     }
 
-    PluginId pluginId = config != null ? config.getPluginId() : getPluginByClassName(componentClassName);
+    PluginId pluginId = null;
+    if (config != null) {
+      pluginId = config.getPluginId();
+    }
+    if (pluginId == null || CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
+      pluginId = getPluginByClassName(componentClassName);
+    }
+    if (pluginId == null || CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
+      if (t instanceof PicoPluginExtensionInitializationException) {
+        pluginId = ((PicoPluginExtensionInitializationException)t).getPluginId();
+      }
+    }
 
     if (pluginId != null && !CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
       getLogger().warn(t);
@@ -206,7 +221,7 @@
       String message =
         "Plugin '" + pluginId.getIdString() + "' failed to initialize and will be disabled\n" +
         "(reason: " + t.getMessage() + ")\n\n" +
-        ApplicationNamesInfo.getInstance().getFullProductName() + " will be restarted.";
+        "Please restart " + ApplicationNamesInfo.getInstance().getFullProductName() + ".";
       Main.showMessage("Plugin Error", message, false);
 
       throw new StartupAbortedException(t).exitCode(Main.PLUGIN_ERROR).logError(false);
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
index 92027af..99d50c7 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
@@ -148,6 +148,7 @@
       // when we leave only system LaFs on other OSes, the order also should be determined as Default, Darcula
       
       Arrays.sort(myLaFs, new Comparator<UIManager.LookAndFeelInfo>() {
+        @Override
         public int compare(UIManager.LookAndFeelInfo obj1, UIManager.LookAndFeelInfo obj2) {
           String name1 = obj1.getName();
           String name2 = obj2.getName();
@@ -162,6 +163,7 @@
   /**
    * Adds specified listener
    */
+  @Override
   public void addLafManagerListener(@NotNull final LafManagerListener l) {
     myListenerList.add(LafManagerListener.class, l);
   }
@@ -169,6 +171,7 @@
   /**
    * Removes specified listener
    */
+  @Override
   public void removeLafManagerListener(@NotNull final LafManagerListener l) {
     myListenerList.remove(LafManagerListener.class, l);
   }
@@ -180,11 +183,13 @@
     }
   }
 
+  @Override
   @NotNull
   public String getComponentName() {
     return "LafManager";
   }
 
+  @Override
   public void initComponent() {
     if (myCurrentLaf != null) {
       final UIManager.LookAndFeelInfo laf = findLaf(myCurrentLaf.getClassName());
@@ -213,6 +218,7 @@
     }
   }
 
+  @Override
   public void disposeComponent() {
     if (myThemeChangeListener != null) {
       Toolkit.getDefaultToolkit().removePropertyChangeListener(GNOME_THEME_PROPERTY_NAME, myThemeChangeListener);
@@ -220,6 +226,7 @@
     }
   }
 
+  @Override
   public void loadState(final Element element) {
     String className = null;
     for (final Object o : element.getChildren()) {
@@ -244,6 +251,7 @@
     myCurrentLaf = laf;
   }
 
+  @Override
   public Element getState() {
     Element element = new Element("state");
     if (myCurrentLaf != null) {
@@ -257,10 +265,12 @@
     return element;
   }
 
+  @Override
   public UIManager.LookAndFeelInfo[] getInstalledLookAndFeels(){
     return myLaFs.clone();
   }
 
+  @Override
   public UIManager.LookAndFeelInfo getCurrentLookAndFeel(){
     return myCurrentLaf;
   }
@@ -322,6 +332,7 @@
   /**
    * Sets current LAF. The method doesn't update component hierarchy.
    */
+  @Override
   public void setCurrentLookAndFeel(UIManager.LookAndFeelInfo lookAndFeelInfo) {
     if (findLaf(lookAndFeelInfo.getClassName()) == null) {
       LOG.error("unknown LookAndFeel : " + lookAndFeelInfo);
@@ -458,6 +469,7 @@
    * Updates LAF of all windows. The method also updates font of components
    * as it's configured in <code>UISettings</code>.
    */
+  @Override
   public void updateUI() {
     final UIDefaults uiDefaults = UIManager.getLookAndFeelDefaults();
 
@@ -671,6 +683,7 @@
   /**
    * Repaints all displayable window.
    */
+  @Override
   public void repaintUI(){
     Frame[] frames=Frame.getFrames();
     for (Frame frame : frames) {
@@ -761,6 +774,7 @@
       myDelegate = delegate;
     }
 
+    @Override
     public Popup getPopup(final Component owner, final Component contents, final int x, final int y) throws IllegalArgumentException {
       final Point point = fixPopupLocation(contents, x, y);
 
diff --git a/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java b/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java
index 2057169..ba61547 100644
--- a/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java
+++ b/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java
@@ -93,6 +93,7 @@
     init();
   }
 
+  @NotNull
   public List<T> showAndGetResult() {
     show();
     return getChosenElements();
diff --git a/platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java b/platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java
index cf6d25d..a743569 100644
--- a/platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java
@@ -75,6 +75,16 @@
   }
 
   @Override
+  public void setValue(@NotNull String name, @NotNull String value, @NotNull String defaultValue) {
+    if (value.equals(defaultValue)) {
+      myMap.remove(name);
+    }
+    else {
+      myMap.put(name, value);
+    }
+  }
+
+  @Override
   public void unsetValue(String name) {
     myMap.remove(name);
   }
diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
index 46ca05d..87f1b23 100644
--- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
+++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.idea;
 
+import com.intellij.ide.Bootstrap;
 import com.intellij.openapi.application.ApplicationInfo;
 import com.intellij.openapi.application.ApplicationNamesInfo;
 import com.intellij.openapi.application.ConfigImportHelper;
@@ -45,7 +46,7 @@
  * @author yole
  */
 public class StartupUtil {
-  @NonNls public static final String NO_SPLASH = "nosplash";
+  @NonNls public static final String NO_SPLASH = Bootstrap.NO_SPLASH;
 
   private static SocketLock ourLock;
   private static String myDefaultLAF;
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java
index 25882ae..273e580 100644
--- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java
+++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java
@@ -35,6 +35,7 @@
 
 @State(
   name = "UsagesStatistic",
+  roamingType = RoamingType.DISABLED,
   storages = {
     @Storage(
       file = StoragePathMacros.APP_CONFIG + "/usage.statistics.xml"
@@ -67,6 +68,7 @@
     }
   }
 
+  @Override
   public void loadState(final Element element) {
     List groupsList = element.getChildren(GROUP_TAG);
     for (Object project : groupsList) {
@@ -92,14 +94,15 @@
     }
 
     final String isAllowedValue = element.getAttributeValue(IS_ALLOWED_ATTR);
-    setAllowed(StringUtil.isEmptyOrSpaces(isAllowedValue) ? false : Boolean.parseBoolean(isAllowedValue));
+    setAllowed(!StringUtil.isEmptyOrSpaces(isAllowedValue) && Boolean.parseBoolean(isAllowedValue));
 
     final String isShowNotificationValue = element.getAttributeValue(SHOW_NOTIFICATION_ATTR);
-    setShowNotification(StringUtil.isEmptyOrSpaces(isShowNotificationValue) ? true : Boolean.parseBoolean(isShowNotificationValue));
+    setShowNotification(StringUtil.isEmptyOrSpaces(isShowNotificationValue) || Boolean.parseBoolean(isShowNotificationValue));
 
     setPeriod(parsePeriod(element.getAttributeValue(PERIOD_ATTR)));
   }
 
+  @Override
   public Element getState() {
     Element element = new Element("state");
 
@@ -162,6 +165,7 @@
     return Double.parseDouble(priority);
   }
 
+  @Override
   @NonNls
   @NotNull
   public String getComponentName() {
@@ -172,6 +176,7 @@
   public void initComponent() {
   }
 
+  @Override
   public void disposeComponent() {
   }
 }
diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
index e48e2bf..0fd0ab3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
@@ -29,13 +29,14 @@
 import com.intellij.openapi.application.ex.ApplicationEx;
 import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.components.ComponentConfig;
-import com.intellij.openapi.components.RoamingType;
 import com.intellij.openapi.components.StateStorageException;
 import com.intellij.openapi.components.impl.ApplicationPathMacroManager;
 import com.intellij.openapi.components.impl.ComponentManagerImpl;
-import com.intellij.openapi.components.impl.stores.*;
+import com.intellij.openapi.components.impl.stores.IApplicationStore;
+import com.intellij.openapi.components.impl.stores.IComponentStore;
+import com.intellij.openapi.components.impl.stores.StoreUtil;
+import com.intellij.openapi.components.impl.stores.StoresFactory;
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.extensions.ExtensionPoint;
 import com.intellij.openapi.extensions.ExtensionPointName;
 import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -518,8 +519,6 @@
       myIsFiringLoadingEvent = false;
     }
 
-    loadComponentRoamingTypes();
-
     HeavyProcessLatch.INSTANCE.processStarted();
     try {
       getStateStore().load();
@@ -559,23 +558,6 @@
     return super.getComponentFromContainer(interfaceClass);
   }
 
-  private static void loadComponentRoamingTypes() {
-    ExtensionPoint<RoamingTypeExtensionPointBean> point = Extensions.getRootArea().getExtensionPoint("com.intellij.ComponentRoamingType");
-    final RoamingTypeExtensionPointBean[] componentRoamingTypes = point.getExtensions();
-
-    for (RoamingTypeExtensionPointBean object : componentRoamingTypes) {
-
-      assert object.componentName != null;
-      assert object.roamingType != null;
-
-      final RoamingType type = RoamingType.valueOf(object.roamingType);
-
-      assert type != null;
-
-      ComponentRoamingManager.getInstance().setRoamingType(object.componentName, type);
-    }
-  }
-
   private void fireBeforeApplicationLoaded() {
     for (ApplicationLoadListener listener : ApplicationLoadListener.EP_NAME.getExtensions()) {
       try {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentRoamingManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentRoamingManager.java
index 3d60bca..e78fb56 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentRoamingManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentRoamingManager.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.
@@ -18,6 +18,8 @@
 import com.intellij.openapi.components.RoamingType;
 import com.intellij.util.ObjectUtils;
 import gnu.trove.THashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.Map;
 
@@ -30,15 +32,13 @@
     return OUR_INSTANCE;
   }
 
-  public RoamingType getRoamingType(String name) {
-    return ObjectUtils.notNull(myRoamingTypeMap.get(name), RoamingType.PER_USER);
+  public RoamingType getRoamingType(@Nullable String name) {
+    return name == null ? RoamingType.PER_USER : ObjectUtils.notNull(myRoamingTypeMap.get(name), RoamingType.PER_USER);
   }
 
-  public void setRoamingType(final String name, final RoamingType roamingType) {
-    myRoamingTypeMap.put(name, roamingType);
+  public void setRoamingType(@NotNull String name, @NotNull RoamingType roamingType) {
+    if (roamingType != RoamingType.PER_USER) {
+      myRoamingTypeMap.put(name, roamingType);
+    }
   }
-
-  public boolean typeSpecified(final String name) {
-    return myRoamingTypeMap.containsKey(name);
-  }
-}
+}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
index 4a6c0ac..f7b548e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
@@ -17,7 +17,7 @@
 
 import com.intellij.diagnostic.IdeErrorsDialog;
 import com.intellij.diagnostic.PluginException;
-import com.intellij.ide.plugins.PluginManager;
+import com.intellij.ide.plugins.PluginManagerCore;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.ex.ApplicationManagerEx;
 import com.intellij.openapi.components.*;
@@ -226,16 +226,8 @@
   private static Element getJdomState(final Object component, final String componentName, @NotNull final StateStorage defaultsStorage)
       throws StateStorageException {
     ComponentRoamingManager roamingManager = ComponentRoamingManager.getInstance();
-    if (!roamingManager.typeSpecified(componentName)) {
-      if (component instanceof RoamingTypeDisabled) {
-         roamingManager.setRoamingType(componentName, RoamingType.DISABLED);
-      }
-      else if (component instanceof RoamingTypePerPlatform) {
-        roamingManager.setRoamingType(componentName, RoamingType.PER_PLATFORM);
-      }
-      /*else {
-        roamingManager.setRoamingType(componentName, RoamingType.PER_USER);
-      }*/
+    if (component instanceof RoamingTypeDisabled) {
+      roamingManager.setRoamingType(componentName, RoamingType.DISABLED);
     }
     return defaultsStorage.getState(component, componentName, Element.class, null);
   }
@@ -261,13 +253,9 @@
   }
 
   private <T> String initPersistentComponent(@NotNull final PersistentStateComponent<T> component, final boolean reloadData) {
-    final String name = getComponentName(component);
-
-    RoamingType roamingTypeFromComponent = getRoamingType(component);
-    ComponentRoamingManager roamingManager = ComponentRoamingManager.getInstance();
-    if (!roamingManager.typeSpecified(name)) {
-      roamingManager.setRoamingType(name, roamingTypeFromComponent);
-    }
+    State spec = getStateSpec(component);
+    final String name = spec.name();
+    ComponentRoamingManager.getInstance().setRoamingType(name, spec.roamingType());
 
     doAddComponent(name, component);
     if (optimizeTestLoading()) return name;
@@ -283,7 +271,6 @@
     }
 
     Storage[] storageSpecs = getComponentStorageSpecs(component, StateStorageOperation.READ);
-
     for (Storage storageSpec : storageSpecs) {
       StateStorage stateStorage = getStateStorage(storageSpec);
       if (stateStorage == null || !stateStorage.hasState(component, name, stateClass, reloadData)) continue;
@@ -299,21 +286,6 @@
     return name;
   }
 
-  private static RoamingType getRoamingType(final PersistentStateComponent component) {
-    if (component instanceof RoamingTypeDisabled) {
-       return RoamingType.DISABLED;
-    }
-    else if (component instanceof RoamingTypePerPlatform) {
-      return RoamingType.PER_PLATFORM;
-    }
-
-    final State stateSpec = getStateSpec(component);
-    assert stateSpec != null;
-
-    return stateSpec.roamingType();
-
-  }
-
   @NotNull
   private static <T> Class<T> getComponentStateClass(@NotNull final PersistentStateComponent<T> persistentStateComponent) {
     final Class persistentStateComponentClass = PersistentStateComponent.class;
@@ -339,18 +311,15 @@
   }
 
   public static String getComponentName(@NotNull final PersistentStateComponent<?> persistentStateComponent) {
-    final State stateSpec = getStateSpec(persistentStateComponent);
-    if (stateSpec == null) {
-      LOG.error("Null state spec for " + persistentStateComponent);
-    }
-    return stateSpec.name();
+    return getStateSpec(persistentStateComponent).name();
   }
 
+  @NotNull
   private static <T> State getStateSpec(@NotNull final PersistentStateComponent<T> persistentStateComponent) {
     final Class<? extends PersistentStateComponent> aClass = persistentStateComponent.getClass();
     final State stateSpec = aClass.getAnnotation(State.class);
     if (stateSpec == null) {
-      final PluginId pluginId = PluginManager.getPluginByClassName(aClass.getName());
+      final PluginId pluginId = PluginManagerCore.getPluginByClassName(aClass.getName());
       if (pluginId != null) {
         throw new PluginException("No @State annotation found in " + aClass, pluginId);
       }
@@ -359,7 +328,6 @@
     return stateSpec;
   }
 
-
   @NotNull
   protected <T> Storage[] getComponentStorageSpecs(@NotNull final PersistentStateComponent<T> persistentStateComponent,
                                                    final StateStorageOperation operation) throws StateStorageException {
@@ -517,12 +485,8 @@
   public boolean isReloadPossible(@NotNull final Set<String> componentNames) {
     for (String componentName : componentNames) {
       final Object component = myComponents.get(componentName);
-
-      if (component != null) {
-        if (!(component instanceof PersistentStateComponent)) return false;
-
-        final State stateSpec = getStateSpec((PersistentStateComponent<? extends Object>)component);
-        if (stateSpec == null || !stateSpec.reloadable()) return false;
+      if (component != null && (!(component instanceof PersistentStateComponent) || !getStateSpec((PersistentStateComponent<?>)component).reloadable())) {
+        return false;
       }
     }
 
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentVersionListener.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentVersionListener.java
index f452d66..85b74fc 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentVersionListener.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentVersionListener.java
@@ -16,11 +16,5 @@
 package com.intellij.openapi.components.impl.stores;
 
 public interface ComponentVersionListener {
-  ComponentVersionListener EMPTY = new ComponentVersionListener(){
-    public void componentStateChanged(String componentName) {
-
-    }
-  } ;
-
   void componentStateChanged(String componentName);
 }
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java
index 827896f..7ee3a54 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java
@@ -140,7 +140,7 @@
         LOG.error(e);
       }
     }
-    final ExternalizationSession session = new MyExternalizationSession(myPathMacroSubstitutor, myStorageData.clone());
+    final ExternalizationSession session = new MyExternalizationSession(myStorageData.clone());
 
     mySession = session;
     return session;
@@ -330,7 +330,7 @@
   private class MyExternalizationSession implements ExternalizationSession {
     private final DirectoryStorageData myStorageData;
 
-    private MyExternalizationSession(final TrackingPathMacroSubstitutor pathMacroSubstitutor, final DirectoryStorageData storageData) {
+    private MyExternalizationSession(final DirectoryStorageData storageData) {
       myStorageData = storageData;
     }
 
@@ -344,16 +344,13 @@
     private void setState(final String componentName, @NotNull Object state, final Storage storageSpec) throws StateStorageException {
       try {
         final Element element = DefaultStateSerializer.serializeState(state, storageSpec);
-
-        final List<Pair<Element, String>> states = mySplitter.splitState(element);
-        for (Pair<Element, String> pair : states) {
+        for (Pair<Element, String> pair : mySplitter.splitState(element)) {
           Element e = pair.first;
           String name = pair.second;
 
           Element statePart = new Element(StorageData.COMPONENT);
           statePart.setAttribute(StorageData.NAME, componentName);
-          e.detach();
-          statePart.addContent(e);
+          statePart.addContent(e.detach());
 
           myStorageData.put(componentName, myDir.getChild(name), statePart, false);
         }
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
index f8cf115..75b0999 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
@@ -134,7 +134,9 @@
 
   public void resetProviderCache() {
     myProviderUpToDateHash = -1;
-    myProviderVersions = null;
+    if (myRemoteVersionProvider != null) {
+      myRemoteVersionProvider.myProviderVersions = null;
+    }
   }
 
   private class FileSaveSession extends MySaveSession {
@@ -322,7 +324,7 @@
 
   @Nullable
   public File updateFileExternallyFromStreamProviders() throws IOException {
-    StorageData loadedData = loadData(true, myListener);
+    StorageData loadedData = loadData(true);
     Document document = getDocument(loadedData);
     if (physicalContentNeedsSave(document)) {
       File file = new File(myFile.getAbsolutePath());
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java
index 68efd2e..f9ac272 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java
@@ -338,10 +338,14 @@
 
   @Override
   public String getPresentableUrl() {
-    if (myProject.isDefault()) return null;
+    if (myProject.isDefault()) {
+      return null;
+    }
     if (myPresentableUrl == null) {
-      final String url = myScheme == StorageScheme.DIRECTORY_BASED ? getProjectBasePath() : getProjectFilePath();
-      myPresentableUrl = url != null ? FileUtil.toSystemDependentName(url) : url;
+      String url = myScheme == StorageScheme.DIRECTORY_BASED ? getProjectBasePath() : getProjectFilePath();
+      if (url != null) {
+        myPresentableUrl = FileUtil.toSystemDependentName(url);
+      }
     }
     return myPresentableUrl;
   }
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
index 93d3e9a..499eda6 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
@@ -37,7 +37,7 @@
   TrackingPathMacroSubstitutor getMacroSubstitutor();
 
   @Nullable
-  StateStorage getStateStorage(@NotNull Storage storageSpec) throws StateStorageException;
+  StateStorage   getStateStorage(@NotNull Storage storageSpec) throws StateStorageException;
 
   @Nullable
   StateStorage getFileStateStorage(String fileName);
@@ -59,7 +59,7 @@
   String expandMacros(String file);
 
   @Deprecated
-  void registerStreamProvider(StreamProvider streamProvider, final RoamingType type);
+  void registerStreamProvider(@SuppressWarnings("deprecation") StreamProvider streamProvider, final RoamingType type);
 
   void setStreamProvider(@Nullable com.intellij.openapi.components.impl.stores.StreamProvider streamProvider);
 
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
index 186ba20..25c940a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
@@ -144,6 +144,9 @@
   public Collection<String> getStorageFileNames() {
     myStorageLock.lock();
     try {
+      if (myStorages.isEmpty()) {
+        return Collections.emptyList();
+      }
       return Collections.unmodifiableCollection(myStorages.keySet());
     }
     finally {
@@ -488,7 +491,7 @@
   }
 
   @Override
-  public void registerStreamProvider(com.intellij.openapi.options.StreamProvider streamProvider, final RoamingType type) {
+  public void registerStreamProvider(@SuppressWarnings("deprecation") com.intellij.openapi.options.StreamProvider streamProvider, final RoamingType type) {
     synchronized (myOldStreamProvider) {
       myOldStreamProvider.myStreamProviders.add(new OldStreamProviderAdapter(streamProvider, type));
     }
@@ -547,6 +550,11 @@
     private final List<OldStreamProviderAdapter> myStreamProviders = new SmartList<OldStreamProviderAdapter>();
 
     @Override
+    public boolean isVersioningRequired() {
+      return true;
+    }
+
+    @Override
     public boolean isEnabled() {
       for (StreamProvider provider : myStreamProviders) {
         if (provider.isEnabled()) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
index bf03cfb..cf77ee3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
@@ -15,6 +15,15 @@
   public abstract boolean isEnabled();
 
   /**
+   * If true, special version file per storage file will keep version of component.
+   * On load remote data will be ignored if local version of component is higher.
+   * If your storage is always in connected state (for example, git provides you local working copy), you don't need it.
+   */
+  public boolean isVersioningRequired() {
+    return false;
+  }
+
+  /**
    * fileSpec Only main fileSpec, not version
    */
   public boolean isApplicable(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
index 8c2c85b..650419f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
@@ -59,9 +59,7 @@
   private final Map<String, Object> myStorageComponentStates = new THashMap<String, Object>(); // at loading we store Element, on setState Integer of hash// at loading we store Element, on setState Integer of hash
 
   private final ComponentVersionProvider myLocalVersionProvider;
-  private final ComponentVersionProvider myRemoteVersionProvider;
-
-  protected TObjectLongHashMap<String> myProviderVersions;
+  protected final RemoteComponentVersionProvider myRemoteVersionProvider;
 
   protected ComponentVersionListener myListener = new ComponentVersionListener(){
     @Override
@@ -72,7 +70,7 @@
 
   private boolean myDisposed;
 
-  protected XmlElementStorage(@Nullable final TrackingPathMacroSubstitutor pathMacroSubstitutor,
+  protected XmlElementStorage(@Nullable TrackingPathMacroSubstitutor pathMacroSubstitutor,
                               @NotNull Disposable parentDisposable,
                               @NotNull String rootElementName,
                               @Nullable StreamProvider streamProvider,
@@ -86,24 +84,7 @@
     Disposer.register(parentDisposable, this);
 
     myLocalVersionProvider = localComponentVersionsProvider;
-
-    myRemoteVersionProvider = new ComponentVersionProvider() {
-      @Override
-      public long getVersion(String name) {
-        if (myProviderVersions == null) {
-          loadProviderVersions();
-        }
-        return myProviderVersions.get(name);
-      }
-
-      @Override
-      public void changeVersion(String name, long version) {
-        if (myProviderVersions == null) {
-          loadProviderVersions();
-        }
-        myProviderVersions.put(name, version);
-      }
-    };
+    myRemoteVersionProvider = streamProvider == null || !streamProvider.isVersioningRequired() ? null : new RemoteComponentVersionProvider();
   }
 
   protected boolean isDisposed() {
@@ -145,12 +126,12 @@
       return myLoadedData;
     }
 
-    myLoadedData = loadData(true, myListener);
+    myLoadedData = loadData(true);
     return myLoadedData;
   }
 
   @NotNull
-  protected StorageData loadData(boolean useProvidersData, @SuppressWarnings("UnusedParameters") ComponentVersionListener listener) throws StateStorageException {
+  protected StorageData loadData(boolean useProvidersData) throws StateStorageException {
     Document document = loadDocument();
     StorageData result = createStorageData();
 
@@ -158,10 +139,19 @@
       loadState(result, document.getRootElement());
     }
 
-    if (myStreamProvider != null && useProvidersData && myStreamProvider.isEnabled()) {
+    if (useProvidersData && myStreamProvider != null && myStreamProvider.isEnabled()) {
       for (RoamingType roamingType : RoamingType.values()) {
         if (roamingType != RoamingType.DISABLED && roamingType != RoamingType.GLOBAL) {
-          loadProviderData(result, roamingType, myStreamProvider);
+          try {
+            Document sharedDocument = StorageUtil.loadDocument(myStreamProvider.loadContent(myFileSpec, roamingType));
+            if (sharedDocument != null) {
+              filterOutOfDate(sharedDocument.getRootElement());
+              loadState(result, sharedDocument.getRootElement());
+            }
+          }
+          catch (Exception e) {
+            LOG.warn(e);
+          }
         }
       }
     }
@@ -169,19 +159,6 @@
     return result;
   }
 
-  private void loadProviderData(StorageData result, RoamingType roamingType, StreamProvider streamProvider) {
-    try {
-      Document sharedDocument = StorageUtil.loadDocument(streamProvider.loadContent(myFileSpec, roamingType));
-      if (sharedDocument != null) {
-        filterOutOfDateAndDisabledForRoamingComponents(sharedDocument.getRootElement(), roamingType);
-        loadState(result, sharedDocument.getRootElement());
-      }
-    }
-    catch (Exception e) {
-      LOG.warn(e);
-    }
-  }
-
   protected void loadState(final StorageData result, final Element element) throws StateStorageException {
     if (myPathMacroSubstitutor != null) {
       myPathMacroSubstitutor.expandPaths(element);
@@ -433,59 +410,57 @@
     }
 
     private boolean saveForProvider(@NotNull StreamProvider streamProvider) {
-      // it is not really correctly implemented - stream provider can save not the whole document, but only filtered (per roaming type)
-      // but right now it is not our case, so, we should refine it later, but it not leads to bug now
-      boolean result = false;
-      for (final RoamingType roamingType : RoamingType.values()) {
-        if (roamingType == RoamingType.DISABLED || !streamProvider.isApplicable(myFileSpec, roamingType)) {
-          continue;
-        }
+      if (!streamProvider.isApplicable(myFileSpec, RoamingType.PER_USER)) {
+        return false;
+      }
 
-        Document document = getDocumentToSave();
-        if (document.getRootElement().getChildren().isEmpty()) {
-          continue;
-        }
+      Document document = getDocumentToSave();
+      Element rootElement = document.getRootElement();
+      if (rootElement.getChildren().isEmpty()) {
+        return false;
+      }
 
-        Document actualDocument;
-        ElementFilter roamingFilter = new ElementFilter(StorageData.COMPONENT) {
-          @Override
-          public boolean matches(Object obj) {
-            return super.matches(obj) && myComponentRoamingManager.getRoamingType(((Element)obj).getAttributeValue(StorageData.NAME)) != roamingType;
-          }
-        };
+      // skip the whole document if some component has disabled roaming type
+      // you must not store components with different roaming types in one document
+      // one exclusion: workspace file (you don't have choice in this case)
+      // for example, it is important for ICS ProjectId - we cannot keep project in another place,
+      // but this project id must not be shared
+      if (!myFileSpec.equals(StoragePathMacros.WORKSPACE_FILE) &&
+          rootElement.getContent(new RoamingElementFilter(RoamingType.DISABLED)).iterator().hasNext()) {
+        return false;
+      }
 
-        if (document.getRootElement().getContent(roamingFilter).iterator().hasNext()) {
-          actualDocument = document.clone();
-          Iterator<Element> iterator = actualDocument.getRootElement().getContent(roamingFilter).iterator();
-          while (iterator.hasNext()) {
-            iterator.next();
-            iterator.remove();
-          }
+      RoamingElementFilter perPlatformFilter = new RoamingElementFilter(RoamingType.PER_PLATFORM);
+      if (rootElement.getContent(perPlatformFilter).iterator().hasNext()) {
+        return doSaveForProvider(rootElement, new RoamingElementFilter(RoamingType.PER_USER)) ||
+               doSaveForProvider(rootElement, perPlatformFilter);
+      }
+      else {
+        return doSaveForProvider(document, RoamingType.PER_USER, streamProvider);
+      }
+    }
 
-          if (actualDocument.getRootElement().getChildren().isEmpty()) {
-            continue;
-          }
-        }
-        else {
-          actualDocument = document;
-        }
+    private boolean doSaveForProvider(Element element, RoamingElementFilter filter) {
+      Element copiedElement = JDOMUtil.cloneElement(element, filter);
+      return copiedElement != null && doSaveForProvider(new Document(copiedElement), filter.myRoamingType, myStreamProvider);
+    }
 
-        try {
-          if (StorageUtil.doSendContent(streamProvider, myFileSpec, actualDocument, roamingType, true)) {
-            result = true;
-          }
+    private boolean doSaveForProvider(Document actualDocument, RoamingType roamingType, StreamProvider streamProvider) {
+      try {
+        boolean result = StorageUtil.doSendContent(streamProvider, myFileSpec, actualDocument, roamingType, true);
+        if (streamProvider.isVersioningRequired()) {
           TObjectLongHashMap<String> versions = loadVersions(actualDocument.getRootElement().getChildren(StorageData.COMPONENT));
           if (!versions.isEmpty()) {
             Document versionDoc = new Document(StateStorageManagerImpl.createComponentVersionsXml(versions));
             StorageUtil.doSendContent(streamProvider, myFileSpec + VERSION_FILE_SUFFIX, versionDoc, roamingType, true);
           }
         }
-        catch (IOException e) {
-          LOG.warn(e);
-        }
+        return result;
       }
-
-      return result;
+      catch (IOException e) {
+        LOG.warn(e);
+        return false;
+      }
     }
 
     private boolean isHashUpToDate(final Integer hash) {
@@ -527,6 +502,21 @@
 
       return null;
     }
+
+    private class RoamingElementFilter extends ElementFilter {
+      final RoamingType myRoamingType;
+
+      public RoamingElementFilter(RoamingType roamingType) {
+        super(StorageData.COMPONENT);
+
+        myRoamingType = roamingType;
+      }
+
+      @Override
+      public boolean matches(Object obj) {
+        return super.matches(obj) && myComponentRoamingManager.getRoamingType(((Element)obj).getAttributeValue(StorageData.NAME)) == myRoamingType;
+      }
+    }
   }
 
   private TObjectLongHashMap<String> loadVersions(List<Element> elements) {
@@ -554,7 +544,7 @@
 
   @Override
   public void reload(@NotNull final Set<String> changedComponents) throws StateStorageException {
-    final StorageData storageData = loadData(false, myListener);
+    final StorageData storageData = loadData(false);
 
     final StorageData oldLoadedData = myLoadedData;
 
@@ -578,12 +568,16 @@
     myLoadedData = storageData;
   }
 
-  private void filterOutOfDateAndDisabledForRoamingComponents(Element element, RoamingType roamingType) {
+  private void filterOutOfDate(Element element) {
+    if (myRemoteVersionProvider == null) {
+      return;
+    }
+
     Iterator<Element> iterator = element.getContent(new ElementFilter(StorageData.COMPONENT)).iterator();
     while (iterator.hasNext()) {
       String name = iterator.next().getAttributeValue(StorageData.NAME);
-      long remoteVersion;
-      if (myComponentRoamingManager.getRoamingType(name) != roamingType || (remoteVersion = myRemoteVersionProvider.getVersion(name)) <= myLocalVersionProvider.getVersion(name)) {
+      long remoteVersion = myRemoteVersionProvider.getVersion(name);
+      if (remoteVersion <= myLocalVersionProvider.getVersion(name)) {
         iterator.remove();
       }
       else {
@@ -592,30 +586,50 @@
     }
   }
 
-  private void loadProviderVersions() {
-    if (myStreamProvider == null) {
-      return;
+  @Nullable
+  Document logComponents() throws StateStorageException {
+    return mySession instanceof MySaveSession ? getDocument(((MySaveSession)mySession).myStorageData) : null;
+  }
+
+  protected class RemoteComponentVersionProvider implements ComponentVersionProvider {
+    protected TObjectLongHashMap<String> myProviderVersions;
+
+    @Override
+    public long getVersion(String name) {
+      if (myProviderVersions == null) {
+        loadProviderVersions();
+      }
+      return myProviderVersions == null ? -1 : myProviderVersions.get(name);
     }
 
-    myProviderVersions = new TObjectLongHashMap<String>();
-    for (RoamingType type : RoamingType.values()) {
-      Document doc = null;
-      if (myStreamProvider.isEnabled()) {
+    @Override
+    public void changeVersion(String name, long version) {
+      if (myProviderVersions == null) {
+        loadProviderVersions();
+      }
+      if (myProviderVersions != null) {
+        myProviderVersions.put(name, version);
+      }
+    }
+
+    private void loadProviderVersions() {
+      assert myStreamProvider != null;
+      if (!myStreamProvider.isEnabled()) {
+        return;
+      }
+
+      myProviderVersions = new TObjectLongHashMap<String>();
+      for (RoamingType type : RoamingType.values()) {
         try {
-          doc = StorageUtil.loadDocument(myStreamProvider.loadContent(myFileSpec + VERSION_FILE_SUFFIX, type));
+          Document doc = StorageUtil.loadDocument(myStreamProvider.loadContent(myFileSpec + VERSION_FILE_SUFFIX, type));
+          if (doc != null) {
+            StateStorageManagerImpl.loadComponentVersions(myProviderVersions, doc);
+          }
         }
         catch (IOException e) {
           LOG.debug(e);
         }
       }
-      if (doc != null) {
-        StateStorageManagerImpl.loadComponentVersions(myProviderVersions, doc);
-      }
     }
   }
-
-  @Nullable
-  Document logComponents() throws StateStorageException {
-    return mySession instanceof MySaveSession ? getDocument(((MySaveSession)mySession).myStorageData) : null;
-  }
 }
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
index 2fff109..dafe24d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
@@ -35,14 +35,16 @@
 public class EditorHighlighterFactoryImpl extends EditorHighlighterFactory {
   private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.highlighter.EditorHighlighterFactoryImpl");
 
+  @NotNull
   @Override
-  public EditorHighlighter createEditorHighlighter(SyntaxHighlighter highlighter, final EditorColorsScheme colors) {
+  public EditorHighlighter createEditorHighlighter(SyntaxHighlighter highlighter, @NotNull final EditorColorsScheme colors) {
     if (highlighter == null) highlighter = new PlainSyntaxHighlighter();
     return new LexerEditorHighlighter(highlighter, colors);
   }
 
+  @NotNull
   @Override
-  public EditorHighlighter createEditorHighlighter(final FileType fileType, final EditorColorsScheme settings, final Project project) {
+  public EditorHighlighter createEditorHighlighter(@NotNull final FileType fileType, @NotNull final EditorColorsScheme settings, final Project project) {
     if (fileType instanceof LanguageFileType) {
       return FileTypeEditorHighlighterProviders.INSTANCE.forFileType(fileType).getEditorHighlighter(project, fileType, null, settings);
     }
@@ -51,11 +53,13 @@
     return createEditorHighlighter(highlighter, settings);
   }
 
+  @NotNull
   @Override
-  public EditorHighlighter createEditorHighlighter(final Project project, final FileType fileType) {
+  public EditorHighlighter createEditorHighlighter(final Project project, @NotNull final FileType fileType) {
     return createEditorHighlighter(fileType, EditorColorsManager.getInstance().getGlobalScheme(), project);
   }
 
+  @NotNull
   @Override
   public EditorHighlighter createEditorHighlighter(@NotNull VirtualFile vFile, @NotNull EditorColorsScheme settings, @Nullable Project project) {
     FileType fileType = vFile.getFileType();
@@ -105,18 +109,21 @@
     return fileType;
   }
 
+  @NotNull
   @Override
-  public EditorHighlighter createEditorHighlighter(final Project project, final VirtualFile file) {
+  public EditorHighlighter createEditorHighlighter(final Project project, @NotNull final VirtualFile file) {
     return createEditorHighlighter(file, EditorColorsManager.getInstance().getGlobalScheme(), project);
   }
 
+  @NotNull
   @Override
-  public EditorHighlighter createEditorHighlighter(final Project project, final String fileName) {
+  public EditorHighlighter createEditorHighlighter(final Project project, @NotNull final String fileName) {
     return createEditorHighlighter(EditorColorsManager.getInstance().getGlobalScheme(), fileName, project);
   }
 
+  @NotNull
   @Override
-  public EditorHighlighter createEditorHighlighter(final EditorColorsScheme settings, final String fileName, @Nullable final Project project) {
+  public EditorHighlighter createEditorHighlighter(@NotNull final EditorColorsScheme settings, @NotNull final String fileName, @Nullable final Project project) {
     return createEditorHighlighter(new LightVirtualFile(fileName), settings, project);
   }
 }
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java
index f149e0a..e849363 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java
@@ -34,19 +34,23 @@
   @Override
   protected void paintComponent(Graphics g) {
     super.paintComponent(g);
-    Color GRADIENT_C1 = new JBColor(getBackground(), JBColor.background());
+    paintGradient(g, this);
+  }
+
+  public static void paintGradient(Graphics g, JComponent c) {
+    Color GRADIENT_C1 = new JBColor(c.getBackground(), JBColor.background());
     Color GRADIENT_C2 = new JBColor(new Color(Math.max(0, GRADIENT_C1.getRed() - 0x18), Math.max(0, GRADIENT_C1.getGreen() - 0x18),
                                               Math.max(0, GRADIENT_C1.getBlue() - 0x18)), Gray._75);
 
     final Graphics2D g2d = (Graphics2D)g;
 
     if (!UIUtil.isUnderGTKLookAndFeel()) {
-      g2d.setPaint(UIUtil.getGradientPaint(0, 0, GRADIENT_C1, 0, getHeight(), GRADIENT_C2));
-      g2d.fillRect(1, 1, getWidth(), getHeight() - 1);
+      g2d.setPaint(UIUtil.getGradientPaint(0, 0, GRADIENT_C1, 0, c.getHeight(), GRADIENT_C2));
+      g2d.fillRect(1, 1, c.getWidth(), c.getHeight() - 1);
       g2d.setPaint(null);
     }
 
     g.setColor(UIUtil.getBorderColor());
-    g.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
+    g.drawLine(0, c.getHeight() - 1, c.getWidth(), c.getHeight() - 1);
   }
 }
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
index ea637b2..d233f37 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
@@ -94,7 +94,7 @@
   EditorMarkupModelImpl(@NotNull EditorImpl editor) {
     super(editor.getDocument());
     myEditor = editor;
-    myEditorFragmentRenderer = new EditorFragmentRenderer(0, Collections.<RangeHighlighterEx>emptyList(), 0);
+    myEditorFragmentRenderer = new EditorFragmentRenderer();
   }
 
   private int offsetToLine(int offset, Document document) {
@@ -184,7 +184,7 @@
       collectRangeHighlighters(this, line, highlighters);
       collectRangeHighlighters((MarkupModelEx)DocumentMarkupModel.forDocument(myEditor.getDocument(), getEditor().getProject(), true), line,
                                highlighters);
-      myEditorFragmentRenderer.update(line, highlighters, 0);
+      myEditorFragmentRenderer.update(line, highlighters);
       HintHint hint = new HintHint(me).setAwtTooltip(true).setPreferredPosition(Balloon.Position.atLeft).setShowImmediately(true)
         .setAnimationEnabled(false);
       myEditorFragmentRenderer.show(myEditor, me.getPoint(), true, ERROR_STRIPE_TOOLTIP_GROUP, hint);
@@ -267,9 +267,11 @@
   private void doClick(final MouseEvent e) {
     RangeHighlighter marker = getNearestRangeHighlighter(e);
     int offset;
+    LogicalPosition logicalPositionToScroll = null;
     if (marker == null) {
       if (myEditorPreviewHint != null) {
-        offset = myEditor.getDocument().getLineStartOffset(getLineByEvent(e)/*myEditorFragmentRenderer.myLine*/);
+        logicalPositionToScroll = myEditor.visualToLogicalPosition(new VisualPosition(myEditorFragmentRenderer.myStartLine, 0));
+        offset = myEditor.getDocument().getLineStartOffset(logicalPositionToScroll.line);
       } else {
         return;
       }
@@ -281,7 +283,7 @@
     if (doc.getLineCount() > 0 && myEditorPreviewHint == null) {
       // Necessary to expand folded block even if navigating just before one
       // Very useful when navigating to first unused import statement.
-      int lineEnd = doc.getLineEndOffset(myEditorFragmentRenderer.myLine);
+      int lineEnd = doc.getLineEndOffset(doc.getLineNumber(offset));
       myEditor.getCaretModel().moveToOffset(lineEnd);
     }
 
@@ -289,8 +291,8 @@
     myEditor.getSelectionModel().removeSelection();
     ScrollingModel scrollingModel = myEditor.getScrollingModel();
     scrollingModel.disableAnimation();
-    if (myEditorPreviewHint != null) {
-      int lineY = myEditor.logicalPositionToXY(new LogicalPosition(myEditorFragmentRenderer.myStartLine, 0)).y;
+    if (logicalPositionToScroll != null) {
+      int lineY = myEditor.logicalPositionToXY(logicalPositionToScroll).y;
       int relativePopupOffset = myEditorFragmentRenderer.myRelativeY;
       scrollingModel.scrollVertically(lineY - relativePopupOffset);
     }
@@ -1014,20 +1016,18 @@
   private class EditorFragmentRenderer implements TooltipRenderer {
     private int myLine;
     private Collection<RangeHighlighterEx> myHighlighters;
-    private int myMouseX;
     private BufferedImage myImage;
     private int myStartLine;
     private int myEndLine;
     private int myRelativeY;
 
-    private EditorFragmentRenderer(int currentLine, Collection<RangeHighlighterEx> rangeHighlighters, int mouseX) {
-      update(currentLine, rangeHighlighters, mouseX);
+    private EditorFragmentRenderer() {
+      update(0, Collections.<RangeHighlighterEx>emptyList());
     }
 
-    public void update(int currentLine, Collection<RangeHighlighterEx> rangeHighlighters, int mouseX) {
+    public void update(int currentLine, Collection<RangeHighlighterEx> rangeHighlighters) {
       myLine = currentLine;
       myHighlighters = rangeHighlighters;
-      myMouseX = mouseX;
       myImage = null;
       myStartLine = Math.max(0, myLine - myPreviewLines);
       myEndLine = Math.min(myEditor.getDocument().getLineCount() - 1, myLine + myPreviewLines + 1);
@@ -1043,13 +1043,13 @@
       if (myEditorPreviewHint == null) {
         final JPanel editorFragmentPreviewPanel = new JPanel() {
           private static final int R = 6;
-
+          private static final int LEFT_INDENT = BalloonImpl.ARC + 5;
 
           @Override
           public Dimension getPreferredSize() {
             int width = myEditor.getGutterComponentEx().getWidth();
             width += Math.min(myEditor.getScrollingModel().getVisibleArea().width, myEditor.getContentComponent().getWidth());
-            return new Dimension(width - BalloonImpl.POINTER_WIDTH, myEditor.getLineHeight() * (myEndLine - myStartLine));
+            return new Dimension(width - BalloonImpl.POINTER_WIDTH - LEFT_INDENT, myEditor.getLineHeight() * (myEndLine - myStartLine));
           }
 
           @Override
@@ -1077,7 +1077,7 @@
                   exs.add(rangeHighlighter);
                 }
               }
-              AffineTransform translateInstance = AffineTransform.getTranslateInstance(myMouseX, lineShift);
+              AffineTransform translateInstance = AffineTransform.getTranslateInstance(-LEFT_INDENT, lineShift);
               translateInstance.preConcatenate(transform);
               g2d.setTransform(translateInstance);
               EditorGutterComponentEx gutterComponentEx = myEditor.getGutterComponentEx();
@@ -1086,7 +1086,7 @@
               gutterComponentEx.paint(g2d);
               JComponent contentComponent = myEditor.getContentComponent();
               g2d.setClip(width, 0, contentComponent.getWidth(), contentComponent.getHeight());
-              translateInstance = AffineTransform.getTranslateInstance(width - myMouseX, lineShift);
+              translateInstance = AffineTransform.getTranslateInstance(width - LEFT_INDENT, lineShift);
               translateInstance.preConcatenate(transform);
               g2d.setTransform(translateInstance);
               contentComponent.paint(g2d);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/PlatformFileTypeFactory.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/PlatformFileTypeFactory.java
index ad5fd0f..7f550f9 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/PlatformFileTypeFactory.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/PlatformFileTypeFactory.java
@@ -25,7 +25,7 @@
 public class PlatformFileTypeFactory extends FileTypeFactory {
   public void createFileTypes(@NotNull final FileTypeConsumer consumer) {
     consumer.consume(ArchiveFileType.INSTANCE, "zip;jar;war;ear;swc;ane;egg;apk");
-    consumer.consume(PlainTextFileType.INSTANCE, "txt;sh;bat;cmd;policy;log;cgi;MF;jad;jam;htaccess");
+    consumer.consume(PlainTextFileType.INSTANCE, "txt;sh;bat;cmd;policy;log;cgi;MF;jad;jam;htaccess;rb");
     consumer.consume(NativeFileType.INSTANCE, "doc;docx;xls;xlsx;ppt;pptx;mdb;vsd;pdf;hlp;chm;odt");
     consumer.consume(UnknownFileType.INSTANCE);
   }
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java
index 4965ae0..f77ab13 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java
@@ -18,7 +18,7 @@
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.actionMacro.ActionMacro;
 import com.intellij.ide.plugins.IdeaPluginDescriptor;
-import com.intellij.ide.plugins.PluginManager;
+import com.intellij.ide.plugins.PluginManagerCore;
 import com.intellij.ide.ui.search.SearchUtil;
 import com.intellij.openapi.actionSystem.*;
 import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
@@ -69,7 +69,7 @@
     final KeymapManagerEx keymapManager = KeymapManagerEx.getInstanceEx();
     ActionManagerEx managerEx = ActionManagerEx.getInstanceEx();
     final List<IdeaPluginDescriptor> plugins = new ArrayList<IdeaPluginDescriptor>();
-    Collections.addAll(plugins, PluginManager.getPlugins());
+    Collections.addAll(plugins, PluginManagerCore.getPlugins());
     Collections.sort(plugins, new Comparator<IdeaPluginDescriptor>() {
       public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) {
         return o1.getName().compareTo(o2.getName());
@@ -150,7 +150,7 @@
           return filter == null ? !actionBound : !actionBound && filter.value(action);
         }
 
-        return filter == null ? true : filter.value(action);
+        return filter == null || filter.value(action);
       }
     };
   }
@@ -214,9 +214,11 @@
                           ? ((DefaultActionGroup)actionGroup).getChildActionsOrStubs()
                           : actionGroup.getChildren(null);
 
-    for (int i = 0; i < children.length; i++) {
-      AnAction action = children[i];
-      LOG.assertTrue(action != null, groupName + " contains null actions");
+    for (AnAction action : children) {
+      if (action == null) {
+        LOG.error(groupName + " contains null actions");
+        continue;
+      }
       if (action instanceof ActionGroup) {
         Group subGroup = createGroup((ActionGroup)action, getName(action), null, null, ignore, filtered, normalizeSeparators);
         if (subGroup.getSize() > 0) {
@@ -234,7 +236,7 @@
       else if (action instanceof Separator) {
         group.addSeparator();
       }
-      else if (action != null) {
+      else {
         String id = action instanceof ActionStub ? ((ActionStub)action).getId() : actionManager.getId(action);
         if (id != null) {
           if (id.startsWith(TOOL_ACTION_PREFIX)) continue;
@@ -490,7 +492,7 @@
             .isComponentHighlighted(lowerText, insensitiveFilter, force, null)) {
             return true;
           }
-          else if (lowerText.indexOf(insensitiveFilter) != -1) {
+          else if (lowerText.contains(insensitiveFilter)) {
             return true;
           }
         }
@@ -501,7 +503,7 @@
             .isComponentHighlighted(insensitiveDescription, insensitiveFilter, force, null)) {
             return true;
           }
-          else if (insensitiveDescription.indexOf(insensitiveFilter) != -1) {
+          else if (insensitiveDescription.contains(insensitiveFilter)) {
             return true;
           }
         }
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SchemeImporterEP.java b/platform/platform-impl/src/com/intellij/openapi/options/SchemeImporterEP.java
new file mode 100644
index 0000000..4202ee4
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/options/SchemeImporterEP.java
@@ -0,0 +1,91 @@
+/*
+ * 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.openapi.options;
+
+import com.intellij.openapi.extensions.AbstractExtensionPointBean;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.util.LazyInstance;
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+public class SchemeImporterEP <S extends Scheme> extends AbstractExtensionPointBean {
+  
+  public static ExtensionPointName<SchemeImporterEP> EP_NAME = ExtensionPointName.create("com.intellij.schemeImporter");
+
+  @Attribute("name")
+  public String name;
+
+  @Attribute("schemeClass")
+  public String schemeClass;
+
+  @Attribute("implementationClass")
+  public String implementationClass;
+
+  private final LazyInstance<SchemeImporter<S>> myImporterInstance = new LazyInstance<SchemeImporter<S>>() {
+    @Override
+    protected Class<SchemeImporter<S>> getInstanceClass() throws ClassNotFoundException {
+      return findClass(implementationClass);
+    }
+  };
+  
+  public SchemeImporter<S> getInstance() {
+    return myImporterInstance.getValue();
+  }
+
+  /**
+   * Finds extensions supporting the given <code>schemeClass</code>
+   * @param schemeClass The class of the scheme to search extensions for.
+   * @return A collection of importers capable of importing schemes of the given class. An empty collection is returned if there are
+   *         no matching importers.
+   */
+  @NotNull
+  public static <S extends Scheme> Collection<SchemeImporterEP<S>> getExtensions(Class<S> schemeClass) {
+    List<SchemeImporterEP<S>> importers = new ArrayList<SchemeImporterEP<S>>();
+    for (SchemeImporterEP<?> importerEP : EP_NAME.getExtensions()) {
+      if (schemeClass.getName().equals(importerEP.schemeClass)) {
+        //noinspection unchecked
+        importers.add((SchemeImporterEP<S>)importerEP);
+      }
+    }
+    return importers;
+  }
+
+
+  /**
+   * Find an importer for the given name and scheme class. It is allowed for importers to have the same name but different scheme classes.
+   * @param name        The importer name as defined in plug-in configuration.
+   * @param schemeClass The scheme class the importer has to support.
+   * @return The found importer or null if there are no importers for the given name and scheme class.
+   */
+  @Nullable
+  public static <S extends Scheme> SchemeImporter<S> getImporter(@NotNull String name, Class<S> schemeClass) {
+    for (SchemeImporterEP<S> importerEP : getExtensions(schemeClass)) {
+      if (name.equals(importerEP.name)) {
+        return importerEP.getInstance();
+      }
+    }
+    return null;
+  }
+
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java
index d2a5e85..376cfcf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java
@@ -572,7 +572,7 @@
     schemeKey.getExternalInfo().setCurrentFileName(fileName);
   }
 
-  private static long computeHashValue(final Document document) throws IOException {
+  private static long computeHashValue(final Document document) {
     return JDOMUtil.getTreeHash(document);
   }
 
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java
index 063cb2f..42495b5 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java
@@ -236,7 +236,7 @@
     if (actualNames != null) {
       String currentName = child.getName();
       String actualName = actualNames.get(currentName);
-      if (!currentName.equals(actualName)) {
+      if (actualName != null && !currentName.equals(actualName)) {
         scheduleAttributeChange(child, VirtualFile.PROP_NAME, currentName, actualName);
       }
     }
diff --git a/platform/platform-impl/src/com/intellij/ui/CellRendererPanel.java b/platform/platform-impl/src/com/intellij/ui/CellRendererPanel.java
new file mode 100644
index 0000000..cf488e1
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ui/CellRendererPanel.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 com.intellij.ui;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * Cell renderer CPU optimization.
+ * @see javax.swing.table.DefaultTableCellRenderer#invalidate()
+ *
+ * @author gregsh
+ */
+public class CellRendererPanel extends JPanel {
+  // BEGIN no validation methods --------------
+  @Override
+  public void doLayout() {
+    if (getComponentCount() != 1) return;
+    getComponent(0).setBounds(0, 0, getWidth(), getHeight());
+  }
+
+  @Override
+  public Dimension getPreferredSize() {
+    if (getComponentCount() != 1) return super.getPreferredSize();
+    return getComponent(0).getPreferredSize();
+  }
+
+  public void invalidate() {
+  }
+
+  public void validate() {
+    doLayout();
+  }
+
+  public void revalidate() {
+  }
+
+  public void repaint(long tm, int x, int y, int width, int height) {
+  }
+
+  public void repaint(Rectangle r) {
+  }
+
+  public void repaint() {
+  }
+
+// END no validation methods --------------
+}
diff --git a/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java b/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java
index fe649b3..5a07cbd 100644
--- a/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java
+++ b/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java
@@ -31,7 +31,7 @@
 /**
  * @author gregsh
  */
-public abstract class EditorTextFieldCellRenderer extends JPanel implements TableCellRenderer, Disposable {
+public abstract class EditorTextFieldCellRenderer extends CellRendererPanel implements TableCellRenderer, Disposable {
 
   private EditorEx myEditor;
 
@@ -112,40 +112,6 @@
     ((EditorImpl)editor).resetSizes();
   }
 
-  // BEGIN no validation methods --------------
-  @Override
-  public void doLayout() {
-    if (getComponentCount() != 1) return;
-    getComponent(0).setBounds(0, 0, getWidth(), getHeight());
-  }
-
-  @Override
-  public Dimension getPreferredSize() {
-    if (getComponentCount() != 1) return super.getPreferredSize();
-    return getComponent(0).getPreferredSize();
-  }
-
-  public void invalidate() {
-  }
-
-  public void validate() {
-    doLayout();
-  }
-
-  public void revalidate() {
-  }
-
-  public void repaint(long tm, int x, int y, int width, int height) {
-  }
-
-  public void repaint(Rectangle r) {
-  }
-
-  public void repaint() {
-  }
-
-// END no validation methods --------------
-
   private static class MyDocument extends UserDataHolderBase implements DocumentEx {
 
     RangeMarkerTree<RangeMarkerEx> myRangeMarkers = new RangeMarkerTree<RangeMarkerEx>(this) {};
diff --git a/platform/platform-impl/src/com/intellij/ui/GotItMessage.java b/platform/platform-impl/src/com/intellij/ui/GotItMessage.java
index 6580d0c..d44318b 100644
--- a/platform/platform-impl/src/com/intellij/ui/GotItMessage.java
+++ b/platform/platform-impl/src/com/intellij/ui/GotItMessage.java
@@ -41,11 +41,13 @@
                        @NotNull String message                       ) {
     myTitle = title;
     final String[] lines = message.split("\n");
-    if (lines.length > 1) {
-      myMessage = "<html><div align='center'>" + message.replace("\n", "<br>") + "</div></html>";
-    } else {
-      myMessage = message;
-    }
+
+    StringBuffer buf = new StringBuffer("<html><body><div align='center' style=\"font-family: ")
+      .append(UIUtil.getLabelFont().getFontName()).append("; ")
+      .append("font-size: 12pt;\">")
+      .append(lines.length > 1 ? message.replace("\n", "<br>") : message)
+      .append("</div></body></html>");
+    myMessage = buf.toString();
   }
 
   public static GotItMessage createMessage(@NotNull String title,
@@ -86,6 +88,7 @@
       .setHideOnFrameResize(false)
       .setHideOnKeyOutside(false)
       .setShowCallout(myShowCallout)
+      .setBlockClicksThroughBalloon(true)
       .createBalloon();
     panel.myButton.addMouseListener(new MouseAdapter() {
       @Override
diff --git a/platform/platform-impl/src/com/intellij/ui/GotItPanel.form b/platform/platform-impl/src/com/intellij/ui/GotItPanel.form
index 0fda696..2c6f5d7 100644
--- a/platform/platform-impl/src/com/intellij/ui/GotItPanel.form
+++ b/platform/platform-impl/src/com/intellij/ui/GotItPanel.form
@@ -24,13 +24,15 @@
           <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
         </constraints>
       </vspacer>
-      <component id="1102e" class="javax.swing.JLabel" binding="myMessage">
+      <component id="10cce" class="javax.swing.JEditorPane" binding="myMessage" custom-create="true">
         <constraints>
           <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
+          <contentType value="text/html"/>
           <font size="12"/>
-          <text value="Text text text text"/>
+          <opaque value="false"/>
+          <text value="&lt;html&gt;&#13;&#10;  &lt;head&gt;&#13;&#10;    &#13;&#10;  &lt;/head&gt;&#13;&#10;  &lt;body&gt;&#13;&#10;    &lt;p style=&quot;margin-top: 0&quot;&gt;&#13;&#10;      Test test test&#13;&#10;    &lt;/p&gt;&#13;&#10;  &lt;/body&gt;&#13;&#10;&lt;/html&gt;&#13;&#10;"/>
         </properties>
       </component>
       <grid id="fd7bc" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
diff --git a/platform/platform-impl/src/com/intellij/ui/GotItPanel.java b/platform/platform-impl/src/com/intellij/ui/GotItPanel.java
index 20c43fa..a2bb792 100644
--- a/platform/platform-impl/src/com/intellij/ui/GotItPanel.java
+++ b/platform/platform-impl/src/com/intellij/ui/GotItPanel.java
@@ -16,6 +16,7 @@
 package com.intellij.ui;
 
 import com.intellij.util.ui.GraphicsUtil;
+import com.intellij.util.ui.UIUtil;
 
 import javax.swing.*;
 import java.awt.*;
@@ -27,7 +28,8 @@
   JPanel myButton;
   JPanel myRoot;
   JLabel myTitle;
-  JLabel myMessage;
+  JEditorPane myMessage;
+
 
   private void createUIComponents() {
     myButton = new JPanel(new BorderLayout()) {
@@ -45,5 +47,10 @@
         g.drawRoundRect(0,0,getWidth()-1, getHeight()-1, 5,5);
       }
     };
+    myMessage = new JEditorPane("text/html", "<html></html>");
+    myMessage.setEditorKit(UIUtil.getHTMLEditorKit());
+    myMessage.setEditable(false);
+    myMessage.addHyperlinkListener(new BrowserHyperlinkListener());
+    myMessage.setFont(UIUtil.getLabelFont().deriveFont(UIUtil.getLabelFont().getSize() + 2f));
   }
 }
diff --git a/platform/platform-impl/src/com/intellij/ui/TreeSpeedSearch.java b/platform/platform-impl/src/com/intellij/ui/TreeSpeedSearch.java
index 2594f91..c44488b 100644
--- a/platform/platform-impl/src/com/intellij/ui/TreeSpeedSearch.java
+++ b/platform/platform-impl/src/com/intellij/ui/TreeSpeedSearch.java
@@ -16,9 +16,9 @@
 package com.intellij.ui;
 
 import com.intellij.ide.util.treeView.NodeDescriptor;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.containers.Convertor;
 import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.ArrayUtilRt;
+import com.intellij.util.containers.Convertor;
 import com.intellij.util.ui.tree.TreeUtil;
 
 import javax.swing.*;
@@ -86,7 +86,7 @@
   @Override
   protected int getSelectedIndex() {
     if (myCanExpand) {
-      return ArrayUtil.find(getAllElements(), myComponent.getSelectionPath());
+      return ArrayUtilRt.find(getAllElements(), myComponent.getSelectionPath());
     }
     int[] selectionRows = myComponent.getSelectionRows();
     return selectionRows == null || selectionRows.length == 0 ? -1 : selectionRows[0];
diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties
index 520aeaa..ecf9703 100644
--- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties
+++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties
@@ -460,6 +460,14 @@
 button.edit.global.settings=Edit Global Settings...
 label.edit.per.project.or.global.code.style=<html><body>Check option above on for per-project code style configuration<br>or use global code style. Global code style settings can be configured<br>in IDE Settings/Global Code Style</body></html>
 title.project.code.style=Project\nCode Style
+title.code.style.settings.import=Settings Import
+title.import.scheme.from=Import From
+import.scheme.shared=Shared Scheme
+message.code.style.scheme.already.exists=Scheme {0} already exists. Overwrite settings?
+code.style.scheme.import.unnamed=Unnamed
+message.code.style.scheme.import.success={0} settings were imported to {1} scheme.
+message.code.style.scheme.import.failure={0} import failed with error message: {1}
+
 label.name=Name:
 error.scheme.must.have.a.name=Scheme must have a name
 error.illegal.scheme.name=Illegal scheme name
diff --git a/platform/platform-resources-en/src/messages/OptionsBundle.properties b/platform/platform-resources-en/src/messages/OptionsBundle.properties
index 920fd45..f92eab5 100644
--- a/platform/platform-resources-en/src/messages/OptionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/OptionsBundle.properties
@@ -228,6 +228,8 @@
 # Console settings
 color.settings.console.name=Console Colors
 color.settings.console.output=IRB Output
+
+color.settings.console.black=ANSI Black
 color.settings.console.red=ANSI Red
 color.settings.console.green=ANSI Green
 color.settings.console.yellow=ANSI Yellow
@@ -235,4 +237,14 @@
 color.settings.console.magenta=ANSI Magenta
 color.settings.console.cyan=ANSI Cyan
 color.settings.console.gray=ANSI Gray
+
+color.settings.console.darkGray=ANSI Dark Gray
+color.settings.console.redBright=ANSI Bright Red
+color.settings.console.greenBright=ANSI Bright Green
+color.settings.console.yellowBright=ANSI Bright Yellow
+color.settings.console.blueBright=ANSI Bright Blue
+color.settings.console.magentaBright=ANSI Bright Magenta
+color.settings.console.cyanBright=ANSI Bright Cyan
+color.settings.console.white=ANSI White
+
 options.general.attribute.descriptor.live.template=Live Template
\ No newline at end of file
diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties
index 7f9d09d..4571f97 100644
--- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties
+++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties
@@ -2,42 +2,42 @@
 progress.text=Looking for Usages
 usageView.tabText=Refactoring Preview
 usageView.usagesText=usages
-usageView.need.reRun=Cannot perform the refactoring operation.\nThere were changes in code after the usages have been found.\nPlease, perform the usage search again.
+usageView.need.reRun=Cannot perform refactoring operation.\nThere were changes in code after usages have been found.\nPlease perform usage search again.
 usageView.doAction=&Do Refactor
 statusBar.refactoring.result={0, choice, 1#1 occurrence|2#{0,number} occurrences} changed
 statusBar.noUsages=No occurrences found
 anonymousToInner.refactoring.name=Convert Anonymous to Inner
 anonymousToInner.no.inner.class.name=Class name should be specified
-inner.class.exists=Inner class named ''{0}'' is already defined\nin the class ''{1}''
+inner.class.exists=Inner class named ''{0}'' is already defined\nin class ''{1}''
 anonymousToInner.class.name.label.text=Class name:
 anonymousToInner.make.class.static.checkbox.text=Make class &static
 anonymousToInner.parameters.panel.border.title=Constructor Parameters
-error.wrong.caret.position.method=The caret should be positioned inside the method to be refactored.
-error.wrong.caret.position.constructor=The caret should be positioned inside the constructor to be refactored.
-error.wrong.caret.position.method.or.class.name=The caret should be positioned at the name of the method or class to be refactored.
-error.wrong.caret.position.method.or.variable.name=The caret should be positioned at the name of the method or variable to be refactored.
-error.wrong.caret.position.anonymous=The caret should be positioned inside the anonymous class to be refactored.
-error.wrong.caret.position.class=The caret should be positioned inside the class to be refactored.
-error.wrong.caret.position.method.or.local.name=The caret should be positioned at the name of the element to be refactored.
-error.wrong.caret.position.local.name=The caret should be positioned at the name of the local variable to be refactored.
-error.wrong.caret.position.local.or.expression.name=The caret should be positioned at the name of the local variable or expression to be refactored.
-error.wrong.caret.position.symbol.to.rename=The caret should be positioned at the symbol to be renamed.
-error.wrong.caret.position.symbol.to.refactor=The caret should be positioned at the symbol to be refactored.
-error.out.of.project.element=Selected {0} is not located inside the project.
-error.in.injected.lang.prefix.suffix=Selected {0} is located in the readonly part of the injected language document.
-error.cannot.be.renamed=This element cannot be renamed.
+error.wrong.caret.position.method=Caret should be positioned inside method to be refactored
+error.wrong.caret.position.constructor=Caret should be positioned inside constructor to be refactored
+error.wrong.caret.position.method.or.class.name=Caret should be positioned at the name of method or class to be refactored
+error.wrong.caret.position.method.or.variable.name=Caret should be positioned at the name of method or variable to be refactored
+error.wrong.caret.position.anonymous=Caret should be positioned inside anonymous class to be refactored
+error.wrong.caret.position.class=Caret should be positioned inside class to be refactored
+error.wrong.caret.position.method.or.local.name=Caret should be positioned at the name of element to be refactored
+error.wrong.caret.position.local.name=Caret should be positioned at the name of local variable to be refactored
+error.wrong.caret.position.local.or.expression.name=Caret should be positioned at the name of local variable or expression to be refactored
+error.wrong.caret.position.symbol.to.rename=Caret should be positioned at symbol to be renamed
+error.wrong.caret.position.symbol.to.refactor=Caret should be positioned at symbol to be refactored
+error.out.of.project.element=Selected {0} is not located inside project.
+error.in.injected.lang.prefix.suffix=Selected {0} is located in the read-only part of injected language document
+error.cannot.be.renamed=This element cannot be renamed
 to.refactor=to refactor
 error.cannot.resolve=Cannot resolve {0}
 error.incorrect.data=Incorrect Data
 error.wrong.name.input=Wrong name: {0}
 error.not.supported.for.jsp={0} refactoring is not supported for JSP
 changeClassSignature.refactoring.name=Change Class Signature
-changeClassSignature.no.type.parameters=The class cannot have type parameters.
+changeClassSignature.no.type.parameters=Class cannot have type parameters
 changeClassSignature.parameters.panel.border.title=Parameters
 changeClassSignature.bad.default.value=Wrong default value: ''{0}'' for parameter ''{1}''
 changeClassSignature.class.label.text=Change signature of {0}
-changeSignature.no.type.for.parameter=Specify a type for parameter ''{0}''
-changeSignature.no.type.for.exception=Specify a type for exception
+changeSignature.no.type.for.parameter=Specify type for parameter ''{0}''
+changeSignature.no.type.for.exception=Specify type for exception
 changeSignature.refactoring.name=Change Signature
 column.name.name=Name:
 changeSignature.default.value.column=Default Value
@@ -59,7 +59,7 @@
 changeSignature.wrong.type.for.parameter=Wrong type: ''{0}'' for parameter ''{1}''
 changeSignature.wrong.type.for.exception=Wrong type: ''{0}'' for exception
 changeSignature.vararg.not.last=Vararg parameter should be the last in method signature
-changeSignature.no.default.value=New parameter ''{0}'' has been added.\nSpecify a default value to be used in all existing calls of this method.
+changeSignature.no.default.value=New parameter ''{0}'' has been added.\nSpecify default value to be used in all existing calls of this method.
 changeSignature.not.throwable.type=Wrong type ''{0}'' for exception, should extend java.lang.Throwable
 changeSignature.cannot.resolve.parameter.type=Type ''{0}'' for parameter ''{1}'' cannot be resolved.\nContinue?
 search.in.comments.and.strings=Search in &comments and strings
@@ -128,9 +128,9 @@
 do.not.replace=Do &not replace
 replace.fields.inaccessible.in.usage.context=Replace fields &inaccessible in usage context
 replace.all.fields=&Replace all fields
-class.does.not.exist.in.the.project=Class does not exist in the project. Do you want to create it?
+class.does.not.exist.in.the.project=Class does not exist in project. Do you want to create it?
 no.field.name.specified=No field name specified
-field.exists=The field with the name {0}\nalready exists in class ''{1}''.\nContinue?
+field.exists=Field with name {0}\nalready exists in class ''{1}''.\nContinue?
 choose.destination.class=Choose Destination Class
 replace.write.access.occurrences=Rep&lace write access occurrences
 
@@ -146,49 +146,49 @@
 
 variable.of.type=Variable of &type:
 convert.to.instance.method.title=Convert To Instance Method
-convertToInstanceMethod.method.is.not.static=Cannot perform the refactoring\nMethod {0} is not static.
-convertToInstanceMethod.no.parameters.with.reference.type=There are no parameters that have a reference type
-convertToInstanceMethod.all.reference.type.parametres.have.unknown.types=All reference type parametres have unknown types
+convertToInstanceMethod.method.is.not.static=Cannot perform the refactoring\nMethod {0} is not static
+convertToInstanceMethod.no.parameters.with.reference.type=There are no parameters that have reference type
+convertToInstanceMethod.all.reference.type.parametres.have.unknown.types=All reference type parameters have unknown types
 convertToInstanceMethod.all.reference.type.parameters.are.not.in.project=All reference type parameters have types that are not in project
 cannot.perform.refactoring=Cannot perform refactoring.
 move.instance.method.title=Move Instance Method
 move.method.is.not.supported.for.constructors=Move method is not supported for constructors
 move.method.is.not.supported.for.generic.classes=Move method is not supported for generic classes
 move.method.is.not.supported.when.method.is.part.of.inheritance.hierarchy=Move method is not supported when method is a part of inheritance hierarchy
-synthetic.jsp.class.is.referenced.in.the.method=Synthetic jsp class is referenced in the method
-there.are.no.variables.that.have.reference.type=There are no variables that have a reference type
+synthetic.jsp.class.is.referenced.in.the.method=Synthetic jsp class is referenced in method
+there.are.no.variables.that.have.reference.type=There are no variables that have reference type
 all.candidate.variables.have.unknown.types=All candidate variables have unknown types
 all.candidate.variables.have.types.not.in.project=All candidate variables have types that are not in project
 use.interface.where.possible.title=Use Interface Where Possible
-interface.does.not.have.base.interfaces=Interface {0} does not have base interfaces.
-the.field.should.be.declared.in.a.class=The field should be declared in a class.
+interface.does.not.have.base.interfaces=Interface {0} does not have base interfaces
+the.field.should.be.declared.in.a.class=The field should be declared in a class
 encapsulate.fields.title=Encapsulate Fields
-fields.to.be.refactored.should.belong.to.the.same.class=Fields to be refactored should belong to the same class.
+fields.to.be.refactored.should.belong.to.the.same.class=Fields to be refactored should belong to the same class
 encapsulate.fields.refactoring.cannot.be.applied.to.interface=Encapsulate fields refactoring cannot be applied to interface
 extract.interface.title=Extract Interface
 extract.interface.command.name=Extracting interface {0} from {1}
 extract.method.title=Extract Method
-selected.block.contains.invocation.of.another.class.constructor=Selected block contains invocation of another class constructor.
+selected.block.contains.invocation.of.another.class.constructor=Selected block contains invocation of another class constructor
 selected.block.should.represent.a.set.of.statements.or.an.expression=Selected block should represent a set of statements or an expression
 press.escape.to.remove.the.highlighting=Press Escape to remove the highlighting
 extract.superclass.title=Extract Superclass
 extract.superclass.command.name=Extracting superclass {0} from {1}
-superclass.cannot.be.extracted.from.an.interface=Superclass cannot be extracted from an interface.
-superclass.cannot.be.extracted.from.an.enum=Superclass cannot be extracted from an enum.
+superclass.cannot.be.extracted.from.an.interface=Superclass cannot be extracted from interface
+superclass.cannot.be.extracted.from.an.enum=Superclass cannot be extracted from enum
 replace.inheritance.with.delegation.title=Replace Inheritance With Delegation
 class.is.interface={0} is an interface.
-class.does.not.have.base.classes.or.interfaces=Class {0} does not have base classes or interfaces.
+class.does.not.have.base.classes.or.interfaces=Class {0} does not have base classes or interfaces
 inline.title=Inline
 introduce.constant.title=Extract Constant
 introduce.selection.error=Cannot perform refactoring using selected element(s)
-selected.expression.cannot.be.a.constant.initializer=Selected expression cannot be a constant initializer.
+selected.expression.cannot.be.a.constant.initializer=Selected expression cannot be a constant initializer
 variable.does.not.have.an.initializer=Variable {0} does not have an initializer.
-initializer.for.variable.cannot.be.a.constant.initializer=Initializer for variable {0} cannot be a constant initializer.
-cannot.introduce.field.in.interface=Cannot extract field in interface
+initializer.for.variable.cannot.be.a.constant.initializer=Initializer for variable {0} cannot be a constant initializer
+cannot.introduce.field.in.interface=Cannot extract field in the interface
 introduce.field.title=Extract Field
-selected.block.should.represent.an.expression=Selected block should represent an expression.
-is.not.supported.in.the.current.context={0} is not supported in current context.
-type.of.the.selected.expression.cannot.be.determined=Type of the selected expression cannot be determined.
+selected.block.should.represent.an.expression=Selected block should represent an expression
+is.not.supported.in.the.current.context={0} is not supported in current context
+type.of.the.selected.expression.cannot.be.determined=Type of selected expression cannot be determined.
 selected.expression.has.void.type=Selected expression has void type.
 to.rename=to rename
 to.delete.with.usage.search=to delete (with usage search)
@@ -196,30 +196,30 @@
 invalid.expression.context=Invalid expression context.
 refactoring.is.not.supported.in.the.current.context={0} refactoring is not supported in the current context
 cannot.introduce.variable.in.super.constructor.call=Cannot extract variable in super constructor call
-is.modified.in.loop.body={0} is modified in loop body.
-introducing.variable.may.break.code.logic=Introducing variable may break code logic.
+is.modified.in.loop.body={0} is modified in loop body
+introducing.variable.may.break.code.logic=Introducing variable may break code logic
 no.selection=No selection.
-selection.does.not.form.a.fragment.for.extraction=Selection does not form a fragment for extraction.
-cannot.extract.selected.elements.into.include.file=Cannot extract selected elements into include file.
+selection.does.not.form.a.fragment.for.extraction=Selection does not form a fragment for extraction
+cannot.extract.selected.elements.into.include.file=Cannot extract selected elements into include file
 the.language.for.selected.elements.has.no.associated.file.type=The language for selected elements has no associated file type
 extract.include.file.title=Extract include file
 replace.fragment=Replace Fragment
 idea.has.found.fragments.that.can.be.replaced.with.include.directive={0} has found fragments that can be replaced with include directive\nDo you want to review them?
 remove.duplicates.command=Remove Duplicates
 make.method.static.title=Make Method Static
-constructor.cannot.be.made.static=Constructor cannot be made static.
-this.member.does.not.seem.to.belong.to.any.class=This member does not seem to belong to any class.
-member.is.already.static=Member is already static.
-cannot.make.abstract.method.static=Cannot make abstract method static.
-inner.classes.cannot.have.static.members=Inner classes cannot have static members.
+constructor.cannot.be.made.static=Constructor cannot be made static
+this.member.does.not.seem.to.belong.to.any.class=This member does not seem to belong to any class
+member.is.already.static=Member is already static
+cannot.make.abstract.method.static=Cannot make abstract method static
+inner.classes.cannot.have.static.members=Inner classes cannot have static members
 pull.members.up.title=Pull Members Up
-the.caret.should.be.positioned.inside.a.class.to.pull.members.from=The caret should be positioned inside a class to pull members from.
-class.does.not.have.base.classes.interfaces.in.current.project={0} does not have base classes/interfaces in current project.
+the.caret.should.be.positioned.inside.a.class.to.pull.members.from=Caret should be positioned inside a class to pull members from
+class.does.not.have.base.classes.interfaces.in.current.project={0} does not have base classes/interfaces in current project
 pullUp.command=Pulling members up from {0}
 push.members.down.title=Push Members Down
-the.caret.should.be.positioned.inside.a.class.to.push.members.from=The caret should be positioned inside a class to push members from
+the.caret.should.be.positioned.inside.a.class.to.push.members.from=Caret should be positioned inside a class to push members from
 move.title=Move
-the.caret.should.be.positioned.at.the.class.method.or.field.to.be.refactored=The caret should be positioned at the class, method or field to be refactored.
+the.caret.should.be.positioned.at.the.class.method.or.field.to.be.refactored=Caret should be positioned at the class, method or field to be refactored
 select.refactoring.title=Select Refactoring
 what.would.you.like.to.do=What would you like to do?
 move.packages.to.another.package=Move {0} &packages to another package
@@ -228,11 +228,11 @@
 move.directory.to.another.source.root=Move directory {0} to &another source root
 move.inner.class.to.upper.level=Move &inner class {0} to upper level
 move.inner.class.to.another.class=&Move inner class {0} to another class
-move.nonstatic.class.from.jsp.not.supported = Moving non-static classes from JSP page is not supported.
+move.nonstatic.class.from.jsp.not.supported = Moving non-static classes from JSP page is not supported
 package.occurs.in.package.prefixes.of.the.following.source.folders.n=Package {0} occurs in package prefixes of the following source folders:\n
 these.package.prefixes.will.be.changed=These package prefixes will be changed.
 rename.title=Rename
-rename.not.supported=Operation is not supported.
+rename.not.supported=Operation is not supported
 multiple.directories.correspond.to.package=Multiple directories correspond to package\n
 directories.and.all.references.to.package.will.be.renamed=\n\nDo you want to rename the whole package or directory \n{0} only?
 rename.package.button.text=Rename &package
@@ -243,26 +243,26 @@
 move.directories= Move &all
 warning.title=Warning
 replace.constructor.with.factory.method.title=Replace Constructor With Factory Method
-class.does.not.have.implicit.default.constructor=Class {0} does not have implicit default constructor.
+class.does.not.have.implicit.default.constructor=Class {0} does not have implicit default constructor
 would.you.like.to.replace.default.constructor.of.0.with.factory.method=Would you like to replace default constructor of {0} with factory method?
-refactoring.is.not.supported.for.local.and.jsp.classes=Refactoring is not supported for local and JSP classes.
-refactoring.is.not.supported.for.jsp.classes=Refactoring is not supported for JSP classes.
+refactoring.is.not.supported.for.local.and.jsp.classes=Refactoring is not supported for local and JSP classes
+refactoring.is.not.supported.for.jsp.classes=Refactoring is not supported for JSP classes
 class.is.abstract={0} is abstract.
-method.is.not.a.constructor=Method is not a constructor.
+method.is.not.a.constructor=Method is not a constructor
 safe.delete.title=Safe Delete
 replace.temp.with.query.title=Replace Temp with Query
-cannot.replace.temp.with.query.in.interface=Cannot replace temp with query in interface.
-variable.has.no.initializer=Variable {0} has no initializer.
-variable.has.no.dominating.definition=Cannot find a single definition to inline.
+cannot.replace.temp.with.query.in.interface=Cannot replace temp with query in interface
+variable.has.no.initializer=Variable {0} has no initializer
+variable.has.no.dominating.definition=Cannot find a single definition to inline
 variable.is.never.used=Variable {0} is never used
-variable.is.accessed.for.writing=Variable ''{0}'' is accessed for writing.
-variable.is.accessed.for.writing.and.used.with.inlined=Another variable ''{0}'' definition is used together with inlined one.
+variable.is.accessed.for.writing=Variable ''{0}'' is accessed for writing
+variable.is.accessed.for.writing.and.used.with.inlined=Another variable ''{0}'' definition is used together with inlined one
 only.fields.variables.of.methods.of.valid.type.can.be.considered=Only fields, variables, method parameters\u00A0or methods of valid type can be considered.
 unable.to.start.type.migration=Unable to start type migration
 replace.method.code.duplicates.title=Replace Code Duplicates
-locate.caret.inside.a.method=Locate caret inside a member.
+locate.caret.inside.a.method=Locate caret inside a member
 replace.with.method.call.does.not.work.for.constructors=Replace With Method Call does not work for constructors
-method.does.not.have.a.body=Method {0} does not have a body.
+method.does.not.have.a.body=Method {0} does not have a body
 method.has.an.empty.body=Method {0} has an empty body.
 idea.has.not.found.any.code.that.can.be.replaced.with.method.call={0} has not found any duplicates
 method.duplicates.found.message={0, choice, 1#1 code fragment|2#{0,number} code fragments} found
@@ -288,20 +288,20 @@
 javadoc.move=&Move
 replace.instance.qualifiers.with.class.references=Replace instance qualifiers with class references
 make.0.static=Make {0} Static
-0.already.has.parameter.named.1.use.this.name.anyway={0} already has parameter named ''{1}''.\nUse this name anyway?
+0.already.has.parameter.named.1.use.this.name.anyway={0} already has a parameter named ''{1}''.\nUse this name anyway?
 this.method=This method
 add.object.as.a.parameter.with.name=Add &object as a parameter with name:
 add.object.as.a.parameter.to.constructors.with.name=Add &object as a parameter to constructors with name:
 add.parameters.for.fields=Add parameters for &fields:
 add.parameters.for.fields.to.constructors=Add parameters for &fields to constructors:
-0.already.contains.field.1={0} already contains field {1}.
+0.already.contains.field.1={0} already contains field {1}
 0.is.already.overridden.in.1={0} is already overridden in {1}. Method will not be pushed down to that class.
-0.already.contains.inner.class.named.1={0} already contains inner class named {1}.
+0.already.contains.inner.class.named.1={0} already contains inner class named {1}
 0.uses.1.which.is.pushed.down={0} uses {1}, which is pushed down
 refactoring.cannot.be.performed=Refactoring cannot be performed
 there.is.already.a.0.it.will.conflict.with.an.introduced.parameter=There is already a {0}. It will conflict with an introduced parameter
 introduce.parameter.command=Extracting parameter to {0}
-parameter.initializer.contains.0.but.not.all.calls.to.method.are.in.its.class=Parameter initializer contains {0}, but not all calls to method are in its class.
+parameter.initializer.contains.0.but.not.all.calls.to.method.are.in.its.class=Parameter initializer contains {0}, but not all calls to method are in its class
 0.is.not.accessible.from.1.value.for.introduced.parameter.in.that.method.call.will.be.incorrect={0} is not accessible from {1}. Value for introduced parameter in that method call will be incorrect.
 use.interface.superclass.in.instanceof=Use interface/superclass in instanceof
 introduce.parameter.to.method=Extract parameter to method:
@@ -325,7 +325,7 @@
 copy.files.copy.specified.directories.label=Copy specified directories
 copy.files.copy.specified.mixed.label=Copy specified files and directories
 copy.files.to.directory.label=To &directory:
-the.file.will.be.copied.to.this.directory=The file will be copied to this directory
+the.file.will.be.copied.to.this.directory=File will be copied to this directory
 copy.files.clone.title=Clone
 copy.files.copy.title=Copy
 copy.files.clone.file.0=Clone file {0}
@@ -352,8 +352,8 @@
 encapsulate.fields.setter.column.name=Setter
 encapsulate.fields.no.fields.selected=No fields selected
 encapsulate.fields.command.name=Encapsulating fields in {0}
-encapsulate.fields.getter.exists=There already is a method {0} which differs from getter {1} by return type only.
-encapsulate.fields.setter.exists=There already is a method {0} which differs from setter {1} by return type only.
+encapsulate.fields.getter.exists=There is already method {0} which differs from getter {1} by return type only
+encapsulate.fields.setter.exists=There is already method {0} which differs from setter {1} by return type only
 encapsulate.fields.fields.to.be.encapsulated=Fields to be encapsulated
 invocations.to.be.inlined=Invocations to be inlined {0}
 classes.to.push.down.members.to=Classes to push down members to {0}
@@ -374,8 +374,8 @@
 make.static.description.label=Make {0} {1} static
 there.is.already.a.0.in.1=There is already a {0} in {1}
 0.uses.non.static.1.which.is.not.passed.as.a.parameter={0} uses non-static {1}, which is not passed as a parameter
-0.uses.1.which.needs.class.instance={0} uses {1}, which needs class instance.
-method.0.is.overridden.by.1=Method {0} is overridden by {1}.
+0.uses.1.which.needs.class.instance={0} uses {1}, which needs class instance
+method.0.is.overridden.by.1=Method {0} is overridden by {1}
 make.static.command=Making {0} static
 introduce.parameter.elements.header=Adding parameter to a method
 annotate.field.as.nonnls.checkbox=Annotate &field as @NonNls
@@ -398,7 +398,7 @@
 declare.varargs.checkbox=Declare v&arargs
 declare.folded.parameters=&Fold parameters
 extract.method.method.panel.border=Method
-there.are.multiple.exit.points.in.the.selected.code.fragment=There are multiple exit points in the selected code fragment.
+there.are.multiple.exit.points.in.the.selected.code.fragment=There are multiple exit points in the selected code fragment
 move.members.elements.header=Members to be moved
 move.members.move.members.from.label=Move members from:
 move.members.to.fully.qualified.name.label=To (fully qualified name):
@@ -407,10 +407,10 @@
 0.is.not.a.legal.fq.name=''{0}'' is not a legal FQ-name
 create.class.command=Create class {0}
 source.and.destination.classes.should.be.different=Source and destination classes should be different
-cannot.move.inner.class.0.into.itself=Cannot move inner class {0} into itself.
+cannot.move.inner.class.0.into.itself=Cannot move inner class {0} into itself
 class.0.does.not.exist=Class {0} does not exist.\nDo you want to create it?
 move.members.title=Move Members
-members.to.be.moved.should.belong.to.the.same.class=Members to be moved should belong to the same class.
+members.to.be.moved.should.belong.to.the.same.class=Members to be moved should belong to the same class
 field.0.is.not.static=Field {0} is not static.\n{1} refactoring is supported for static members only.
 0.refactoring.cannot.be.applied.to.constructors={0} refactoring cannot be applied to constructors
 method.0.is.not.static=Method {0} is not static.\n{1} refactoring is supported for static members only.
@@ -455,16 +455,16 @@
 inline.field.elements.header=Field to inline
 inline.class.elements.header=Class to inline
 inline.vars.elements.header=Variable to inline
-interface.has.been.successfully.created=Interface {0} has been successfully created.
-class.has.been.successfully.created=Class {0} has been successfully created.
+interface.has.been.successfully.created=Interface {0} has been successfully created
+class.has.been.successfully.created=Class {0} has been successfully created
 use.super.references.prompt=At this stage {0} can analyze usages of {1} \nand replace them with usages of {2} where possible.\nDo you want to proceed?
 analyze.and.replace.usages=Analyze and Replace Usages
 there.are.multiple.output.values.for.the.selected.code.fragment=There are multiple output values for the selected code fragment:
 expression.result=expression result
 boolean.method.result=boolean method result
 instances.of.0.upcasted.to.1.were.found=Instances of {0} upcasted to {1} were found. If you continue, they will be shown in a separate Find tab.
-0.uses.1.of.an.instance.of.a.2={0} uses {1} of an instance of a {2}.
-0.upcasts.an.instance.of.1.to.2={0} upcasts an instance of {1} to {2}.
+0.uses.1.of.an.instance.of.a.2={0} uses {1} of an instance of a {2}
+0.upcasts.an.instance.of.1.to.2={0} upcasts an instance of {1} to {2}
 0.will.no.longer.override.1={0} will no longer override {1}
 replacing.inheritance.with.delegation=Replacing inheritance with delegation
 instances.casted.to.java.lang.object=Instances casted to java.lang.Object
@@ -474,7 +474,7 @@
 replace.inheritance.with.delegation.elements.header=Replace inheritance with delegation
 # Inline included file
 inline.included.file.title=Inline included file
-the.caret.should.be.positioned.on.the.included.file.to.inline=The caret should be positioned on the included file reference to inline
+the.caret.should.be.positioned.on.the.included.file.to.inline=Caret should be positioned on the included file reference to inline
 
 inline.the.contents.include.prompt=Inline the contents of ''{0}''?
 remove.include.prompt=Included file is no longer used. Remove it?
@@ -492,8 +492,8 @@
 keep.abstract.column.header=Keep abstract
 push.down.javadoc.panel.title=JavaDoc for abstracts
 push.down.members.elements.header=Push down members from
-interface.0.does.not.have.inheritors=Interface {0} does not have inheritors.
-class.0.does.not.have.inheritors=Class {0} does not have inheritors.
+interface.0.does.not.have.inheritors=Interface {0} does not have inheritors
+class.0.does.not.have.inheritors=Class {0} does not have inheritors
 push.down.will.delete.members=Pushing members down will result in them being deleted. Would you like to create a new subclass?
 edit.migration.map.title=Edit Migration Map
 migration.map.name.prompt=Map name:
@@ -529,30 +529,30 @@
 package.does.not.exist=Package {0} does not exist.\nDo you want to create it?
 move.package.refactoring.cannot.be.applied.to.default.package=Move Package refactoring cannot be applied to default package
 move.class.refactoring.cannot.be.applied.to.anonymous.classes=Move Class refactoring cannot be applied to anonymous classes
-moving.local.classes.is.not.supported=Moving local classes is not supported.
-there.are.going.to.be.multiple.destination.files.with.the.same.name=There are going to be multiple destination files with the same name.
+moving.local.classes.is.not.supported=Moving local classes is not supported
+there.are.going.to.be.multiple.destination.files.with.the.same.name=There are going to be multiple destination files with the same name
 do.you.wish.to.continue=Do you wish to continue?
 all.these.directories.will.be.moved.and.all.references.to.0.will.be.changed=All these directories will be moved, and all references to {0} \nwill be changed.
 select.source.root.chooser.title=Select Source Root
 moving.directories.command=Moving directories
-0.uses.a.package.local.1={0} uses a package-local {1}.
-a.package.local.class.0.will.no.longer.be.accessible.from.1=A package-local class {0} will no longer be accessible from {1}
+0.uses.a.package.local.1={0} uses package-local {1}
+a.package.local.class.0.will.no.longer.be.accessible.from.1=Package-local class {0} will no longer be accessible from {1}
 element.will.no.longer.be.accessible={0} will no longer be accessible from {1}
 move.instance.method.command=Move Instance method
 move.instance.method.elements.header=Move instance method
 move.method.this.parameter.label=Select a name for ''{0}.this'' parameter
 move.method.enter.a.valid.name.for.parameter=Please Enter a Valid name for Parameter
-0.is.an.interface.that.has.no.implementing.classes={0} is an interface. \nthat has no implementing classes.
+0.is.an.interface.that.has.no.implementing.classes={0} is an interface that has no implementing classes
 0.is.an.interface.method.implementation.will.be.added.to.all.directly.implementing.classes={0} is an interface. \nMethod implementation will be added to all directly implementing classes.\n Proceed?
 move.inner.to.upper.level.title=Move Inner to Upper Level
 move.inner.class.command=Moving inner class {0}
-0.will.become.inaccessible.from.1={0} will become inaccessible from {1}.
+0.will.become.inaccessible.from.1={0} will become inaccessible from {1}
 move.specified.files=Move specified files
 move.specified.directories=Move specified directories
 move.file.0=Move file {0}
 move.directory.0=Move directory {0}
 move.files.to.directory.label=To directory:
-the.file.will.be.moved.to.this.directory=The file will be moved to this directory
+the.file.will.be.moved.to.this.directory=File will be moved to this directory
 searching.for.variables=Searching for variables
 no.usages.can.be.replaced=No usages of {0} \ncan be replaced with usages of {1}
 turn.refs.to.super.command=Replacing usages of {0} with {1}
@@ -560,8 +560,8 @@
 factory.method.name.label=Factory method name:
 replace.constructor.with.factory.target.fq.name=In (fully qualified name):
 class.0.not.found=Class {0} not found.
-class.0.is.not.accessible.from.target.1=Class {0} is not accessible from target {1}.
-target.0.is.not.accessible.from.1=Target {0} is not accessible from {1}.
+class.0.is.not.accessible.from.target.1=Class {0} is not accessible from target {1}
+target.0.is.not.accessible.from.1=Target {0} is not accessible from {1}
 constructor.being.refactored.is.used.in.initializer.of.0=Constructor being refactored is used in initializer of {0}. Non-static factory of inner class{1} cannot be used in this context. Resulting code will not compile.
 replace.constructor.0.with.a.factory.method=Replace constructor {0} with a factory method
 replace.default.constructor.of.0.with.a.factory.method=Replace default constructor of {0} with a factory method
@@ -606,8 +606,8 @@
 entity.name.inheritor=Inheritor
 entity.name.test=Test
 unused.overriding.methods.title=Unused Overriding Methods
-there.are.unused.methods.that.override.methods.you.delete=There are unused methods that override methods you delete.
-choose.the.ones.you.want.to.be.deleted=Choose the ones you want to be deleted.
+there.are.unused.methods.that.override.methods.you.delete=There are unused methods that override methods you delete
+choose.the.ones.you.want.to.be.deleted=Choose the ones you want to be deleted
 method.column=Method
 0.implements.1={0} implements {1}.
 attempting.to.delete.targets.node.text=Attempting to delete
@@ -668,19 +668,19 @@
 0.is.located.in.a.jar.file={0} is located in a jar file.\n
 0.is.read.only={0} is read-only.\n
 0.is.not.a.legal.java.identifier=''{0}'' is not a legal java identifier
-method.0.is.already.defined.in.the.1=Method {0} is already defined in the {1}.
-method.0.will.hide.method.of.the.base.class=Method {0} will hide \nthe method of the base class {1}.
-method.0.will.implement.method.of.the.base.class=Method {0} will implement \na method of the base class {1}.
-method.0.will.override.a.method.of.the.base.class=Method {0} will override \na method of the base class {1}.
+method.0.is.already.defined.in.the.1=Method {0} is already defined in the {1}
+method.0.will.hide.method.of.the.base.class=Method {0} will hide \nthe method of the base class {1}
+method.0.will.implement.method.of.the.base.class=Method {0} will implement \na method of the base class {1}
+method.0.will.override.a.method.of.the.base.class=Method {0} will override \na method of the base class {1}
 current.class=current class
-field.0.is.already.defined.in.the.1=Field {0} is already defined in the {1}.
-field.0.will.hide.field.1.of.the.base.class=Field {0} will hide \na field {1} of the base class {2}.
+field.0.is.already.defined.in.the.1=Field {0} is already defined in the {1}
+field.0.will.hide.field.1.of.the.base.class=Field {0} will hide \na field {1} of the base class {2}
 directory.0.already.contains.1.named.2=Directory {0} \nalready contains {1} named ''{2}''
 directory.0.already.contains.a.file.named.1=Directory {0} \nalready contains a file named ''{1}''
 getter.and.setter.methods.found.for.the.field.0=Getter and setter methods found for the field {0}. \n{1} them as well?
 getter.method.found.for.the.field.0=Getter method found for the field {0}. \n{1} the getter as well?
 setter.method.found.for.the.field.0=Setter method found for the field {0}. \n{1} the setter as well?
-0.has.1.usages.in.comments.and.strings={0} has {1,choice,1#1 usage|2#{1,number} usages} in strings, comments, or non-code files.
+0.has.1.usages.in.comments.and.strings={0} has {1,choice,1#1 usage|2#{1,number} usages} in strings, comments, or non-code files
 0.has.1.usages.that.are.not.safe.to.delete.of.those.2={0} has {1,choice,1#1 usage that is|2#{1,number} usages that are} not safe to delete.\nOf those {2,choice,0#0 usages are|1#1 usage is|2#{2,number} usages are} in strings, comments, or non-code files.
 type.cook.drop.obsolete.casts=&Drop obsolete casts
 type.cook.preserve.raw.arrays=Preserve raw &arrays
@@ -693,7 +693,7 @@
 type.cook.report=Items generified: {0}, casts removed: {1}
 type.cook.ratio.generified={0,choice,-1#not calculated|0#{0,number} of {1}}
 extract.method.control.flow.analysis.failed=Code contains syntax errors. Cannot perform necessary analysis.
-pushed.members.will.not.be.visible.from.certain.call.sites=Pushed members will not be visible from certain call sites.
+pushed.members.will.not.be.visible.from.certain.call.sites=Pushed members will not be visible from certain call sites
 invert.boolean.title=Invert Boolean
 invert.boolean.wrong.type=Return type of the method or type of the variable to be refactored should be boolean
 invert.boolean.refs.to.invert=References to be inverted {0}
diff --git a/platform/platform-resources-en/src/messages/StatisticsBundle.properties b/platform/platform-resources-en/src/messages/StatisticsBundle.properties
index 5ed23cd..e7705d7 100644
--- a/platform/platform-resources-en/src/messages/StatisticsBundle.properties
+++ b/platform/platform-resources-en/src/messages/StatisticsBundle.properties
@@ -1,4 +1,4 @@
 stats.title=Help improve {0} by sending anonymous usage statistics to {1}
 
-stats.config.allow.send.stats.text=Allow to send usages statistics to {0}
-stats.config.details=<html>We're asking your permission to send information about your plugins configuration (what is enabled <br>and what is not) and feature usage statistics (e.g. how frequently you're using code completion).<br>    This data is anonymous, does not contain any personal information, collected for use only by {0}<br> and will never be transmitted to any third party.</html>
\ No newline at end of file
+stats.config.allow.send.stats.text=Allow sending usage statistics to {0}
+stats.config.details=<html>We are asking your permission to send information about your plugins configuration (what is enabled <br>and what is not) and feature usage statistics (e.g. how frequently you are using code completion).<br>    This data is anonymous, does not contain any personal information, collected for use only by {0}<br> and will never be transmitted to any third party.</html>
\ No newline at end of file
diff --git a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
index 8b5133d..8e0d36d 100644
--- a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
+++ b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
@@ -25,11 +25,13 @@
 xbreakpoints.dialog.button.remove=&Remove
 xbreakpoints.dialog.button.add=&Add...
 xbreakpoints.conditions.group.title=Conditions
-xbreakpoints.suspend.group.title=Suspend policy
-xbreakpoints.suspend.checkbox=&Suspend
-xbreakpoints.suspend.all.radio=All
-xbreakpoints.suspend.thread.radio=Thread
-xbreakpoints.suspend.none.radio=None
+
+suspend.policy.panel.title=Suspend policy
+suspend.policy.panel.suspend=&Suspend
+suspend.policy.panel.all=All
+suspend.policy.panel.thread=Thread
+suspend.policy.panel.makeDefault=Make De&fault
+
 xbreakpoints.properties.actions.group.title=Actions
 xbreakpoints.log.message.checkbox=Log &message to console
 xbreakpoints.log.expression.checkbox=Log evaluated &expression
diff --git a/platform/platform-resources/src/DefaultColorSchemesManager.xml b/platform/platform-resources/src/DefaultColorSchemesManager.xml
index 8e08ee1..7bac479 100644
--- a/platform/platform-resources/src/DefaultColorSchemesManager.xml
+++ b/platform/platform-resources/src/DefaultColorSchemesManager.xml
@@ -858,7 +858,7 @@
       </option>
       <option name="LOG_WARNING_OUTPUT">
         <value>
-          <option name="FOREGROUND" value="80A000"/>
+          <option name="FOREGROUND" value="ffa500"/>
         </value>
       </option>
       <option name="LOG_ERROR_OUTPUT">
@@ -892,9 +892,29 @@
           <option name="ERROR_STRIPE_COLOR" value="ff" />
         </value>
       </option>
+        <option name="CONSOLE_BLACK_OUTPUT">
+          <value>
+            <option name="FOREGROUND" value="000000" />
+            <option name="BACKGROUND" />
+            <option name="FONT_TYPE" value="0" />
+            <option name="EFFECT_COLOR" />
+            <option name="EFFECT_TYPE" value="0" />
+            <option name="ERROR_STRIPE_COLOR" />
+          </value>
+        </option>
         <option name="CONSOLE_BLUE_OUTPUT">
           <value>
-            <option name="FOREGROUND" value="ff" />
+            <option name="FOREGROUND" value="0000ee" />
+            <option name="BACKGROUND" />
+            <option name="FONT_TYPE" value="0" />
+            <option name="EFFECT_COLOR" />
+            <option name="EFFECT_TYPE" value="0" />
+            <option name="ERROR_STRIPE_COLOR" />
+          </value>
+        </option>
+        <option name="CONSOLE_BLUE_BRIGHT_OUTPUT">
+          <value>
+            <option name="FOREGROUND" value="5c5cff" />
             <option name="BACKGROUND" />
             <option name="FONT_TYPE" value="0" />
             <option name="EFFECT_COLOR" />
@@ -904,7 +924,27 @@
         </option>
         <option name="CONSOLE_CYAN_OUTPUT">
           <value>
-            <option name="FOREGROUND" value="b2b2" />
+            <option name="FOREGROUND" value="00cccc" />
+            <option name="BACKGROUND" />
+            <option name="FONT_TYPE" value="0" />
+            <option name="EFFECT_COLOR" />
+            <option name="EFFECT_TYPE" value="0" />
+            <option name="ERROR_STRIPE_COLOR" />
+          </value>
+        </option>
+        <option name="CONSOLE_CYAN_BRIGHT_OUTPUT">
+          <value>
+            <option name="FOREGROUND" value="00ffff" />
+            <option name="BACKGROUND" />
+            <option name="FONT_TYPE" value="0" />
+            <option name="EFFECT_COLOR" />
+            <option name="EFFECT_TYPE" value="0" />
+            <option name="ERROR_STRIPE_COLOR" />
+          </value>
+        </option>
+        <option name="CONSOLE_DARKGRAY_OUTPUT">
+          <value>
+            <option name="FOREGROUND" value="555555" />
             <option name="BACKGROUND" />
             <option name="FONT_TYPE" value="0" />
             <option name="EFFECT_COLOR" />
@@ -914,7 +954,7 @@
         </option>
         <option name="CONSOLE_GRAY_OUTPUT">
           <value>
-            <option name="FOREGROUND" value="595959" />
+            <option name="FOREGROUND" value="aaaaaa" />
             <option name="BACKGROUND" />
             <option name="FONT_TYPE" value="0" />
             <option name="EFFECT_COLOR" />
@@ -924,7 +964,17 @@
         </option>
         <option name="CONSOLE_GREEN_OUTPUT">
           <value>
-            <option name="FOREGROUND" value="8000" />
+            <option name="FOREGROUND" value="00cd00" />
+            <option name="BACKGROUND" />
+            <option name="FONT_TYPE" value="0" />
+            <option name="EFFECT_COLOR" />
+            <option name="EFFECT_TYPE" value="0" />
+            <option name="ERROR_STRIPE_COLOR" />
+          </value>
+        </option>
+        <option name="CONSOLE_GREEN_BRIGHT_OUTPUT">
+          <value>
+            <option name="FOREGROUND" value="00ff00" />
             <option name="BACKGROUND" />
             <option name="FONT_TYPE" value="0" />
             <option name="EFFECT_COLOR" />
@@ -934,6 +984,16 @@
         </option>
         <option name="CONSOLE_MAGENTA_OUTPUT">
           <value>
+            <option name="FOREGROUND" value="cd00cd" />
+            <option name="BACKGROUND" />
+            <option name="FONT_TYPE" value="0" />
+            <option name="EFFECT_COLOR" />
+            <option name="EFFECT_TYPE" value="0" />
+            <option name="ERROR_STRIPE_COLOR" />
+          </value>
+        </option>
+        <option name="CONSOLE_MAGENTA_BRIGHT_OUTPUT">
+          <value>
             <option name="FOREGROUND" value="ff00ff" />
             <option name="BACKGROUND" />
             <option name="FONT_TYPE" value="0" />
@@ -944,6 +1004,16 @@
         </option>
         <option name="CONSOLE_RED_OUTPUT">
           <value>
+            <option name="FOREGROUND" value="cd0000" />
+            <option name="BACKGROUND" />
+            <option name="FONT_TYPE" value="0" />
+            <option name="EFFECT_COLOR" />
+            <option name="EFFECT_TYPE" value="0" />
+            <option name="ERROR_STRIPE_COLOR" />
+          </value>
+        </option>
+        <option name="CONSOLE_RED_BRIGHT_OUTPUT">
+          <value>
             <option name="FOREGROUND" value="ff0000" />
             <option name="BACKGROUND" />
             <option name="FONT_TYPE" value="0" />
@@ -954,7 +1024,27 @@
         </option>
         <option name="CONSOLE_YELLOW_OUTPUT">
           <value>
-            <option name="FOREGROUND" value="ffcc00" />
+            <option name="FOREGROUND" value="cdcd00" />
+            <option name="BACKGROUND" />
+            <option name="FONT_TYPE" value="0" />
+            <option name="EFFECT_COLOR" />
+            <option name="EFFECT_TYPE" value="0" />
+            <option name="ERROR_STRIPE_COLOR" />
+          </value>
+        </option>
+        <option name="CONSOLE_YELLOW_BRIGHT_OUTPUT">
+          <value>
+            <option name="FOREGROUND" value="eaea00" />
+            <option name="BACKGROUND" />
+            <option name="FONT_TYPE" value="0" />
+            <option name="EFFECT_COLOR" />
+            <option name="EFFECT_TYPE" value="0" />
+            <option name="ERROR_STRIPE_COLOR" />
+          </value>
+        </option>
+        <option name="CONSOLE_WHITE_OUTPUT">
+          <value>
+            <option name="FOREGROUND" value="ffffff" />
             <option name="BACKGROUND" />
             <option name="FONT_TYPE" value="0" />
             <option name="EFFECT_COLOR" />
diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml
index bd4f689..15b1e43 100644
--- a/platform/platform-resources/src/META-INF/LangExtensions.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensions.xml
@@ -565,6 +565,8 @@
                                   id="PlatformProjectConfigurator"/>
     <directoryProjectConfigurator implementation="com.intellij.platform.PlatformProjectViewOpener"/>
 
+    <fileIconProvider implementation="com.intellij.ide.FileIconPatcherImpl"/>
+    <iconProvider implementation="com.intellij.ide.NativeIconProvider"/>
     <iconProvider implementation="com.intellij.psi.impl.file.DirectoryIconProvider" id="directory" order="last"/>
 
     <statementUpDownMover implementation="com.intellij.codeInsight.editorActions.moveUpDown.LineMover" id="line" order="last"/>
@@ -756,8 +758,6 @@
     <!--<projectViewPane implementation="com.intellij.ide.favoritesTreeView.FavoritesProjectViewPane"/>-->
     <projectViewPane implementation="com.intellij.ide.scopeView.ScopeViewPane"/>
 
-    <fileIconProvider implementation="com.intellij.openapi.fileTypes.impl.NativeFileIconProvider"/>
-    <fileIconProvider implementation="com.intellij.ide.FileIconPatcherImpl"/>
     <renameHandler implementation="com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler"/>
     <renameHandler implementation="com.intellij.refactoring.rename.inplace.MemberInplaceRenameHandler"/>
     <completion.contributor language="any"
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
index 337bfaf..a689fbc 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
@@ -97,7 +97,6 @@
                     interface="com.intellij.platform.ProjectTemplatesFactory"/>
 
     <extensionPoint name="ApplicationLoadListener" interface="com.intellij.ide.ApplicationLoadListener"/>
-    <extensionPoint name="ComponentRoamingType" beanClass="com.intellij.openapi.components.impl.stores.RoamingTypeExtensionPointBean"/>
 
     <extensionPoint name="editorTabTitleProvider" interface="com.intellij.openapi.fileEditor.impl.EditorTabTitleProvider"/>
     <extensionPoint name="editorTabColorProvider" interface="com.intellij.openapi.fileEditor.impl.EditorTabColorProvider"/>
@@ -197,5 +196,10 @@
     <extensionPoint name="colorPickerListenerFactory" interface="com.intellij.ui.ColorPickerListenerFactory"/>
 
     <extensionPoint name="search.topHitProvider" interface="com.intellij.ide.SearchTopHitProvider"/>
+    
+    <extensionPoint name="schemeImporter" beanClass="com.intellij.openapi.options.SchemeImporterEP">
+      <with attribute="schemeClass" implements="com.intellij.openapi.options.Scheme"/>
+      <with attribute="implementationClass" implements="com.intellij.openapi.options.SchemeImporter"/>
+    </extensionPoint>
   </extensionPoints>
 </idea-plugin>
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
index 45c340a..c948106 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
@@ -239,8 +239,6 @@
     <fileEditorProvider implementation="com.intellij.openapi.fileEditor.impl.http.HttpFileEditorProvider"/>
     <componentConfigurationMerger implementation="com.intellij.openapi.vcs.changes.shelf.ShelfManagerConfigurationMerger"/>
     <editorActionHandler action="EditorEscape" implementationClass="com.intellij.codeInsight.hint.EscapeHandler" id="hide-hints"/>
-    <ComponentRoamingType component="ChangeListManager" type="DISABLED"/>
-    <ComponentRoamingType component="RestoreUpdateTree" type="DISABLED"/>
 
     <projectConfigurable instance="com.intellij.javaee.ExternalResourceConfigurable" key="display.name.edit.external.resource"
                          bundle="messages.XmlBundle" id="preferences.externalResources">
diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml
index 1eb54ac..73839f0 100644
--- a/platform/platform-resources/src/META-INF/XmlPlugin.xml
+++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml
@@ -297,7 +297,7 @@
     <extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.XmlCDATAContentSelectioner"/>
     <extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.DtdSelectioner"/>
     <extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.XmlElementSelectioner"/>
-    <extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.XmlTokenSelectioner"/>
+    <extendWordSelectionHandler id="xmlTokenSelectioner" implementation="com.intellij.codeInsight.editorActions.XmlTokenSelectioner"/>
     <extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.XmlLineSelectioner"/>
 
 
diff --git a/platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.java b/platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.java
index 343b58f2..5a47fdf 100644
--- a/platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.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.
@@ -33,9 +33,6 @@
 import com.intellij.util.diff.DiffTreeChangeBuilder;
 import com.intellij.util.diff.FlyweightCapableTreeStructure;
 import com.intellij.util.diff.ShallowNodeComparator;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 
@@ -674,7 +671,7 @@
     private int myBufferEnd = 1;
 
     @Override
-    public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+    public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
       myBuffer = buffer.subSequence(startOffset, endOffset);
       myIndex = 0;
       myBufferEnd = myBuffer.length();
@@ -710,6 +707,7 @@
       if (myIndex < myBufferEnd) myIndex++;
     }
 
+    @NotNull
     @Override
     public CharSequence getBufferSequence() {
       return myBuffer;
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
index c3a8641..8d8a924 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
@@ -288,7 +288,7 @@
 
     LocalFileSystem local = LocalFileSystem.getInstance();
     VirtualFile virtualDir = local.findFileByIoFile(testDir);
-    assert virtualDir != null : virtualDir;
+    assert virtualDir != null : testDir;
     virtualDir.getChildren();
     virtualDir.refresh(false, true);
     checkChildCount(virtualDir, 1);
diff --git a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy
index 0b451d3..677e42b 100644
--- a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy
+++ b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy
@@ -516,6 +516,12 @@
     assertPreference("*e", "fileIndex", "file", NameUtil.MatchingCaseSensitivity.NONE);
   }
 
+  public void "test first letter case match is important"() {
+    assertPreference("*pim", "PNGImageDecoder", "posIdMap", NameUtil.MatchingCaseSensitivity.NONE)
+    assertPreference("*pim", "PImageDecoder", "posIdMap", NameUtil.MatchingCaseSensitivity.NONE)
+    assertPreference("*er", "Error", "exchangeRequest", NameUtil.MatchingCaseSensitivity.NONE)
+  }
+
   public void testPreferences() {
     assertPreference(" fb", "FooBar", "_fooBar", NameUtil.MatchingCaseSensitivity.NONE);
     assertPreference("*foo", "barFoo", "foobar");
diff --git a/platform/platform-tests/testSrc/com/intellij/run/PathMacrosCollectorTest.java b/platform/platform-tests/testSrc/com/intellij/run/PathMacrosCollectorTest.java
index cff8a1c..5f961b7 100644
--- a/platform/platform-tests/testSrc/com/intellij/run/PathMacrosCollectorTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/run/PathMacrosCollectorTest.java
@@ -18,6 +18,7 @@
 import com.intellij.application.options.PathMacrosCollector;
 import com.intellij.application.options.PathMacrosImpl;
 import com.intellij.openapi.application.PathMacroFilter;
+import com.intellij.testFramework.UsefulTestCase;
 import junit.framework.TestCase;
 import org.jdom.Attribute;
 import org.jdom.Element;
@@ -41,21 +42,17 @@
     root.addContent(new Text("$$$ "));
     root.addContent(new Text("$c:\\a\\b\\c$ "));
     root.addContent(new Text("$Revision 1.23$"));
+    root.addContent(new Text("file://$root$/some/path/just$file$name.txt"));
 
     final Set<String> macros = PathMacrosCollector.getMacroNames(root, null, new PathMacrosImpl());
-
-    assertEquals(5, macros.size());
-    assertTrue(macros.contains("MACro1"));
-    assertTrue(macros.contains("macro4"));
-    assertTrue(macros.contains("mac_ro6"));
-    assertTrue(macros.contains("macr.o7"));
-    assertTrue(macros.contains("mac-ro8"));
+    UsefulTestCase.assertSameElements(macros, "MACro1", "macro4", "mac_ro6", "macr.o7", "mac-ro8", "root");
   }
 
   public void testWithRecursiveFilter() throws Exception {
     Element root = new Element("root");
     final Element configuration = new Element("configuration");
     configuration.setAttribute("value", "some text$macro5$fdsjfhdskjfsd$MACRO$");
+    configuration.setAttribute("value2", "file://$root$/some/path/just$file$name.txt");
     root.addContent(configuration);
 
     final Set<String> macros = PathMacrosCollector.getMacroNames(root, new PathMacroFilter() {
@@ -64,10 +61,7 @@
                                                                       return "value".equals(attribute.getName());
                                                                     }
                                                                   }, new PathMacrosImpl());
-
-    assertEquals(2, macros.size());
-    assertTrue(macros.contains("macro5"));
-    assertTrue(macros.contains("MACRO"));
+    UsefulTestCase.assertSameElements(macros, "macro5", "MACRO", "root");
   }
 
   public void testWithFilter() throws Exception {
diff --git a/platform/projectModel-api/src/com/intellij/ide/highlighter/ModuleFileType.java b/platform/projectModel-api/src/com/intellij/ide/highlighter/ModuleFileType.java
index 4a8fde4..9d06028 100644
--- a/platform/projectModel-api/src/com/intellij/ide/highlighter/ModuleFileType.java
+++ b/platform/projectModel-api/src/com/intellij/ide/highlighter/ModuleFileType.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.
@@ -29,33 +29,40 @@
   @NonNls public static final String DEFAULT_EXTENSION = "iml";
   @NonNls public static final String DOT_DEFAULT_EXTENSION = ".iml";
 
+  @Override
   @NotNull
   public String getName() {
     return "IDEA_MODULE";
   }
 
+  @Override
   @NotNull
   public String getDescription() {
     return IdeBundle.message("filetype.description.idea.module");
   }
 
+  @Override
   @NotNull
   public String getDefaultExtension() {
     return DEFAULT_EXTENSION;
   }
 
+  @Override
   public Icon getIcon() {
     return AllIcons.Nodes.IdeaModule;
   }
 
+  @Override
   public boolean isBinary() {
     return false;
   }
 
+  @Override
   public boolean isReadOnly() {
     return true;
   }
 
+  @Override
   public String getCharset(@NotNull VirtualFile file, final byte[] content) {
     return CharsetToolkit.UTF8;
   }
diff --git a/platform/projectModel-api/src/com/intellij/ide/highlighter/ProjectFileType.java b/platform/projectModel-api/src/com/intellij/ide/highlighter/ProjectFileType.java
index 43f5958..20f7a62 100644
--- a/platform/projectModel-api/src/com/intellij/ide/highlighter/ProjectFileType.java
+++ b/platform/projectModel-api/src/com/intellij/ide/highlighter/ProjectFileType.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.
@@ -29,33 +29,40 @@
   @NonNls public static final String DEFAULT_EXTENSION = "ipr";
   @NonNls public static final String DOT_DEFAULT_EXTENSION = ".ipr";
 
+  @Override
   @NotNull
   public String getName() {
     return "IDEA_PROJECT";
   }
 
+  @Override
   @NotNull
   public String getDescription() {
     return IdeBundle.message("filetype.description.idea.project");
   }
 
+  @Override
   @NotNull
   public String getDefaultExtension() {
     return DEFAULT_EXTENSION;
   }
 
+  @Override
   public Icon getIcon() {
     return AllIcons.Nodes.IdeaModule;
   }
 
+  @Override
   public boolean isBinary() {
     return false;
   }
 
+  @Override
   public boolean isReadOnly() {
     return true;
   }
 
+  @Override
   public String getCharset(@NotNull VirtualFile file, final byte[] content) {
     return CharsetToolkit.UTF8;
   }
diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/State.java b/platform/projectModel-api/src/com/intellij/openapi/components/State.java
index 8278b2d..ec6b970 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/components/State.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/components/State.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.
@@ -22,8 +22,15 @@
 @Retention(RetentionPolicy.RUNTIME)
 public @interface State {
   String name();
+
+  /**
+   * {@link RoamingType#GLOBAL} will be ignored, use only {@link RoamingType#DISABLED} or {@link RoamingType#PER_PLATFORM}
+   */
   RoamingType roamingType() default RoamingType.PER_USER;
+
   Storage[] storages();
+
   Class<? extends StateStorageChooser> storageChooser() default StorageAnnotationsDefaultValues.NullStateStorageChooser.class;
+
   boolean reloadable() default true;
-}
+}
\ No newline at end of file
diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/StorageAnnotationsDefaultValues.java b/platform/projectModel-api/src/com/intellij/openapi/components/StorageAnnotationsDefaultValues.java
index d9d3c92..5105105 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/components/StorageAnnotationsDefaultValues.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/components/StorageAnnotationsDefaultValues.java
@@ -26,42 +26,40 @@
 
 public interface StorageAnnotationsDefaultValues {
   class NullStateStorage implements StateStorage {
+    @Override
     @Nullable
     public <T> T getState(final Object component, final String componentName, Class<T> stateClass, @Nullable T mergeInto)
     throws StateStorageException {
       throw new UnsupportedOperationException("Method getState is not supported in " + getClass());
     }
 
+    @Override
     public boolean hasState(final Object component, final String componentName, final Class<?> aClass, final boolean reloadData) throws StateStorageException {
       throw new UnsupportedOperationException("Method hasState not implemented in " + getClass());
     }
 
-    public boolean needsSave() throws StateStorageException {
-      throw new UnsupportedOperationException("Method needsSave is not supported in " + getClass());
-    }
-
     public void save() throws StateStorageException {
       throw new UnsupportedOperationException("Method save is not supported in " + getClass());
     }
 
-    public Set<String> getUsedMacros() {
-      throw new UnsupportedOperationException("Method getUsedMacros not implemented in " + getClass());
-    }
-
+    @Override
     @NotNull
     public ExternalizationSession startExternalization() {
       throw new UnsupportedOperationException("Method startExternalization not implemented in " + getClass());
     }
 
+    @Override
     @NotNull
     public SaveSession startSave(@NotNull ExternalizationSession externalizationSession) {
       throw new UnsupportedOperationException("Method startSave not implemented in " + getClass());
     }
 
+    @Override
     public void finishSave(@NotNull SaveSession saveSession) {
       throw new UnsupportedOperationException("Method finishSave not implemented in " + getClass());
     }
 
+    @Override
     public void reload(@NotNull final Set<String> changedComponents) throws StateStorageException {
       throw new UnsupportedOperationException("Method reload not implemented in " + getClass());
     }
@@ -69,16 +67,19 @@
   }
 
   class NullStateStorageChooser implements StateStorageChooser {
+    @Override
     public Storage[] selectStorages(Storage[] storages, Object component, final StateStorageOperation operation) {
       throw new UnsupportedOperationException("Method selectStorages is not supported in " + getClass());
     }
   }
 
   class NullStateSplitter implements StateSplitter {
+    @Override
     public List<Pair<Element, String>> splitState(Element e) {
       throw new UnsupportedOperationException("Method splitState not implemented in " + getClass());
     }
 
+    @Override
     public void mergeStatesInto(final Element target, final Element[] elements) {
       throw new UnsupportedOperationException("Method mergeStatesInto not implemented in " + getClass());
     }
diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ContentEntry.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ContentEntry.java
index 360de66..d6e983c 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/roots/ContentEntry.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ContentEntry.java
@@ -135,6 +135,10 @@
   @NotNull
   SourceFolder addSourceFolder(@NotNull String url, boolean isTestSource);
 
+  @NotNull
+  <P extends JpsElement>
+  SourceFolder addSourceFolder(@NotNull String url, @NotNull JpsModuleSourceRootType<P> type);
+
   /**
    * Removes a source or test source root from this content root.
    *
diff --git a/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosCollector.java b/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosCollector.java
index 05d8533..b4ed15f 100644
--- a/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosCollector.java
+++ b/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosCollector.java
@@ -21,12 +21,13 @@
 import com.intellij.openapi.components.PathMacroMap;
 import com.intellij.openapi.extensions.ExtensionPointName;
 import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.containers.ContainerUtilRt;
+import gnu.trove.THashSet;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
@@ -43,9 +44,6 @@
   private final Matcher myMatcher;
   private final Map<String, String> myMacroMap = ContainerUtilRt.newLinkedHashMap();
 
-  private static final String FILE_PROTOCOL = "file:";
-  private static final String JAR_PROTOCOL = "jar:";
-
   private PathMacrosCollector() {
     myMatcher = MACRO_PATTERN.matcher("");
   }
@@ -59,7 +57,7 @@
   public static Set<String> getMacroNames(Element root, @Nullable PathMacroFilter filter, @NotNull final PathMacros pathMacros) {
     final PathMacrosCollector collector = new PathMacrosCollector();
     collector.substitute(root, true, false, filter);
-    final HashSet<String> result = new HashSet<String>(collector.myMacroMap.keySet());
+    final Set<String> result = new THashSet<String>(collector.myMacroMap.keySet());
     result.removeAll(pathMacros.getSystemMacroNames());
     result.removeAll(pathMacros.getLegacyMacroNames());
     result.removeAll(PathMacrosImpl.getToolMacroNames());
@@ -69,12 +67,13 @@
 
   @Override
   public String substituteRecursively(String text, boolean caseSensitive) {
-    if (text == null || text.isEmpty()) return text;
+    if (StringUtil.isEmpty(text)) {
+      return text;
+    }
 
     myMatcher.reset(text);
     while (myMatcher.find()) {
-      final String macroName = myMatcher.group(1);
-      myMacroMap.put(macroName, null);
+      myMacroMap.put(myMatcher.group(1), null);
     }
 
     return text;
@@ -82,23 +81,30 @@
 
   @Override
   public String substitute(String text, boolean caseSensitive) {
-    if (text == null || text.isEmpty()) return text;
-
-    String protocol = null;
-    if (text.length() > 7 && text.charAt(0) == 'f') {
-      protocol = FILE_PROTOCOL;
-    } else if (text.length() > 6 && text.charAt(0) == 'j') {
-      protocol = JAR_PROTOCOL;
-    } else if ('$' != text.charAt(0)) {
+    if (StringUtil.isEmpty(text)) {
       return text;
     }
 
-    if (protocol != null && !text.startsWith(protocol)) return text;
+    int startPos = -1;
+    if (text.charAt(0) == '$') {
+      startPos = 0;
+    }
+    else {
+      for (String protocol : ReplacePathToMacroMap.PROTOCOLS) {
+        if (text.length() > protocol.length() + 4 && text.startsWith(protocol) && text.charAt(protocol.length()) == ':') {
+          startPos = protocol.length() + 1;
+          if (text.charAt(startPos) == '/') startPos++;
+          if (text.charAt(startPos) == '/') startPos++;
+        }
+      }
+    }
+    if (startPos < 0) {
+      return text;
+    }
 
-    myMatcher.reset(text);
-    if (myMatcher.find()) {
-      final String macroName = myMatcher.group(1);
-      myMacroMap.put(macroName, null);
+    myMatcher.reset(text).region(startPos, text.length());
+    if (myMatcher.lookingAt()) {
+      myMacroMap.put(myMatcher.group(1), null);
     }
 
     return text;
diff --git a/platform/projectModel-impl/src/com/intellij/application/options/ReplacePathToMacroMap.java b/platform/projectModel-impl/src/com/intellij/application/options/ReplacePathToMacroMap.java
index ffb0096..10acdbe 100644
--- a/platform/projectModel-impl/src/com/intellij/application/options/ReplacePathToMacroMap.java
+++ b/platform/projectModel-impl/src/com/intellij/application/options/ReplacePathToMacroMap.java
@@ -43,7 +43,7 @@
   private List<String> myPathsIndex = null;
   private final Map<String, String> myMacroMap = ContainerUtilRt.newLinkedHashMap();
 
-  @NonNls private static final String[] PROTOCOLS;
+  @NonNls public static final String[] PROTOCOLS;
   static {
     List<String> protocols = new ArrayList<String>();
     protocols.add("file");
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java
index 33fac00..82dece3 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java
@@ -25,6 +25,7 @@
 import com.intellij.openapi.util.JDOMUtil;
 import com.intellij.util.ArrayUtil;
 import gnu.trove.THashMap;
+import gnu.trove.THashSet;
 import org.jdom.Attribute;
 import org.jdom.Element;
 import org.jetbrains.annotations.NonNls;
@@ -54,37 +55,32 @@
   }
 
   public void load(@NotNull Element rootElement) throws IOException {
-    final Element[] elements = JDOMUtil.getElements(rootElement);
-    for (Element element : elements) {
-      if (element.getName().equals(COMPONENT)) {
-        final String name = element.getAttributeValue(NAME);
+    for (Iterator<Element> iterator = rootElement.getChildren(COMPONENT).iterator(); iterator.hasNext(); ) {
+      Element element = iterator.next();
+      String name = element.getAttributeValue(NAME);
+      if (name == null) {
+        LOG.info("Broken content in file : " + this);
+        continue;
+      }
 
-        if (name == null) {
-          LOG.info("Broken content in file : " + this);
-          continue;
+      iterator.remove();
+
+      if (element.getAttributes().size() > 1 || !element.getChildren().isEmpty()) {
+        assert element.getAttributeValue(NAME) != null : "No name attribute for component: " + name + " in " + this;
+
+        Element existingElement = myComponentStates.get(name);
+        if (existingElement != null) {
+          element = mergeElements(name, element, existingElement);
         }
 
-        element.detach();
-
-        if (element.getAttributes().size() > 1 || !element.getChildren().isEmpty()) {
-          assert element.getAttributeValue(NAME) != null : "No name attribute for component: " + name + " in " + this;
-
-          Element existingElement = myComponentStates.get(name);
-
-          if (existingElement != null) {
-            element = mergeElements(name, element, existingElement);
-          }
-
-          myComponentStates.put(name, element);
-        }
+        myComponentStates.put(name, element);
       }
     }
   }
 
   private static Element mergeElements(final String name, final Element element1, final Element element2) {
     ExtensionPoint<XmlConfigurationMerger> point = Extensions.getRootArea().getExtensionPoint("com.intellij.componentConfigurationMerger");
-    XmlConfigurationMerger[] mergers = point.getExtensions();
-    for (XmlConfigurationMerger merger : mergers) {
+    for (XmlConfigurationMerger merger : point.getExtensions()) {
       if (merger.getComponentName().equals(name)) {
         return merger.merge(element1, element2);
       }
@@ -111,14 +107,12 @@
 
   @Nullable
   public Element getState(final String name) {
-    final Element e = myComponentStates.get(name);
-
-    if (e != null) {
-      assert e.getAttributeValue(NAME) != null : "No name attribute for component: " + name + " in " + this;
-      e.removeAttribute(NAME);
+    final Element element = myComponentStates.get(name);
+    if (element != null) {
+      assert element.getAttributeValue(NAME) != null : "No name attribute for component: " + name + " in " + this;
+      element.removeAttribute(NAME);
     }
-
-    return e;
+    return element;
   }
 
   void removeState(final String componentName) {
@@ -174,10 +168,10 @@
   }
 
   public Set<String> getDifference(final StorageData storageData, PathMacroSubstitutor substitutor) {
-    Set<String> bothStates = new HashSet<String>(myComponentStates.keySet());
+    Set<String> bothStates = new THashSet<String>(myComponentStates.keySet());
     bothStates.retainAll(storageData.myComponentStates.keySet());
 
-    Set<String> diffs = new HashSet<String>();
+    Set<String> diffs = new THashSet<String>();
     diffs.addAll(storageData.myComponentStates.keySet());
     diffs.addAll(myComponentStates.keySet());
     diffs.removeAll(bothStates);
@@ -196,7 +190,6 @@
       }
     }
 
-
     return diffs;
   }
 
@@ -209,7 +202,9 @@
   }
 
   public void checkUnknownMacros(TrackingPathMacroSubstitutor pathMacroSubstitutor) {
-    if (pathMacroSubstitutor == null) return;
+    if (pathMacroSubstitutor == null) {
+      return;
+    }
 
     for (String componentName : myComponentStates.keySet()) {
       final Set<String> unknownMacros = PathMacrosCollector.getMacroNames(myComponentStates.get(componentName));
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java
index 1dea810..980123e 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java
@@ -21,6 +21,7 @@
 import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.roots.libraries.Library;
 import com.intellij.util.Consumer;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Collections;
@@ -118,7 +119,7 @@
     });
   }
 
-  private static void updateModel(Module module, Consumer<ModifiableRootModel> task) {
+  public static void updateModel(@NotNull Module module, @NotNull Consumer<ModifiableRootModel> task) {
     final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
     try {
       task.consume(model);
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java
index 0197e1d..085abe6 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java
@@ -42,6 +42,7 @@
 import org.jetbrains.jps.model.JpsSimpleElement;
 import org.jetbrains.jps.model.java.JavaSourceRootProperties;
 import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
 import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer;
 
@@ -209,10 +210,15 @@
   @NotNull
   @Override
   public SourceFolder addSourceFolder(@NotNull String url, boolean isTestSource) {
+    return addSourceFolder(url, isTestSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE);
+  }
+
+  @NotNull
+  @Override
+  public <P extends JpsElement> SourceFolder addSourceFolder(@NotNull String url, @NotNull JpsModuleSourceRootType<P> type) {
     assertFolderUnderMe(url);
-    JavaSourceRootType type = isTestSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE;
-    JpsSimpleElement<JavaSourceRootProperties> properties = JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(""));
-    return addSourceFolder(new SourceFolderImpl(JpsElementFactory.getInstance().createModuleSourceRoot(url, type, properties), this));
+    JpsModuleSourceRoot sourceRoot = JpsElementFactory.getInstance().createModuleSourceRoot(url, type, type.createDefaultProperties());
+    return addSourceFolder(new SourceFolderImpl(sourceRoot, this));
   }
 
   @NotNull
diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java
index 44e5ee5..49a391d 100644
--- a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java
+++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java
@@ -185,10 +185,7 @@
   private SourceFolder addSourceFolder(final String url, boolean isTestSource, String packagePrefix) {
     final JavaSourceRootType rootType = isTestSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE;
     JpsSimpleElement<JavaSourceRootProperties> properties = JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(packagePrefix));
-    final JpsModuleSourceRoot sourceRoot = myModule.addSourceRoot(url, rootType, properties);
-    final JpsSourceFolder sourceFolder = new JpsSourceFolder(sourceRoot, this);
-    mySourceFolders.add(sourceFolder);
-    return sourceFolder;
+    return addSourceFolder(url, rootType, properties);
   }
 
   @NotNull
@@ -197,6 +194,19 @@
     return addSourceFolder(url, isTestSource, "");
   }
 
+  @NotNull
+  @Override
+  public <P extends JpsElement> SourceFolder addSourceFolder(@NotNull String url, @NotNull JpsModuleSourceRootType<P> type) {
+    return addSourceFolder(url, type, type.createDefaultProperties());
+  }
+
+  private <P extends JpsElement> SourceFolder addSourceFolder(final String url, JpsModuleSourceRootType<P> type, P properties) {
+    final JpsModuleSourceRoot sourceRoot = myModule.addSourceRoot(url, type, properties);
+    final JpsSourceFolder sourceFolder = new JpsSourceFolder(sourceRoot, this);
+    mySourceFolders.add(sourceFolder);
+    return sourceFolder;
+  }
+
   @Override
   public void removeSourceFolder(@NotNull SourceFolder sourceFolder) {
     final JpsSourceFolder folder = (JpsSourceFolder)sourceFolder;
diff --git a/platform/projectModel-impl/src/messages/ProjectBundle.properties b/platform/projectModel-impl/src/messages/ProjectBundle.properties
index 0c0d6f9..d44173b 100644
--- a/platform/projectModel-impl/src/messages/ProjectBundle.properties
+++ b/platform/projectModel-impl/src/messages/ProjectBundle.properties
@@ -167,6 +167,7 @@
 module.classpath.button.move.up=Move Up
 module.classpath.button.move.down=Move Down
 module.remove.confirmation.prompt=Remove {1, choice, 1#Module|2#Modules} {0} from the project?\nNo files will be deleted.
+project.remove.confirmation.prompt=Would you like to detach the {1, choice, 1#project|2#projects} {0}?
 module.remove.command=Detach module from project
 module.new.action=New Module
 module.new.action.description=Add new module to the project
@@ -346,7 +347,6 @@
 error.message.unknown.facet.type.0=Unknown facet type: ''{0}''
 error.message.cannot.load.facet.condiguration.0=Cannot load facet condiguration: {0}
 error.message.facet.type.isn.t.specified=Facet type isn''t specified
-error.message.cannot.find.underlying.facet.type.for.0=Cannot find underlying facet type for ''{0}''
 error.message.0.facet.must.be.placed.under.1.facet={0} facet must be placed under {1} facet
 error.message.0.cannot.be.placed.under.1={0} cannot be placed under {1}
 error.message.0.facets.are.not.allowed.in.1={0} facets are not allowed in {1}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgent.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgent.java
new file mode 100644
index 0000000..4eb2bf1
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgent.java
@@ -0,0 +1,8 @@
+package com.intellij.remoteServer.agent;
+
+/**
+ * @author michael.golubev
+ */
+public interface RemoteAgent {
+
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgentManager.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgentManager.java
new file mode 100644
index 0000000..10c81de
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgentManager.java
@@ -0,0 +1,27 @@
+package com.intellij.remoteServer.agent;
+
+import com.intellij.openapi.components.ServiceManager;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * @author michael.golubev
+ */
+public abstract class RemoteAgentManager {
+
+  public static RemoteAgentManager getInstance() {
+    return ServiceManager.getService(RemoteAgentManager.class);
+  }
+
+  public abstract <T extends RemoteAgent> T createAgent(RemoteAgentProxyFactory agentProxyFactory,
+                                                        List<File> instanceLibraries,
+                                                        List<Class<?>> commonJarClasses,
+                                                        String specificsRuntimeModuleName,
+                                                        String specificsBuildJarPath,
+                                                        Class<T> agentInterface,
+                                                        String agentClassName,
+                                                        Class<?> pluginClass) throws Exception;
+
+  public abstract RemoteAgentProxyFactory createReflectiveThreadProxyFactory(ClassLoader callerClassLoader);
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgentProxyFactory.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgentProxyFactory.java
new file mode 100644
index 0000000..1cf9c73
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgentProxyFactory.java
@@ -0,0 +1,12 @@
+package com.intellij.remoteServer.agent;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * @author michael.golubev
+ */
+public interface RemoteAgentProxyFactory {
+
+  <T> T createProxy(List<File> libraries, Class<T> agentInterface, String agentClassName) throws Exception;
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/AsyncCall.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/AsyncCall.java
new file mode 100644
index 0000000..e310564
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/AsyncCall.java
@@ -0,0 +1,16 @@
+package com.intellij.remoteServer.agent.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: michael.golubev
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface AsyncCall {
+
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/ChildCall.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/ChildCall.java
new file mode 100644
index 0000000..c3fc17b
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/ChildCall.java
@@ -0,0 +1,15 @@
+package com.intellij.remoteServer.agent.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author michael.golubev
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface ChildCall {
+
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/FinalCall.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/FinalCall.java
new file mode 100644
index 0000000..5b77d54
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/FinalCall.java
@@ -0,0 +1,16 @@
+package com.intellij.remoteServer.agent.annotation;
+
+/**
+ * @author michael.golubev
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface FinalCall {
+
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/ImmediateCall.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/ImmediateCall.java
new file mode 100644
index 0000000..33767d7
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/ImmediateCall.java
@@ -0,0 +1,15 @@
+package com.intellij.remoteServer.agent.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author michael.golubev
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface ImmediateCall {
+
+}
diff --git a/platform/remote-servers/impl/src/META-INF/RemoteServers.xml b/platform/remote-servers/impl/src/META-INF/RemoteServers.xml
index d8b3bdf..a539fbe 100644
--- a/platform/remote-servers/impl/src/META-INF/RemoteServers.xml
+++ b/platform/remote-servers/impl/src/META-INF/RemoteServers.xml
@@ -9,6 +9,8 @@
                         serviceImplementation="com.intellij.remoteServer.impl.configuration.RemoteServersManagerImpl"/>
     <applicationService serviceInterface="com.intellij.remoteServer.runtime.ServerConnectionManager"
                         serviceImplementation="com.intellij.remoteServer.impl.runtime.ServerConnectionManagerImpl"/>
+    <applicationService serviceInterface="com.intellij.remoteServer.agent.RemoteAgentManager"
+                        serviceImplementation="com.intellij.remoteServer.agent.impl.RemoteAgentManagerImpl"/>
     <applicationConfigurable instance="com.intellij.remoteServer.impl.configuration.RemoteServerListConfigurable"/>
     <programRunner implementation="com.intellij.remoteServer.impl.runtime.DeployToServerRunner"/>
     <projectService serviceInterface="com.intellij.remoteServer.runtime.ui.RemoteServersView"
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/CallerClassLoaderProvider.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/CallerClassLoaderProvider.java
new file mode 100644
index 0000000..e6910db
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/CallerClassLoaderProvider.java
@@ -0,0 +1,19 @@
+package com.intellij.remoteServer.agent.impl;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author michael.golubev
+ */
+public class CallerClassLoaderProvider {
+
+  private ClassLoader myCallerClassLoader;
+
+  public CallerClassLoaderProvider(@Nullable ClassLoader callerClassLoader) {
+    myCallerClassLoader = callerClassLoader;
+  }
+
+  public ClassLoader getCallerClassLoader(Class<?> classOfDefaultLoader) {
+    return myCallerClassLoader == null ? classOfDefaultLoader.getClassLoader() : myCallerClassLoader;
+  }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ChildWrapperCreator.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ChildWrapperCreator.java
new file mode 100644
index 0000000..d8be065
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ChildWrapperCreator.java
@@ -0,0 +1,11 @@
+package com.intellij.remoteServer.agent.impl;
+
+import java.lang.reflect.InvocationHandler;
+
+/**
+ * @author michael.golubev
+ */
+public interface ChildWrapperCreator {
+
+  InvocationHandler createWrapperInvocationHandler(Object child);
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentClassLoaderCache.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentClassLoaderCache.java
new file mode 100644
index 0000000..5b9311a
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentClassLoaderCache.java
@@ -0,0 +1,24 @@
+package com.intellij.remoteServer.agent.impl;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteAgentClassLoaderCache {
+
+  private final Map<Set<URL>, URLClassLoader> myUrls2ClassLoader = new HashMap<Set<URL>, URLClassLoader>();
+
+  public URLClassLoader getOrCreateClassLoader(Set<URL> libraryUrls) {
+    URLClassLoader result = myUrls2ClassLoader.get(libraryUrls);
+    if (result == null) {
+      result = new URLClassLoader(libraryUrls.toArray(new URL[libraryUrls.size()]), null);
+      myUrls2ClassLoader.put(libraryUrls, result);
+    }
+    return result;
+  }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentManagerImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentManagerImpl.java
new file mode 100644
index 0000000..6f3bc30
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentManagerImpl.java
@@ -0,0 +1,61 @@
+package com.intellij.remoteServer.agent.impl;
+
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.remoteServer.agent.RemoteAgent;
+import com.intellij.remoteServer.agent.RemoteAgentManager;
+import com.intellij.remoteServer.agent.RemoteAgentProxyFactory;
+import com.intellij.util.PathUtil;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteAgentManagerImpl extends RemoteAgentManager {
+
+  private final RemoteAgentClassLoaderCache myClassLoaderCache = new RemoteAgentClassLoaderCache();
+
+  @Override
+  public <T extends RemoteAgent> T createAgent(RemoteAgentProxyFactory agentProxyFactory,
+                                               List<File> instanceLibraries,
+                                               List<Class<?>> commonJarClasses,
+                                               String specificsRuntimeModuleName,
+                                               String specificsBuildJarPath,
+                                               Class<T> agentInterface,
+                                               String agentClassName,
+                                               Class<?> pluginClass) throws Exception {
+
+    List<Class<?>> allCommonJarClasses = new ArrayList<Class<?>>();
+    allCommonJarClasses.addAll(commonJarClasses);
+    allCommonJarClasses.add(RemoteAgent.class);
+    allCommonJarClasses.add(agentInterface);
+
+    List<File> libraries = new ArrayList<File>();
+    libraries.addAll(instanceLibraries);
+
+    for (Class<?> clazz : allCommonJarClasses) {
+      libraries.add(new File(PathUtil.getJarPathForClass(clazz)));
+    }
+
+    File plugin = new File(PathUtil.getJarPathForClass(pluginClass));
+    String allPluginsDir = plugin.getParent();
+    if (plugin.isDirectory()) {
+      // runtime behavior
+      File specificsModule = new File(allPluginsDir, specificsRuntimeModuleName);
+      libraries.add(specificsModule);
+    }
+    else {
+      // build behavior
+      File specificsDir = new File(allPluginsDir, FileUtil.toSystemDependentName(specificsBuildJarPath));
+      libraries.add(specificsDir);
+    }
+
+    return agentProxyFactory.createProxy(libraries, agentInterface, agentClassName);
+  }
+
+  public RemoteAgentProxyFactory createReflectiveThreadProxyFactory(ClassLoader callerClassLoader) {
+    return new RemoteAgentReflectiveThreadProxyFactory(myClassLoaderCache, callerClassLoader);
+  }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentProxyFactoryBase.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentProxyFactoryBase.java
new file mode 100644
index 0000000..688869a
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentProxyFactoryBase.java
@@ -0,0 +1,42 @@
+package com.intellij.remoteServer.agent.impl;
+
+import com.intellij.remoteServer.agent.RemoteAgentProxyFactory;
+import com.intellij.remoteServer.agent.impl.util.UrlCollector;
+
+import java.io.File;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.net.URL;
+import java.util.List;
+
+/**
+ * @author michael.golubev
+ */
+public abstract class RemoteAgentProxyFactoryBase implements RemoteAgentProxyFactory {
+
+  private final CallerClassLoaderProvider myCallerClassLoaderProvider;
+
+  public RemoteAgentProxyFactoryBase(CallerClassLoaderProvider callerClassLoaderProvider) {
+    myCallerClassLoaderProvider = callerClassLoaderProvider;
+  }
+
+  @Override
+  public <T> T createProxy(List<File> libraries, Class<T> agentInterface, String agentClassName) throws Exception {
+    ClassLoader callerClassLoader = myCallerClassLoaderProvider.getCallerClassLoader(agentInterface);
+    ClassLoader agentClassLoader = createAgentClassLoader(libraries);
+    Object agentImpl = agentClassLoader.loadClass(agentClassName).getDeclaredConstructor().newInstance();
+    return agentInterface.cast(Proxy.newProxyInstance(agentInterface.getClassLoader(),
+                                                      new Class[]{agentInterface},
+                                                      createInvocationHandler(agentImpl, agentClassLoader, callerClassLoader)));
+  }
+
+  protected ClassLoader createAgentClassLoader(List<File> libraries) throws Exception {
+    return createAgentClassLoader(new UrlCollector().collect(libraries));
+  }
+
+  protected abstract ClassLoader createAgentClassLoader(URL[] agentLibraryUrls) throws Exception;
+
+  protected abstract InvocationHandler createInvocationHandler(Object agentImpl,
+                                                               ClassLoader agentClassLoader,
+                                                               ClassLoader callerClassLoader);
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentReflectiveProxyFactory.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentReflectiveProxyFactory.java
new file mode 100644
index 0000000..c2bf104
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentReflectiveProxyFactory.java
@@ -0,0 +1,140 @@
+package com.intellij.remoteServer.agent.impl;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.containers.hash.HashSet;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.reflect.*;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.Set;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteAgentReflectiveProxyFactory extends RemoteAgentProxyFactoryBase {
+
+  private static final Logger LOG = Logger.getInstance("#" + RemoteAgentReflectiveProxyFactory.class.getName());
+
+  private final RemoteAgentClassLoaderCache myClassLoaderCache;
+
+  public RemoteAgentReflectiveProxyFactory(@Nullable RemoteAgentClassLoaderCache classLoaderCache,
+                                           CallerClassLoaderProvider callerClassLoaderProvider) {
+    super(callerClassLoaderProvider);
+    myClassLoaderCache = classLoaderCache;
+  }
+
+  @Override
+  protected ClassLoader createAgentClassLoader(URL[] agentLibraryUrls) throws Exception {
+    Set<URL> urls = new HashSet<URL>();
+    urls.addAll(Arrays.asList(agentLibraryUrls));
+    return myClassLoaderCache == null
+           ? new URLClassLoader(urls.toArray(new URL[urls.size()]), null)
+           : myClassLoaderCache.getOrCreateClassLoader(urls);
+  }
+
+  @Override
+  protected InvocationHandler createInvocationHandler(Object agentImpl, ClassLoader agentClassLoader, ClassLoader callerClassLoader) {
+    return new ReflectiveInvocationHandler(agentImpl, agentClassLoader, callerClassLoader);
+  }
+
+  private static class ReflectiveInvocationHandler implements InvocationHandler {
+
+    private final Object myTarget;
+    private final ClassLoader myTargetClassLoader;
+    private final ClassLoader mySourceClassLoader;
+
+    public ReflectiveInvocationHandler(Object target, ClassLoader targetClassLoader, ClassLoader sourceClassLoader) {
+      myTarget = target;
+      myTargetClassLoader = targetClassLoader;
+      mySourceClassLoader = sourceClassLoader;
+    }
+
+    @Nullable
+    @Override
+    public Object invoke(Object proxy, final Method method, final Object[] args) {
+      ClassLoader initialClassLoader = Thread.currentThread().getContextClassLoader();
+      try {
+        Thread.currentThread().setContextClassLoader(myTargetClassLoader);
+
+        Class<?>[] parameterTypes = method.getParameterTypes();
+        Class<?>[] delegateParameterTypes = new Class<?>[parameterTypes.length];
+
+        Object[] delegateArgs = new Object[parameterTypes.length];
+        for (int i = 0; i < parameterTypes.length; i++) {
+          Mirror parameterMirror = new Mirror(parameterTypes[i], args[i], mySourceClassLoader, myTargetClassLoader);
+          delegateParameterTypes[i] = parameterMirror.getMirrorType();
+          delegateArgs[i] = parameterMirror.getMirrorValue();
+        }
+
+        Method delegateMethod = myTarget.getClass().getMethod(method.getName(), delegateParameterTypes);
+        delegateMethod.setAccessible(true);
+
+        Object result = delegateMethod.invoke(myTarget, delegateArgs);
+        Mirror resultMirror = new Mirror(delegateMethod.getReturnType(), result, myTargetClassLoader, mySourceClassLoader);
+        return resultMirror.getMirrorValue();
+      }
+      catch (IllegalAccessException e) {
+        LOG.error(e);
+        return null;
+      }
+      catch (InvocationTargetException e) {
+        LOG.error(e);
+        return null;
+      }
+      catch (NoSuchMethodException e) {
+        LOG.error(e);
+        return null;
+      }
+      catch (ClassNotFoundException e) {
+        LOG.error(e);
+        return null;
+      }
+      finally {
+        Thread.currentThread().setContextClassLoader(initialClassLoader);
+      }
+    }
+  }
+
+  private static class Mirror {
+
+    private final Class<?> myMirrorType;
+
+    private final Object myMirrorValue;
+
+    public Mirror(Class<?> type, Object value, ClassLoader classLoader, ClassLoader mirrorClassLoader) throws ClassNotFoundException {
+      if (type.isArray()) {
+        Class<?> componentType = type.getComponentType();
+        Mirror componentMirror = new Mirror(componentType, null, classLoader, mirrorClassLoader);
+        int length = value == null ? 0 : Array.getLength(value);
+        Object mirrorValue = Array.newInstance(componentMirror.getMirrorType(), length);
+        for (int i = 0; i < length; i++) {
+          Mirror itemMirror = new Mirror(componentType, Array.get(value, i), classLoader, mirrorClassLoader);
+          Array.set(mirrorValue, i, itemMirror.getMirrorValue());
+        }
+        myMirrorType = mirrorValue.getClass();
+        myMirrorValue = value == null ? null : mirrorValue;
+      }
+      else if (type.isInterface()) {
+        myMirrorType = mirrorClassLoader.loadClass(type.getName());
+        myMirrorValue = value == null ? null
+                                      : Proxy.newProxyInstance(mirrorClassLoader,
+                                                               new Class[]{myMirrorType},
+                                                               new ReflectiveInvocationHandler(value, classLoader, mirrorClassLoader));
+      }
+      else {
+        myMirrorType = type;
+        myMirrorValue = value;
+      }
+    }
+
+    public Class<?> getMirrorType() {
+      return myMirrorType;
+    }
+
+    public Object getMirrorValue() {
+      return myMirrorValue;
+    }
+  }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentReflectiveThreadProxyFactory.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentReflectiveThreadProxyFactory.java
new file mode 100644
index 0000000..2669670
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentReflectiveThreadProxyFactory.java
@@ -0,0 +1,22 @@
+package com.intellij.remoteServer.agent.impl;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteAgentReflectiveThreadProxyFactory extends RemoteAgentThreadProxyFactory {
+
+  public RemoteAgentReflectiveThreadProxyFactory() {
+    this(null, (ClassLoader)null);
+  }
+
+  public RemoteAgentReflectiveThreadProxyFactory(RemoteAgentClassLoaderCache classLoaderCache, @Nullable ClassLoader callerClassLoader) {
+    this(classLoaderCache, new CallerClassLoaderProvider(callerClassLoader));
+  }
+
+  private RemoteAgentReflectiveThreadProxyFactory(RemoteAgentClassLoaderCache classLoaderCache,
+                                                  CallerClassLoaderProvider callerClassLoaderProvider) {
+    super(callerClassLoaderProvider, new RemoteAgentReflectiveProxyFactory(classLoaderCache, callerClassLoaderProvider), null);
+  }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentThreadProxyCreator.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentThreadProxyCreator.java
new file mode 100644
index 0000000..c5be2b2
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentThreadProxyCreator.java
@@ -0,0 +1,32 @@
+package com.intellij.remoteServer.agent.impl;
+
+import com.intellij.remoteServer.agent.impl.util.SequentialTaskExecutor;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.reflect.Proxy;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteAgentThreadProxyCreator {
+
+  private final CallerClassLoaderProvider myCallerClassLoaderProvider;
+  private final ChildWrapperCreator myPreWrapperCreator;
+
+  public RemoteAgentThreadProxyCreator(CallerClassLoaderProvider callerClassLoaderProvider,
+                                       @Nullable ChildWrapperCreator preWrapperCreator) {
+    myPreWrapperCreator = preWrapperCreator;
+    myCallerClassLoaderProvider = callerClassLoaderProvider;
+  }
+
+  public <T> T createProxy(Class<T> agentInterface, T agentInstance) {
+    final SequentialTaskExecutor taskExecutor = new SequentialTaskExecutor();
+
+    ClassLoader callerClassLoader = myCallerClassLoaderProvider.getCallerClassLoader(agentInterface);
+
+    return agentInterface.cast(Proxy.newProxyInstance(callerClassLoader,
+                                                      new Class[]{agentInterface},
+                                                      new ThreadInvocationHandler(taskExecutor, callerClassLoader, agentInstance,
+                                                                                  myPreWrapperCreator)));
+  }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentThreadProxyFactory.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentThreadProxyFactory.java
new file mode 100644
index 0000000..651e2ae
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentThreadProxyFactory.java
@@ -0,0 +1,29 @@
+package com.intellij.remoteServer.agent.impl;
+
+import com.intellij.remoteServer.agent.RemoteAgentProxyFactory;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteAgentThreadProxyFactory implements RemoteAgentProxyFactory {
+
+  private final RemoteAgentThreadProxyCreator myCreator;
+  private final RemoteAgentProxyFactory myDelegate;
+
+  public RemoteAgentThreadProxyFactory(CallerClassLoaderProvider callerClassLoaderProvider, @NotNull RemoteAgentProxyFactory delegate,
+                                       @Nullable ChildWrapperCreator preWrapperCreator) {
+    myCreator = new RemoteAgentThreadProxyCreator(callerClassLoaderProvider, preWrapperCreator);
+    myDelegate = delegate;
+  }
+
+  @Override
+  public <T> T createProxy(List<File> libraries, Class<T> agentInterface, String agentClassName) throws Exception {
+    T agentDelegate = myDelegate.createProxy(libraries, agentInterface, agentClassName);
+    return myCreator.createProxy(agentInterface, agentDelegate);
+  }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ThreadInvocationHandler.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ThreadInvocationHandler.java
new file mode 100644
index 0000000..3e26022
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ThreadInvocationHandler.java
@@ -0,0 +1,153 @@
+package com.intellij.remoteServer.agent.impl;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.remoteServer.agent.annotation.AsyncCall;
+import com.intellij.remoteServer.agent.annotation.ChildCall;
+import com.intellij.remoteServer.agent.annotation.FinalCall;
+import com.intellij.remoteServer.agent.annotation.ImmediateCall;
+import com.intellij.remoteServer.agent.impl.util.FinalTask;
+import com.intellij.remoteServer.agent.impl.util.SequentialTaskExecutor;
+import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+/**
+ * @author michael.golubev
+ */
+public class ThreadInvocationHandler implements InvocationHandler {
+
+  private static final Logger LOG = Logger.getInstance("#" + ThreadInvocationHandler.class.getName());
+
+  private final SequentialTaskExecutor myTaskExecutor;
+  private final ClassLoader myCallerClassLoader;
+  private final Object myTarget;
+  private final ChildWrapperCreator myPreWrapperFactory;
+
+  private Map<Object, Object> myChild2Wrapped;
+
+  public ThreadInvocationHandler(SequentialTaskExecutor taskExecutor, ClassLoader callerClassLoader, Object target) {
+    this(taskExecutor, callerClassLoader, target, null);
+  }
+
+  public ThreadInvocationHandler(SequentialTaskExecutor taskExecutor, ClassLoader callerClassLoader, Object target,
+                                 @Nullable ChildWrapperCreator preWrapperCreator) {
+    myTaskExecutor = taskExecutor;
+    myCallerClassLoader = callerClassLoader;
+    myTarget = target;
+    myPreWrapperFactory = preWrapperCreator;
+    myChild2Wrapped = new HashMap<Object, Object>();
+  }
+
+  @Override
+  public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
+    final Callable<Object> taskCallable = new Callable<Object>() {
+
+      @Override
+      public Object call() {
+        try {
+          return method.invoke(myTarget, args);
+        }
+        catch (IllegalAccessException e) {
+          LOG.error(e);
+          return null;
+        }
+        catch (InvocationTargetException e) {
+          LOG.error(e);
+          return null;
+        }
+      }
+    };
+
+    try {
+      boolean immediateCall = method.getAnnotation(ImmediateCall.class) != null;
+
+      boolean childCall = method.getAnnotation(ChildCall.class) != null;
+      if (childCall) {
+        Object child = immediateCall ? taskCallable.call() : myTaskExecutor.queueAndWaitTask(taskCallable);
+        if (child == null) {
+          return null;
+        }
+
+        Object cached = myChild2Wrapped.get(child);
+        if (cached != null) {
+          return cached;
+        }
+
+        Class<?> childClass = child.getClass();
+        Class<?>[] childInterfaces = childClass.getInterfaces();
+        LOG.assertTrue(childInterfaces.length == 1, "Child class is expected to implement single child interface");
+        Class<?> childInterface = childInterfaces[0];
+
+        Class<?> callerChildInterface;
+        try {
+          callerChildInterface = myCallerClassLoader.loadClass(childInterface.getName());
+        }
+        catch (ClassNotFoundException e) {
+          LOG.error(e);
+          return null;
+        }
+
+        Object preWrappedChild;
+        if (myPreWrapperFactory == null) {
+          preWrappedChild = child;
+        }
+        else {
+          preWrappedChild = Proxy.newProxyInstance(myCallerClassLoader,
+                                                   new Class[]{callerChildInterface},
+                                                   myPreWrapperFactory.createWrapperInvocationHandler(child));
+        }
+
+        Object result = Proxy.newProxyInstance(myCallerClassLoader,
+                                               new Class[]{callerChildInterface},
+                                               new ThreadInvocationHandler(myTaskExecutor, myCallerClassLoader, preWrappedChild,
+                                                                           myPreWrapperFactory));
+
+        myChild2Wrapped.put(child, result);
+        return result;
+      }
+
+      if (immediateCall) {
+        return taskCallable.call();
+      }
+
+      boolean asyncCall = method.getAnnotation(AsyncCall.class) != null;
+
+      if (asyncCall) {
+        myTaskExecutor.queueTask(new Runnable() {
+
+          @Override
+          public void run() {
+            try {
+              taskCallable.call();
+            }
+            catch (Exception e) {
+              LOG.error(e); // should never happen
+            }
+          }
+        });
+        return null;
+      }
+      else {
+        return myTaskExecutor.queueAndWaitTask(taskCallable);
+      }
+    }
+    finally {
+      boolean finalCall = method.getAnnotation(FinalCall.class) != null;
+      if (finalCall) {
+        myTaskExecutor.queueTask(new FinalTask() {
+
+          @Override
+          public void run() {
+
+          }
+        });
+      }
+    }
+  }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/FinalTask.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/FinalTask.java
new file mode 100644
index 0000000..7d3ce82
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/FinalTask.java
@@ -0,0 +1,9 @@
+package com.intellij.remoteServer.agent.impl.util;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: michael.golubev
+ */
+public interface FinalTask extends Runnable {
+
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/SequentialTaskExecutor.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/SequentialTaskExecutor.java
new file mode 100644
index 0000000..fa9c320
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/SequentialTaskExecutor.java
@@ -0,0 +1,81 @@
+package com.intellij.remoteServer.agent.impl.util;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Ref;
+import com.intellij.util.concurrency.Semaphore;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: michael.golubev
+ */
+public class SequentialTaskExecutor {
+
+  private static final Logger LOG = Logger.getInstance("#" + SequentialTaskExecutor.class.getName());
+
+  private BlockingQueue<Runnable> myTasks;
+
+  public SequentialTaskExecutor() {
+    myTasks = new LinkedBlockingQueue<Runnable>();
+
+    ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+
+      @Override
+      public void run() {
+        try {
+          while (true) {
+            Runnable task = myTasks.take();
+            task.run();
+            if (task instanceof FinalTask) {
+              break;
+            }
+          }
+        }
+        catch (InterruptedException e) {
+          LOG.debug(e);
+        }
+      }
+    });
+  }
+
+  public void queueTask(Runnable task) {
+    myTasks.offer(task);
+  }
+
+  public <V> V queueAndWaitTask(final Callable<V> task) throws Throwable {
+    final Ref<V> resultRef = new Ref<V>();
+    final Ref<Throwable> throwableRef = new Ref<Throwable>();
+
+    final Semaphore taskSemaphore = new Semaphore();
+    taskSemaphore.down();
+
+    queueTask(new Runnable() {
+
+      @Override
+      public void run() {
+        try {
+          resultRef.set(task.call());
+        }
+        catch (Throwable e) {
+          throwableRef.set(e);
+          LOG.error(e);
+        }
+        finally {
+          taskSemaphore.up();
+        }
+      }
+    });
+
+    taskSemaphore.waitFor();
+
+    if (!throwableRef.isNull()) {
+      throw throwableRef.get();
+    }
+
+    return resultRef.get();
+  }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/UrlCollector.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/UrlCollector.java
new file mode 100644
index 0000000..21e9f8c
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/UrlCollector.java
@@ -0,0 +1,64 @@
+package com.intellij.remoteServer.agent.impl.util;
+
+import com.intellij.openapi.diagnostic.Logger;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: michael.golubev
+ */
+public class UrlCollector {
+
+  private static final Logger LOG = Logger.getInstance("#" + UrlCollector.class.getName());
+
+  private List<File> myFiles;
+
+  public URL[] collect(Collection<File> libraries) {
+    List<File> files = collectFiles(libraries);
+    URL[] result = new URL[files.size()];
+    for (int i = 0; i < files.size(); i++) {
+      try {
+        result[i] = files.get(i).toURI().toURL();
+      }
+      catch (MalformedURLException e) {
+        LOG.error(e); // should never happen
+      }
+    }
+    return result;
+  }
+
+  public List<File> collectFiles(Collection<File> libraries) {
+    myFiles = new ArrayList<File>();
+    for (File library : libraries) {
+      if (library.exists()) {
+        addFile(library);
+        if (library.isDirectory()) {
+          addLibraries(library);
+        }
+      }
+    }
+    return myFiles;
+  }
+
+  private void addLibraries(File dir) {
+    for (File file : dir.listFiles()) {
+      if (file.isDirectory()) {
+        addLibraries(file);
+      }
+      else if (file.getName().endsWith(".jar")) {
+        addFile(file);
+      }
+    }
+  }
+
+  private void addFile(File file) {
+    LOG.debug("addFile: " + file.getAbsolutePath());
+    myFiles.add(file);
+  }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentInformation.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentInformation.java
deleted file mode 100644
index 97117e4..0000000
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentInformation.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.intellij.remoteServer.impl.runtime.deployment;
-
-import com.intellij.remoteServer.runtime.deployment.DeploymentStatus;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author nik
- */
-public class DeploymentInformation {
-  private final DeploymentStatus myStatus;
-  private final String myStatusText;
-
-  public DeploymentInformation(@NotNull DeploymentStatus status) {
-    myStatus = status;
-    myStatusText = status.name();
-  }
-
-  public DeploymentInformation(@NotNull DeploymentStatus status, @NotNull String statusText) {
-    myStatus = status;
-    myStatusText = statusText;
-  }
-
-  public DeploymentStatus getStatus() {
-    return myStatus;
-  }
-
-  public String getStatusText() {
-    return myStatusText;
-  }
-}
diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
index bd407c9..6e1d901 100644
--- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
@@ -74,6 +74,7 @@
 import com.intellij.openapi.vfs.*;
 import com.intellij.openapi.vfs.encoding.EncodingManager;
 import com.intellij.openapi.vfs.encoding.EncodingManagerImpl;
+import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
 import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl;
 import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
 import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl;
@@ -89,6 +90,7 @@
 import com.intellij.psi.impl.PsiManagerImpl;
 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl;
 import com.intellij.psi.templateLanguages.TemplateDataLanguageMappings;
+import com.intellij.util.Consumer;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.LocalTimeCounter;
 import com.intellij.util.containers.ContainerUtil;
@@ -109,11 +111,16 @@
 import java.io.PrintStream;
 import java.util.*;
 
+import static com.intellij.openapi.roots.ModuleRootModificationUtil.updateModel;
+
 /**
  * @author yole
  */
 public abstract class LightPlatformTestCase extends UsefulTestCase implements DataProvider {
-  public static final String PROFILE = "Configurable";
+  @NonNls public static final String PROFILE = "Configurable";
+
+  @NonNls private static final String LIGHT_PROJECT_MARK = "Light project: ";
+
   private static IdeaTestApplication ourApplication;
   protected static Project ourProject;
   private static Module ourModule;
@@ -123,9 +130,9 @@
   private static TestCase ourTestCase = null;
   public static Thread ourTestThread;
   private static LightProjectDescriptor ourProjectDescriptor;
-  @NonNls private static final String LIGHT_PROJECT_MARK = "Light project: ";
-  private final Map<String, InspectionToolWrapper> myAvailableInspectionTools = new THashMap<String, InspectionToolWrapper>();
   private static boolean ourHaveShutdownHook;
+
+  private final Map<String, InspectionToolWrapper> myAvailableInspectionTools = new THashMap<String, InspectionToolWrapper>();
   private ThreadTracker myThreadTracker;
 
   /**
@@ -202,9 +209,11 @@
 
   private static void initProject(@NotNull final LightProjectDescriptor descriptor) throws Exception {
     ourProjectDescriptor = descriptor;
+
     final File projectFile = FileUtil.createTempFile("light_temp_", ProjectFileType.DOT_DEFAULT_EXTENSION);
 
     new WriteCommandAction.Simple(null) {
+      @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod")
       @Override
       protected void run() throws Throwable {
         if (ourProject != null) {
@@ -220,6 +229,7 @@
         new Throwable(projectFile.getPath()).printStackTrace(new PrintStream(buffer));
 
         ourProject = PlatformTestCase.createProject(projectFile, LIGHT_PROJECT_MARK + buffer.toString());
+        ourPathToKeep = projectFile.getPath();
         if (!ourHaveShutdownHook) {
           ourHaveShutdownHook = true;
           registerShutdownHook();
@@ -227,14 +237,13 @@
         ourPsiManager = null;
         ourModule = createMainModule(descriptor.getModuleType());
 
-
-        //ourSourceRoot = DummyFileSystem.getInstance().createRoot("src");
-
-        final VirtualFile dummyRoot = VirtualFileManager.getInstance().findFileByUrl("temp:///");
+        VirtualFile dummyRoot = VirtualFileManager.getInstance().findFileByUrl("temp:///");
+        assert dummyRoot != null;
         dummyRoot.refresh(false, false);
 
         try {
           ourSourceRoot = dummyRoot.createChildDirectory(this, "src");
+          cleanSourceRoot();
         }
         catch (IOException e) {
           throw new RuntimeException(e);
@@ -255,39 +264,35 @@
               @Override
               public boolean visitFile(@NotNull VirtualFile file) {
                 iterator.processFile(file);
-
                 return true;
               }
             });
           }
         }, null);
 
-        final ModuleRootManager rootManager = ModuleRootManager.getInstance(ourModule);
-
-        final ModifiableRootModel rootModel = rootManager.getModifiableModel();
-
-
-        if (descriptor.getSdk() != null) {
-          rootModel.setSdk(descriptor.getSdk());
-        }
-
-        final ContentEntry contentEntry = rootModel.addContentEntry(ourSourceRoot);
-        contentEntry.addSourceFolder(ourSourceRoot, false);
-
-        descriptor.configureModule(ourModule, rootModel, contentEntry);
-
-        rootModel.commit();
-
-        final MessageBusConnection connection = ourProject.getMessageBus().connect();
-        connection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
+        updateModel(ourModule, new Consumer<ModifiableRootModel>() {
           @Override
-          public void beforeRootsChange(ModuleRootEvent event) {
-            if (!event.isCausedByFileTypesChange()) {
-              //TODO: uncomment fail("Root modification in LightIdeaTestCase is not allowed.");
+          public void consume(ModifiableRootModel model) {
+            if (descriptor.getSdk() != null) {
+              model.setSdk(descriptor.getSdk());
             }
+
+            ContentEntry contentEntry = model.addContentEntry(ourSourceRoot);
+            contentEntry.addSourceFolder(ourSourceRoot, false);
+
+            descriptor.configureModule(ourModule, model, contentEntry);
           }
         });
 
+        MessageBusConnection connection = ourProject.getMessageBus().connect();
+        connection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
+          @Override
+          public void beforeRootsChange(ModuleRootEvent event) {
+            /*if (!event.isCausedByFileTypesChange()) {
+              fail("Root modification in LightIdeaTestCase is not allowed.");
+            }*/
+          }
+        });
         connection.subscribe(ProjectTopics.MODULES, new ModuleAdapter() {
           @Override
           public void moduleAdded(Project project, Module module) {
@@ -295,12 +300,22 @@
           }
         });
 
-
-        final StartupManagerImpl startupManager = (StartupManagerImpl)StartupManager.getInstance(ourProject);
+        StartupManagerImpl startupManager = (StartupManagerImpl)StartupManager.getInstance(ourProject);
         startupManager.runStartupActivities();
         startupManager.startCacheUpdate();
       }
+
+      private void cleanSourceRoot() throws IOException {
+        TempFileSystem tempFs = (TempFileSystem)ourSourceRoot.getFileSystem();
+        for (VirtualFile child : ourSourceRoot.getChildren()) {
+          if (!tempFs.exists(child)) {
+            tempFs.createChildFile(this, ourSourceRoot, child.getName());
+          }
+          child.delete(this);
+        }
+      }
     }.execute().throwException();
+
     // project creation may make a lot of pointers, do not regard them as leak
     ((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).storePointers();
   }
@@ -339,12 +354,11 @@
 
   public static void doSetup(@NotNull LightProjectDescriptor descriptor,
                              @NotNull LocalInspectionTool[] localInspectionTools,
-                             @NotNull final Map<String, InspectionToolWrapper> availableInspectionTools)
-    throws Exception {
+                             @NotNull final Map<String, InspectionToolWrapper> availableInspectionTools) throws Exception {
     assertNull("Previous test " + ourTestCase + " hasn't called tearDown(). Probably overridden without super call.", ourTestCase);
     IdeaLogger.ourErrorsOccurred = null;
 
-    if (ourProject == null || !ourProjectDescriptor.equals(descriptor)) {
+    if (ourProject == null || ourProjectDescriptor == null || !ourProjectDescriptor.equals(descriptor)) {
       initProject(descriptor);
     }
     ((ProjectImpl)ourProject).setTemporarilyDisposed(false);
@@ -762,26 +776,32 @@
     return PsiDocumentManager.getInstance(getProject()).getDocument(file);
   }
 
+  @SuppressWarnings("NonPrivateFieldAccessedInSynchronizedContext")
   public static synchronized void closeAndDeleteProject() {
     if (ourProject != null) {
       ApplicationManager.getApplication().assertWriteAccessAllowed();
+
       ((ProjectImpl)ourProject).setTemporarilyDisposed(false);
-      final VirtualFile projFile = ((ProjectEx)ourProject).getStateStore().getProjectFile();
-      final File projectFile = projFile == null ? null : VfsUtilCore.virtualToIoFile(projFile);
+      VirtualFile projectFile = ((ProjectEx)ourProject).getStateStore().getProjectFile();
+      File ioFile = projectFile == null ? null : VfsUtilCore.virtualToIoFile(projectFile);
       if (!ourProject.isDisposed()) Disposer.dispose(ourProject);
 
-      if (projectFile != null) {
-        FileUtil.delete(projectFile);
+      if (ioFile != null) {
+        File dir = ioFile.getParentFile();
+        if (dir.getName().startsWith(UsefulTestCase.TEMP_DIR_MARKER)) {
+          FileUtil.delete(dir);
+        }
+        else {
+          FileUtil.delete(ioFile);
+        }
       }
+
+      ProjectManagerEx.getInstanceEx().closeTestProject(ourProject);
       ourProject = null;
+      ourPathToKeep = null;
     }
   }
 
-
-  static {
-    System.setProperty("jbdt.test.fixture", "com.intellij.designer.dt.IJTestFixture");
-  }
-
   private static void registerShutdownHook() {
     ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
       @Override
diff --git a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java
index 9005752..7d35679 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java
@@ -54,6 +54,8 @@
 import java.util.Collection;
 import java.util.List;
 
+import static com.intellij.openapi.roots.ModuleRootModificationUtil.updateModel;
+
 @NonNls
 public class PsiTestUtil {
   public static VirtualFile createTestProjectStructure(Project project,
@@ -400,28 +402,4 @@
       }
     });
   }
-
-  private static void updateModel(Module module, Consumer<ModifiableRootModel> task) {
-    updateModel(ModuleRootManager.getInstance(module).getModifiableModel(), task);
-  }
-
-  private static void updateModel(ModifiableRootModel model, Consumer<ModifiableRootModel> task) {
-    try {
-      task.consume(model);
-      commitModel(model);
-    }
-    catch (Throwable t) {
-      model.dispose();
-      throw new RuntimeException(t);
-    }
-  }
-
-  private static void commitModel(final ModifiableRootModel model) {
-    new WriteCommandAction.Simple(model.getProject()) {
-      @Override
-      protected void run() throws Throwable {
-        model.commit();
-      }
-    }.execute().throwException();
-  }
 }
\ No newline at end of file
diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
index 404eff3..02cd178 100644
--- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.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.
@@ -69,17 +69,18 @@
  * @author peter
  */
 public abstract class UsefulTestCase extends TestCase {
+  public static final String IDEA_MARKER_CLASS = "com.intellij.openapi.components.impl.stores.IdeaProjectStoreImpl";
+  public static final String TEMP_DIR_MARKER = "unitTest_";
+
   protected static boolean OVERWRITE_TESTDATA = false;
 
   private static final String DEFAULT_SETTINGS_EXTERNALIZED;
-  private static final Random PRNG = new SecureRandom();
+  private static final Random RNG = new SecureRandom();
   private static final String ORIGINAL_TEMP_DIR = FileUtil.getTempDirectory();
-  public static final String IDEA_MARKER_CLASS = "com.intellij.openapi.components.impl.stores.IdeaProjectStoreImpl";
 
   protected final Disposable myTestRootDisposable = new Disposable() {
     @Override
-    public void dispose() {
-    }
+    public void dispose() { }
 
     @Override
     public String toString() {
@@ -87,6 +88,9 @@
       return UsefulTestCase.this.getClass() + (StringUtil.isEmpty(testName) ? "" : ".test" + testName);
     }
   };
+
+  protected static String ourPathToKeep = null;
+
   private CodeStyleSettings myOldCodeStyleSettings;
   private String myTempDir;
 
@@ -119,9 +123,10 @@
       String testName = getTestName(true);
       if (StringUtil.isEmptyOrSpaces(testName)) testName = "";
       testName = new File(testName).getName(); // in case the test name contains file separators
-      myTempDir = ORIGINAL_TEMP_DIR + "/unitTest_" + testName + "_"+ PRNG.nextInt(1000);
+      myTempDir = FileUtil.toSystemDependentName(ORIGINAL_TEMP_DIR + "/" + TEMP_DIR_MARKER + testName + "_"+ RNG.nextInt(1000));
       FileUtil.resetCanonicalTempPathCache(myTempDir);
     }
+    //noinspection AssignmentToStaticFieldFromInstanceMethod
     DocumentImpl.CHECK_DOCUMENT_CONSISTENCY = !isPerformanceTest();
   }
 
@@ -134,7 +139,19 @@
     finally {
       if (shouldContainTempFiles()) {
         FileUtil.resetCanonicalTempPathCache(ORIGINAL_TEMP_DIR);
-        FileUtil.delete(new File(myTempDir));
+        if (ourPathToKeep != null && FileUtil.isAncestor(myTempDir, ourPathToKeep, false)) {
+          File[] files = new File(myTempDir).listFiles();
+          if (files != null) {
+            for (File file : files) {
+              if (!FileUtil.pathsEqual(file.getPath(), ourPathToKeep)) {
+                FileUtil.delete(file);
+              }
+            }
+          }
+        }
+        else {
+          FileUtil.delete(new File(myTempDir));
+        }
       }
     }
 
diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java
index 84848f0..5259fa0 100644
--- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java
+++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.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.
@@ -39,6 +39,7 @@
 /**
  * @author mike
  */
+@SuppressWarnings("TestOnlyProblems")
 public class LightIdeaTestFixtureImpl extends BaseFixture implements LightIdeaTestFixture {
   private final LightProjectDescriptor myProjectDescriptor;
   private CodeStyleSettings myOldCodeStyleSettings;
@@ -73,10 +74,9 @@
     super.tearDown();
     InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project);
     PersistentFS.getInstance().clearIdCache();
-      ((DirectoryIndexImpl)DirectoryIndex.getInstance(project)).assertAncestorConsistent();
+    ((DirectoryIndexImpl)DirectoryIndex.getInstance(project)).assertAncestorConsistent();
   }
 
-
   @Override
   public Project getProject() {
     return LightPlatformTestCase.getProject();
diff --git a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java
index cf7b95d..dc9068e 100644
--- a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java
+++ b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java
@@ -298,13 +298,9 @@
     return attrs;
   }
 
-  private void appendPrefix(List<TextChunk> result, int lineNumber, int columnNumber) {
-    StringBuilder buffer = new StringBuilder("(");
-    buffer.append(lineNumber + 1);
-    buffer.append(": ");
-    buffer.append(columnNumber + 1);
-    buffer.append(") ");
-    TextChunk prefixChunk = new TextChunk(myColorsScheme.getAttributes(UsageTreeColors.USAGE_LOCATION), buffer.toString());
+  private void appendPrefix(@NotNull List<TextChunk> result, int lineNumber, int columnNumber) {
+    String prefix = "(" + (lineNumber + 1) + ": " + (columnNumber + 1) + ") ";
+    TextChunk prefixChunk = new TextChunk(myColorsScheme.getAttributes(UsageTreeColors.USAGE_LOCATION), prefix);
     result.add(prefixChunk);
   }
 }
diff --git a/platform/util-rt/src/com/intellij/openapi/util/UnorderedPair.java b/platform/util-rt/src/com/intellij/openapi/util/UnorderedPair.java
new file mode 100644
index 0000000..83a4859
--- /dev/null
+++ b/platform/util-rt/src/com/intellij/openapi/util/UnorderedPair.java
@@ -0,0 +1,49 @@
+/*
+ * 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.openapi.util;
+
+public class UnorderedPair<T> {
+  public final T first;
+  public final T second;
+
+  public UnorderedPair(T first, T second) {
+    this.first = first;
+    this.second = second;
+  }
+
+  @Override
+  public int hashCode() {
+    int hc1 = first == null ? 0 : first.hashCode();
+    int hc2 = second == null ? 0 : second.hashCode();
+    return hc1 * hc1 + hc2 * hc2;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null) return false;
+    if (obj.getClass() != getClass()) return false;
+
+    final UnorderedPair other = (UnorderedPair)obj;
+    if (Comparing.equal(other.first, first) && Comparing.equal(other.second, second)) return true;
+    if (Comparing.equal(other.first, second) && Comparing.equal(other.second, first)) return true;
+    return false;
+  }
+
+  @Override
+  public String toString() {
+    return "<" + first + ", " + second + '>';
+  }
+}
diff --git a/platform/util/src/com/intellij/openapi/util/JDOMUtil.java b/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
index e143ef8..665776f 100644
--- a/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
@@ -17,6 +17,7 @@
 
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.CharsetToolkit;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.containers.StringInterner;
 import com.intellij.util.io.URLUtil;
@@ -25,6 +26,7 @@
 import com.intellij.util.text.CharSequenceReader;
 import com.intellij.util.text.StringFactory;
 import org.jdom.*;
+import org.jdom.filter.ElementFilter;
 import org.jdom.filter.Filter;
 import org.jdom.input.DOMBuilder;
 import org.jdom.input.SAXBuilder;
@@ -56,12 +58,11 @@
 
   @NotNull
   public static List<Element> getChildren(@Nullable Element parent) {
-    if (parent != null) {
-      @SuppressWarnings({"UnnecessaryLocalVariable", "unchecked"}) final List<Element> children = parent.getChildren();
-      return children;
+    if (parent == null) {
+      return Collections.emptyList();
     }
     else {
-      return Collections.emptyList();
+      return parent.getChildren();
     }
   }
 
@@ -82,8 +83,6 @@
     return LoggerHolder.ourLogger;
   }
 
-  private static final String ENCODING = "UTF-8";
-
   public static boolean areElementsEqual(Element e1, Element e2) {
     if (e1 == null && e2 == null) return true;
     if (e1 == null || e2 == null) return false;
@@ -106,16 +105,12 @@
   private static int addToHash(int i, @NotNull final Element element) {
     i = addToHash(i, element.getName());
 
-    final List<Attribute> list = element.getAttributes();
-    //noinspection ForLoopReplaceableByForEach
-    for (int j = 0; j < list.size(); j++) {
-      i = addToHash(i, list.get(j));
+    for (Attribute aList : element.getAttributes()) {
+      i = addToHash(i, aList);
     }
 
     List<Content> content = element.getContent();
-    //noinspection ForLoopReplaceableByForEach
-    for (int j = 0; j < content.size(); j++) {
-      Content child = content.get(j);
+    for (Content child : content) {
       if (child instanceof Element) {
         i = addToHash(i, (Element)child);
       }
@@ -137,7 +132,6 @@
     return i * 31 + s.hashCode();
   }
 
-  @SuppressWarnings({"unchecked"})
   @NotNull
   public static Object[] getChildNodesWithAttrs(@NotNull Element e) {
     ArrayList<Object> result = new ArrayList<Object>();
@@ -146,18 +140,16 @@
     return ArrayUtil.toObjectArray(result);
   }
 
-  @SuppressWarnings({"unchecked"})
   @NotNull
-  public static Content[] getContent(@NotNull final Element m) {
-    final List list = m.getContent();
-    return (Content[])list.toArray(new Content[list.size()]);
+  public static Content[] getContent(@NotNull Element m) {
+    List<Content> list = m.getContent();
+    return list.toArray(new Content[list.size()]);
   }
 
-  @SuppressWarnings({"unchecked"})
   @NotNull
-  public static Element[] getElements(@NotNull final Element m) {
-    final List list = m.getChildren();
-    return (Element[])list.toArray(new Element[list.size()]);
+  public static Element[] getElements(@NotNull Element m) {
+    List<Element> list = m.getChildren();
+    return list.toArray(new Element[list.size()]);
   }
 
   @NotNull
@@ -186,15 +178,12 @@
   public static void internElement(@NotNull Element element, @NotNull StringInterner interner) {
     element.setName(intern(interner, element.getName()));
 
-    final List attributes = element.getAttributes();
-    for (Object o : attributes) {
-      Attribute attr = (Attribute)o;
+    for (Attribute attr : element.getAttributes()) {
       attr.setName(intern(interner, attr.getName()));
       attr.setValue(intern(interner, attr.getValue()));
     }
 
-    final List content = element.getContent();
-    for (Object o : content) {
+    for (Content o : element.getContent()) {
       if (o instanceof Element) {
         Element e = (Element)o;
         internElement(e, interner);
@@ -226,7 +215,6 @@
     StringBuilder result = new StringBuilder();
 
     while(true) {
-      //noinspection EmptyCatchBlock
       try {
         int each = reader.read();
         if (each == -1) break;
@@ -237,7 +225,7 @@
           result.append("0x").append(StringUtil.toUpperCase(Long.toHexString(each)));
         }
       }
-      catch (IOException e) {
+      catch (IOException ignored) {
       }
     }
 
@@ -248,11 +236,7 @@
   private static class EmptyTextFilter implements Filter {
     @Override
     public boolean matches(Object obj) {
-      if (obj instanceof Text) {
-        final Text t = (Text)obj;
-        return !CharArrayUtil.containsOnlyWhiteSpaces(t.getText());
-      }
-      return true;
+      return !(obj instanceof Text) || !CharArrayUtil.containsOnlyWhiteSpaces(((Text)obj).getText());
     }
   }
 
@@ -375,7 +359,7 @@
 
   @NotNull
   public static Document loadDocument(@NotNull InputStream stream) throws JDOMException, IOException {
-    InputStreamReader reader = new InputStreamReader(stream, ENCODING);
+    InputStreamReader reader = new InputStreamReader(stream, CharsetToolkit.UTF8_CHARSET);
     try {
       return getSaxBuilder().build(reader);
     }
@@ -424,7 +408,7 @@
   }
 
   public static void writeDocument(@NotNull Document document, @NotNull OutputStream stream, String lineSeparator) throws IOException {
-    writeDocument(document, new OutputStreamWriter(stream, ENCODING), lineSeparator);
+    writeDocument(document, new OutputStreamWriter(stream, CharsetToolkit.UTF8_CHARSET), lineSeparator);
   }
 
 
@@ -433,7 +417,7 @@
     CharArrayWriter writer = new CharArrayWriter();
     writeDocument(document, writer, lineSeparator);
 
-    return StringFactory.createShared(writer.toCharArray()).getBytes(ENCODING);
+    return StringFactory.createShared(writer.toCharArray()).getBytes(CharsetToolkit.UTF8_CHARSET);
   }
 
   @NotNull
@@ -529,7 +513,7 @@
     Format format = Format.getCompactFormat().
       setIndent("  ").
       setTextMode(Format.TextMode.TRIM).
-      setEncoding(ENCODING).
+      setEncoding(CharsetToolkit.UTF8).
       setOmitEncoding(false).
       setOmitDeclaration(false).
       setLineSeparator(lineSeparator);
@@ -754,4 +738,35 @@
       throw new IllegalArgumentException("Wrong node: " + node);
     }
   }
+
+  @Nullable
+  public static Element cloneElement(@NotNull Element element, @NotNull ElementFilter elementFilter) {
+    Element result = new Element(element.getName(), element.getNamespace());
+    List<Attribute> attributes = element.getAttributes();
+    if (!attributes.isEmpty()) {
+      ArrayList<Attribute> list = new ArrayList<Attribute>(attributes.size());
+      for (Attribute attribute : attributes) {
+        list.add(attribute.clone());
+      }
+      result.setAttributes(list);
+    }
+
+    for (Namespace namespace : element.getAdditionalNamespaces()) {
+      result.addNamespaceDeclaration(namespace);
+    }
+
+    boolean hasContent = false;
+    for (Content content : element.getContent()) {
+      if (content instanceof Element) {
+        if (elementFilter.matches(content)) {
+          hasContent = true;
+        }
+        else {
+          continue;
+        }
+      }
+      result.addContent(content.clone());
+    }
+    return hasContent ? result : null;
+  }
 }
diff --git a/platform/util/src/com/intellij/openapi/util/Key.java b/platform/util/src/com/intellij/openapi/util/Key.java
index 2c3be89..7dc881b 100644
--- a/platform/util/src/com/intellij/openapi/util/Key.java
+++ b/platform/util/src/com/intellij/openapi/util/Key.java
@@ -59,12 +59,10 @@
     return new Key<T>(name);
   }
 
-  @Nullable
   public T get(@Nullable UserDataHolder holder) {
     return holder == null ? null : holder.getUserData(this);
   }
 
-  @Nullable
   public T get(@Nullable Map<Key, ?> holder) {
     //noinspection unchecked
     return holder == null ? null : (T)holder.get(this);
diff --git a/platform/util/src/com/intellij/openapi/util/RoamingTypePerPlatform.java b/platform/util/src/com/intellij/openapi/util/RoamingTypePerPlatform.java
deleted file mode 100644
index 153aaa0..0000000
--- a/platform/util/src/com/intellij/openapi/util/RoamingTypePerPlatform.java
+++ /dev/null
@@ -1,19 +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.openapi.util;
-
-public interface RoamingTypePerPlatform {
-}
diff --git a/platform/util/src/com/intellij/openapi/util/TextRange.java b/platform/util/src/com/intellij/openapi/util/TextRange.java
index 854f00d..797bc23 100644
--- a/platform/util/src/com/intellij/openapi/util/TextRange.java
+++ b/platform/util/src/com/intellij/openapi/util/TextRange.java
@@ -134,11 +134,17 @@
     return segment1.getStartOffset() == segment2.getStartOffset()
            && segment1.getEndOffset() == segment2.getEndOffset();
   }
+
   @NotNull
   public String replace(@NotNull String original, @NotNull String replacement) {
-    String beginning = original.substring(0, getStartOffset());
-    String ending = original.substring(getEndOffset(), original.length());
-    return beginning + replacement + ending;
+    try {
+      String beginning = original.substring(0, getStartOffset());
+      String ending = original.substring(getEndOffset(), original.length());
+      return beginning + replacement + ending;
+    }
+    catch (StringIndexOutOfBoundsException e) {
+      throw new StringIndexOutOfBoundsException("Can't replace " + this + " range from '" + original + "' with '" + replacement + "'");
+    }
   }
 
   public boolean intersects(@NotNull TextRange textRange) {
diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
index 241244e..b93b988 100644
--- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
@@ -1620,8 +1620,14 @@
   public static int indexOfAny(@NotNull final String s, @NotNull final String chars) {
     return indexOfAny(s, chars, 0, s.length());
   }
+  public static int indexOfAny(@NotNull final CharSequence s, @NotNull final String chars) {
+    return indexOfAny(s, chars, 0, s.length());
+  }
 
   public static int indexOfAny(@NotNull final String s, @NotNull final String chars, final int start, final int end) {
+    return indexOfAny((CharSequence)s, chars, start, end);
+  }
+  public static int indexOfAny(@NotNull final CharSequence s, @NotNull final String chars, final int start, final int end) {
     for (int i = start; i < end; i++) {
       if (containsChar(chars, s.charAt(i))) return i;
     }
diff --git a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java
index c8871be..c96e79b 100644
--- a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java
+++ b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java
@@ -142,11 +142,12 @@
     if (iterable.isEmpty()) return 0;
 
     final TextRange first = iterable.getHead();
+    boolean startMatch = first.getStartOffset() == 0;
 
     int matchingCase = 0;
     int p = -1;
 
-    int integral = 0; // sum of matching-character-count * hump-index over all matched humps; favors longer fragments matching earlier words
+    int integral = 0; // -sum of matching-char-count * hump-index over all matched humps; favors longer fragments matching earlier words
     int humpIndex = 1;
     int nextHumpStart = 0;
     for (TextRange range : iterable) {
@@ -161,7 +162,7 @@
             humpIndex++;
           }
         }
-        integral += humpIndex;
+        integral -= humpIndex;
 
         char c = name.charAt(i);
         p = StringUtil.indexOf(myPattern, c, p + 1, myPattern.length, false);
@@ -169,9 +170,10 @@
           break;
         }
 
-        // favor uppercase letters matching hump start
         if (c == myPattern[p]) {
-          matchingCase += isUpperCase[p] ? 50 : isHumpStart ? 1 : 0;
+          if (isUpperCase[p]) matchingCase += 50; // strongly prefer user's uppercase matching uppercase: they made an effort to press Shift
+          else if (i == 0 && startMatch) matchingCase += 15; // the very first letter case distinguishes classes in Java etc
+          else if (isHumpStart) matchingCase += 1; // if a lowercase matches lowercase hump start, that also means something 
         } else if (isHumpStart) {
           // disfavor hump starts where pattern letter case doesn't match name case
           matchingCase -= 20;
@@ -183,9 +185,12 @@
     boolean afterSeparator = StringUtil.indexOfAny(name, HARD_SEPARATORS, 0, startIndex) >= 0;
     boolean wordStart = startIndex == 0 || isWordStart(name, startIndex) && !isWordStart(name, startIndex - 1);
     boolean finalMatch = iterable.get(iterable.size() - 1).getEndOffset() == name.length();
-    boolean startMatch = iterable.get(0).getStartOffset() == 0;
 
-    return (wordStart ? 1000 : 0) - integral * 10 + matchingCase + (afterSeparator ? 0 : 2) + (startMatch ? 1 : 0) + (finalMatch ? 1 : 0);
+    return (wordStart ? 1000 : 0) + 
+           integral * 10 + 
+           matchingCase * (startMatch ? 10 : 1) + // in start matches, case is more important; in middle matches - fragment length (integral)
+           (afterSeparator ? 0 : 2) + 
+           (finalMatch ? 1 : 0);
   }
 
   public boolean isStartMatch(@NotNull String name) {
diff --git a/platform/util/src/com/intellij/util/EnvironmentUtil.java b/platform/util/src/com/intellij/util/EnvironmentUtil.java
index 11ff535..333920b 100644
--- a/platform/util/src/com/intellij/util/EnvironmentUtil.java
+++ b/platform/util/src/com/intellij/util/EnvironmentUtil.java
@@ -15,6 +15,8 @@
  */
 package com.intellij.util;
 
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
 import com.intellij.execution.process.UnixProcessManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.AtomicNotNullLazyValue;
@@ -22,6 +24,7 @@
 import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.concurrency.FixedFuture;
 import com.intellij.util.text.CaseInsensitiveStringHashingStrategy;
 import gnu.trove.THashMap;
@@ -128,52 +131,63 @@
 
   @SuppressWarnings("SpellCheckingInspection")
   private static Map<String, String> getShellEnv() {
+    File envFile = null;
     try {
       String shell = System.getenv("SHELL");
       if (shell == null || !new File(shell).canExecute()) {
         throw new Exception("shell:" + shell);
       }
 
-      String[] command = {shell, "-l", "-c", "/usr/bin/printenv"};
+      envFile = FileUtil.createTempFile("intellij-shell-env", null, false);
+      String[] command = {shell, "-l", "-c", "/usr/bin/printenv > '" + envFile.getAbsolutePath() + "'"};
+      LOG.info("loading shell env: " + StringUtil.join(command, " "));
       Process process = Runtime.getRuntime().exec(command);
       ProcessKiller processKiller = new ProcessKiller(process);
       processKiller.killAfter(SHELL_ENV_READING_TIMEOUT);
-      List<String> lines = FileUtil.loadLines(process.getInputStream());
-      processKiller.stopWaiting();
       int rv = process.waitFor();
+      processKiller.stopWaiting();
+      List<String> lines = Files.readLines(envFile, Charsets.UTF_8);
       if (rv != 0 || lines.isEmpty()) {
         throw new Exception("rv:" + rv + " lines:" + lines.size());
       }
-
-      Set<String> toIgnore = new HashSet<String>(Arrays.asList("_", "PWD", "SHLVL"));
-      Map<String, String> env = System.getenv();
-      Map<String, String> newEnv = new HashMap<String, String>();
-      for (String line : lines) {
-        int pos = line.indexOf('=');
-        if (pos <= 0) {
-          LOG.warn("malformed:" + line);
-          continue;
-        }
-        String name = line.substring(0, pos);
-        if (!toIgnore.contains(name)) {
-          newEnv.put(name, line.substring(pos + 1));
-        }
-        else if (env.containsKey(name)) {
-          newEnv.put(name, env.get(name));
-        }
-      }
-      if (newEnv.size() < lines.size() - toIgnore.size()) {
-        // some lines weren't parsed - we're better to fall back to original environment than use possibly incomplete one
-        throw new Exception("env:" + newEnv.size() + " lines:" + lines.size());
-      }
-
-      LOG.info("shell environment loaded (" + newEnv.size() + " vars)");
-      return Collections.unmodifiableMap(newEnv);
+      return parseEnv(lines);
     }
     catch (Throwable t) {
       LOG.warn("can't get shell environment", t);
       return System.getenv();
     }
+    finally {
+      if (envFile != null) {
+        FileUtil.delete(envFile);
+      }
+    }
+  }
+
+  private static Map<String, String> parseEnv(List<String> lines) throws Exception {
+    Set<String> toIgnore = new HashSet<String>(Arrays.asList("_", "PWD", "SHLVL"));
+    Map<String, String> env = System.getenv();
+    Map<String, String> newEnv = new HashMap<String, String>();
+    for (String line : lines) {
+      int pos = line.indexOf('=');
+      if (pos <= 0) {
+        LOG.warn("malformed:" + line);
+        continue;
+      }
+      String name = line.substring(0, pos);
+      if (!toIgnore.contains(name)) {
+        newEnv.put(name, line.substring(pos + 1));
+      }
+      else if (env.containsKey(name)) {
+        newEnv.put(name, env.get(name));
+      }
+    }
+    if (newEnv.size() < lines.size() - toIgnore.size()) {
+      // some lines weren't parsed - we're better to fall back to original environment than use possibly incomplete one
+      throw new Exception("env:" + newEnv.size() + " lines:" + lines.size());
+    }
+
+    LOG.info("shell environment loaded (" + newEnv.size() + " vars)");
+    return Collections.unmodifiableMap(newEnv);
   }
 
   private static class ProcessKiller {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
index 16013cf..ca8d5bb 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
@@ -67,7 +67,7 @@
 /**
  * @author max
  */
-public class ChangeListManagerImpl extends ChangeListManagerEx implements ProjectComponent, ChangeListOwner, JDOMExternalizable {
+public class ChangeListManagerImpl extends ChangeListManagerEx implements ProjectComponent, ChangeListOwner, JDOMExternalizable, RoamingTypeDisabled {
   public static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.ChangeListManagerImpl");
 
   private final Project myProject;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeManagerImpl.java
index 70127c3..6e44a78 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeManagerImpl.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeManagerImpl.java
@@ -105,7 +105,7 @@
     if ((! myProject.isOpen()) || myProject.isDisposed() || myVcsManager.getAllActiveVcss().length == 0) return;
 
     if (LOG.isDebugEnabled()) {
-      LOG.debug("everything dirty: " + ReflectionUtil.findCallerClass(1));
+      LOG.debug("everything dirty: " + ReflectionUtil.findCallerClass(2));
     }
 
     final LifeDrop lifeDrop = myLife.doIfAlive(new Runnable() {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesPanel.java
index 52b3c6b..3c606ee 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesPanel.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesPanel.java
@@ -102,7 +102,7 @@
 
     if (auxiliary != null) {
       myShouldBeCalledOnDispose.add(auxiliary.getCalledOnViewDispose());
-      myBrowser.setTableContextMenu(group, (auxiliary.getPopupActions() == null) ? Collections.<AnAction>emptyList() : auxiliary.getPopupActions());
+      myBrowser.setTableContextMenu(group, auxiliary.getPopupActions());
     } else {
       myBrowser.setTableContextMenu(group, Collections.<AnAction>emptyList());
     }
@@ -252,9 +252,9 @@
       for(String word: filterWords) {
         final String comment = changeList.getComment();
         final String committer = changeList.getCommitterName();
-        if ((comment != null && comment.toLowerCase().indexOf(word) >= 0) ||
-            (committer != null && committer.toLowerCase().indexOf(word) >= 0) ||
-            Long.toString(changeList.getNumber()).indexOf(word) >= 0) {
+        if ((comment != null && comment.toLowerCase().contains(word)) ||
+            (committer != null && committer.toLowerCase().contains(word)) ||
+            Long.toString(changeList.getNumber()).contains(word)) {
           return true;
         }
       }
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/update/RestoreUpdateTree.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/update/RestoreUpdateTree.java
index 24c9a29..8ce0067 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/update/RestoreUpdateTree.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/update/RestoreUpdateTree.java
@@ -23,6 +23,7 @@
 import com.intellij.openapi.startup.StartupManager;
 import com.intellij.openapi.util.InvalidDataException;
 import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.RoamingTypeDisabled;
 import com.intellij.openapi.util.WriteExternalException;
 import com.intellij.openapi.vcs.VcsBundle;
 import com.intellij.openapi.vcs.changes.committed.CommittedChangesCache;
@@ -31,7 +32,7 @@
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 
-public class RestoreUpdateTree implements ProjectComponent, JDOMExternalizable {
+public class RestoreUpdateTree implements ProjectComponent, JDOMExternalizable, RoamingTypeDisabled {
   private final Project myProject;
 
   private UpdateInfo myUpdateInfo;
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
index b2485bf..48abf0f 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
@@ -20,6 +20,7 @@
 import com.intellij.execution.ui.ConsoleView;
 import com.intellij.execution.ui.RunContentDescriptor;
 import com.intellij.execution.ui.RunnerLayoutUi;
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.MessageType;
 import com.intellij.xdebugger.breakpoints.XBreakpoint;
@@ -131,6 +132,8 @@
   boolean areBreakpointsMuted();
 
 
+  void addSessionListener(@NotNull XDebugSessionListener listener, @NotNull Disposable parentDisposable);
+
   void addSessionListener(@NotNull XDebugSessionListener listener);
 
   void removeSessionListener(@NotNull XDebugSessionListener listener);
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerUtil.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerUtil.java
index 1a52c2be..80b3e76 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerUtil.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerUtil.java
@@ -31,6 +31,7 @@
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Comparator;
+import java.util.List;
 
 /**
  * @author nik
@@ -50,6 +51,7 @@
                                             @NotNull VirtualFile file,
                                             int line,
                                             boolean temporary);
+
   public abstract boolean canPutBreakpointAt(@NotNull Project project, @NotNull VirtualFile file, int line);
 
   public <P extends XBreakpointProperties> void toggleLineBreakpoint(@NotNull Project project, @NotNull XLineBreakpointType<P> type,
@@ -87,6 +89,8 @@
 
   public abstract <B extends XLineBreakpoint<?>> XBreakpointGroupingRule<B, ?> getGroupingByFileRule();
 
+  public abstract <B extends XLineBreakpoint<?>> List<XBreakpointGroupingRule<B, ?>> getGroupingByFileRuleAsList();
+
   public abstract <B extends XBreakpoint<?>> Comparator<B> getDefaultBreakpointComparator(XBreakpointType<B, ?> type);
 
   public abstract <P extends XBreakpointProperties> Comparator<XLineBreakpoint<P>> getDefaultLineBreakpointComparator();
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpoint.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpoint.java
index c02f3a3..bc6dca2 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpoint.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpoint.java
@@ -16,9 +16,9 @@
 
 package com.intellij.xdebugger.breakpoints;
 
-import com.intellij.xdebugger.XSourcePosition;
-import com.intellij.pom.Navigatable;
 import com.intellij.openapi.util.UserDataHolder;
+import com.intellij.pom.Navigatable;
+import com.intellij.xdebugger.XSourcePosition;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointAdapter.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointAdapter.java
index 9702b5f..ecdb658 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointAdapter.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointAdapter.java
@@ -21,13 +21,16 @@
 /**
  * @author nik
  */
-public abstract class XBreakpointAdapter<B extends XBreakpoint<?>> implements XBreakpointListener<B>{
+public abstract class XBreakpointAdapter<B extends XBreakpoint<?>> implements XBreakpointListener<B> {
+  @Override
   public void breakpointAdded(@NotNull final B breakpoint) {
   }
 
+  @Override
   public void breakpointRemoved(@NotNull final B breakpoint) {
   }
 
+  @Override
   public void breakpointChanged(@NotNull final B breakpoint) {
   }
 }
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointListener.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointListener.java
index 9669402..83aa189 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointListener.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointListener.java
@@ -24,7 +24,6 @@
  * @author nik
  */
 public interface XBreakpointListener<B extends XBreakpoint<?>> extends EventListener {
-
   void breakpointAdded(@NotNull B breakpoint);
 
   void breakpointRemoved(@NotNull B breakpoint);
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java
index 574b6a6..978e840 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java
@@ -50,25 +50,14 @@
   public static final ExtensionPointName<XBreakpointType> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.xdebugger.breakpointType");
   private final @NonNls @NotNull String myId;
   private final @Nls @NotNull String myTitle;
-  private final boolean mySuspendThreadSupported;
 
   /**
    * @param id an unique id of breakpoint type
    * @param title title of tab in the breakpoints dialog
    */
   protected XBreakpointType(@NonNls @NotNull final String id, @Nls @NotNull final String title) {
-    this(id, title, false);
-  }
-
-  /**
-   * @param id an unique id of breakpoint type
-   * @param title title of tab in the breakpoints dialog
-   * @param suspendThreadSupported <code>true</code> if suspending only one thread is supported for this type of breakpoints
-   */
-  protected XBreakpointType(@NonNls @NotNull final String id, @Nls @NotNull final String title, boolean suspendThreadSupported) {
     myId = id;
     myTitle = title;
-    mySuspendThreadSupported = suspendThreadSupported;
   }
 
   @Nullable
@@ -76,8 +65,11 @@
     return null;
   }
 
-  public final boolean isSuspendThreadSupported() {
-    return mySuspendThreadSupported;
+  /**
+   * @return {@code true} if suspending only one thread is supported
+   */
+  public boolean isSuspendThreadSupported() {
+    return false;
   }
 
   @NotNull
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java
index 48fdb82..a6b07b3 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java
@@ -50,17 +50,10 @@
   }
 
   /**
-   * @deprecated implement {@link #canPutAt(com.intellij.openapi.vfs.VirtualFile, int, com.intellij.openapi.project.Project)} instead
-   */
-  public boolean canPutAt(@NotNull VirtualFile file, int line) {
-    return false;
-  }
-
-  /**
    * Return <code>true<code> if breakpoint can be put on <code>line</code> in <code>file</code>
    */
   public boolean canPutAt(@NotNull VirtualFile file, int line, @NotNull Project project) {
-    return canPutAt(file, line);
+    return false;
   }
 
   /**
@@ -70,6 +63,7 @@
   @Nullable
   public abstract P createBreakpointProperties(@NotNull VirtualFile file, int line);
 
+  @Override
   public String getDisplayText(final XLineBreakpoint<P> breakpoint) {
     return fileLineDisplayText(breakpoint.getPresentableFilePath(), breakpoint.getLine());
   }
@@ -78,11 +72,6 @@
     return XDebuggerBundle.message("xbreakpoint.default.display.text", line + 1, path);
   }
 
-  //@NotNull
-  //public Comparator<XLineBreakpoint<P>> getBreakpointComparator() {
-  //  return XDebuggerUtil.getInstance().getDefaultLineBreakpointComparator();
-  //}
-
   /**
    * Source position for line breakpoint is determined by its file and line
    */
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointTypeBase.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointTypeBase.java
new file mode 100644
index 0000000..adbc7b2
--- /dev/null
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointTypeBase.java
@@ -0,0 +1,31 @@
+package com.intellij.xdebugger.breakpoints;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class XLineBreakpointTypeBase extends XLineBreakpointType<XBreakpointProperties> {
+  private final XDebuggerEditorsProvider myEditorsProvider;
+
+  protected XLineBreakpointTypeBase(@NonNls @NotNull final String id, @Nls @NotNull final String title, @Nullable XDebuggerEditorsProvider editorsProvider) {
+    super(id, title);
+
+    myEditorsProvider = editorsProvider;
+  }
+
+  @Nullable
+  @Override
+  public XDebuggerEditorsProvider getEditorsProvider(@NotNull XLineBreakpoint<XBreakpointProperties> breakpoint, @NotNull Project project) {
+    return myEditorsProvider;
+  }
+
+  @Override
+  @Nullable
+  public XBreakpointProperties createBreakpointProperties(@NotNull final VirtualFile file, final int line) {
+    return null;
+  }
+}
\ No newline at end of file
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProviderBase.java b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProviderBase.java
new file mode 100644
index 0000000..bedb6213
--- /dev/null
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProviderBase.java
@@ -0,0 +1,66 @@
+package com.intellij.xdebugger.evaluation;
+
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.xdebugger.XSourcePosition;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class XDebuggerEditorsProviderBase extends XDebuggerEditorsProvider {
+  @NotNull
+  @Override
+  public final Document createDocument(@NotNull Project project, @NotNull String text, @Nullable XSourcePosition sourcePosition, @NotNull EvaluationMode mode) {
+    PsiElement context = null;
+    if (sourcePosition != null) {
+      context = getContextElement(sourcePosition.getFile(), sourcePosition.getOffset(), project);
+    }
+
+    PsiFile codeFragment = createExpressionCodeFragment(project, text, context, true);
+    Document document = PsiDocumentManager.getInstance(project).getDocument(codeFragment);
+    assert document != null;
+    return document;
+  }
+
+  protected abstract PsiFile createExpressionCodeFragment(@NotNull Project project, @NotNull String text, @Nullable PsiElement context, boolean isPhysical);
+
+  protected PsiElement getContextElement(@NotNull VirtualFile virtualFile, int offset, @NotNull Project project) {
+    return doGetContextElement(virtualFile, offset, project);
+  }
+
+  public static PsiElement doGetContextElement(@NotNull VirtualFile virtualFile, int offset, @NotNull Project project) {
+    Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
+    PsiFile file = PsiManager.getInstance(project).findFile(virtualFile);
+    if (file == null || document == null) {
+      return null;
+    }
+
+    if (offset < 0) {
+      offset = 0;
+    }
+    if (offset > document.getTextLength()) {
+      offset = document.getTextLength();
+    }
+    int startOffset = offset;
+
+    int lineEndOffset = document.getLineEndOffset(document.getLineNumber(offset));
+    PsiElement result = null;
+    do {
+      PsiElement element = file.findElementAt(offset);
+      if (!(element instanceof PsiWhiteSpace) && !(element instanceof PsiComment)) {
+        result = element;
+        break;
+      }
+
+      offset = element.getTextRange().getEndOffset() + 1;
+    }
+    while (offset < lineEndOffset);
+
+    if (result == null) {
+      result = file.findElementAt(startOffset);
+    }
+    return result;
+  }
+}
\ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
index 659f49d..ffbd3d4 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
@@ -32,6 +32,7 @@
 import com.intellij.notification.Notification;
 import com.intellij.notification.NotificationGroup;
 import com.intellij.notification.NotificationListener;
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.ReadAction;
@@ -387,6 +388,11 @@
   }
 
   @Override
+  public void addSessionListener(@NotNull XDebugSessionListener listener, @NotNull Disposable parentDisposable) {
+    myDispatcher.addListener(listener, parentDisposable);
+  }
+
+  @Override
   public void addSessionListener(@NotNull final XDebugSessionListener listener) {
     myDispatcher.addListener(listener);
   }
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
index 3e1f8c7..026380c 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
@@ -56,6 +56,7 @@
   private XLineBreakpointType<?>[] myLineBreakpointTypes;
   private Map<Class<? extends XBreakpointType>, XBreakpointType<?,?>> myBreakpointTypeByClass;
 
+  @Override
   public XLineBreakpointType<?>[] getLineBreakpointTypes() {
     if (myLineBreakpointTypes == null) {
       XBreakpointType[] types = XBreakpointUtil.getBreakpointTypes();
@@ -70,6 +71,7 @@
     return myLineBreakpointTypes;
   }
 
+  @Override
   public void toggleLineBreakpoint(@NotNull final Project project, @NotNull final VirtualFile file, final int line, boolean temporary) {
     for (XLineBreakpointType<?> type : getLineBreakpointTypes()) {
       if (type.canPutAt(file, line, project)) {
@@ -89,12 +91,14 @@
     return false;
   }
 
+  @Override
   public <P extends XBreakpointProperties> void toggleLineBreakpoint(@NotNull final Project project,
                                                                      @NotNull final XLineBreakpointType<P> type,
                                                                      @NotNull final VirtualFile file,
                                                                      final int line,
                                                                      final boolean temporary) {
     new WriteAction() {
+      @Override
       protected void run(final Result result) {
         XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
         XLineBreakpoint<P> breakpoint = breakpointManager.findBreakpointAtLine(type, file, line);
@@ -109,14 +113,17 @@
     }.execute();
   }
 
+  @Override
   public void removeBreakpoint(final Project project, final XBreakpoint<?> breakpoint) {
     new WriteAction() {
+      @Override
       protected void run(final Result result) {
         XDebuggerManager.getInstance(project).getBreakpointManager().removeBreakpoint(breakpoint);
       }
     }.execute();
   }
 
+  @Override
   public <B extends XBreakpoint<?>> XBreakpointType<B, ?> findBreakpointType(@NotNull Class<? extends XBreakpointType<B, ?>> typeClass) {
     if (myBreakpointTypeByClass == null) {
       myBreakpointTypeByClass = new HashMap<Class<? extends XBreakpointType>, XBreakpointType<?,?>>();
@@ -129,6 +136,7 @@
     return (XBreakpointType<B, ?>)type;
   }
 
+  @Override
   public <T extends XDebuggerSettings<?>> T getDebuggerSettings(Class<T> aClass) {
     return XDebuggerSettingsManager.getInstance().getSettings(aClass);
   }
@@ -138,16 +146,19 @@
     return XDebuggerTreeActionBase.getSelectedValue(dataContext);
   }
 
+  @Override
   @Nullable
   public XSourcePosition createPosition(@NotNull final VirtualFile file, final int line) {
     return XSourcePositionImpl.create(file, line);
   }
 
-  @Nullable 
+  @Override
+  @Nullable
   public XSourcePosition createPositionByOffset(@NotNull final VirtualFile file, final int offset) {
     return XSourcePositionImpl.createByOffset(file, offset);
   }
 
+  @Override
   public <B extends XLineBreakpoint<?>> XBreakpointGroupingRule<B, ?> getGroupingByFileRule() {
     return new XBreakpointFileGroupingRule<B>();
   }
@@ -172,16 +183,20 @@
     return editor;
   }
 
+  @Override
   public <B extends XBreakpoint<?>> Comparator<B> getDefaultBreakpointComparator(final XBreakpointType<B, ?> type) {
     return new Comparator<B>() {
+      @Override
       public int compare(final B o1, final B o2) {
         return type.getDisplayText(o1).compareTo(type.getDisplayText(o2));
       }
     };
   }
 
+  @Override
   public <P extends XBreakpointProperties> Comparator<XLineBreakpoint<P>> getDefaultLineBreakpointComparator() {
     return new Comparator<XLineBreakpoint<P>>() {
+      @Override
       public int compare(final XLineBreakpoint<P> o1, final XLineBreakpoint<P> o2) {
         int fileCompare = o1.getFileUrl().compareTo(o2.getFileUrl());
         if (fileCompare != 0) return fileCompare;
@@ -202,6 +217,7 @@
     return null;
   }
 
+  @Override
   public void iterateLine(@NotNull Project project, @NotNull Document document, int line, @NotNull Processor<PsiElement> processor) {
     PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
     if (file == null) return;
@@ -235,4 +251,9 @@
       }
     }
   }
+
+  @Override
+  public <B extends XLineBreakpoint<?>> List<XBreakpointGroupingRule<B, ?>> getGroupingByFileRuleAsList() {
+    return Collections.<XBreakpointGroupingRule<B, ?>>singletonList(this.<B>getGroupingByFileRule());
+  }
 }
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EditBreakpointActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EditBreakpointActionHandler.java
index 5a53748..1e30a9c 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EditBreakpointActionHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EditBreakpointActionHandler.java
@@ -16,8 +16,8 @@
 package com.intellij.xdebugger.impl.actions;
 
 import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.ex.EditorEx;
 import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
@@ -39,7 +39,7 @@
   @Override
   public void perform(@NotNull Project project, AnActionEvent event) {
     DataContext dataContext = event.getDataContext();
-    Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
+    Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
     if (editor == null) return;
 
     final Pair<GutterIconRenderer,Object> pair = XBreakpointUtil.findSelectedBreakpoint(project, editor);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerEditBreakpointActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerEditBreakpointActionHandler.java
index 92eb909..3ac17a4 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerEditBreakpointActionHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerEditBreakpointActionHandler.java
@@ -16,8 +16,8 @@
 package com.intellij.xdebugger.impl.actions;
 
 import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.markup.GutterIconRenderer;
 import com.intellij.openapi.project.Project;
@@ -31,13 +31,6 @@
 import javax.swing.*;
 import java.awt.*;
 
-/**
- * Created with IntelliJ IDEA.
- * User: zajac
- * Date: 04.05.12
- * Time: 4:07
- * To change this template use File | Settings | File Templates.
- */
 public class XDebuggerEditBreakpointActionHandler extends EditBreakpointActionHandler {
   @Override
   protected void doShowPopup(Project project, JComponent component, Point whereToShow, Object breakpoint) {
@@ -47,7 +40,7 @@
   @Override
   public boolean isEnabled(@NotNull Project project, AnActionEvent event) {
     DataContext dataContext = event.getDataContext();
-    Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
+    Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
     if (editor == null) return false;
     final Pair<GutterIconRenderer,Object> pair = XBreakpointUtil.findSelectedBreakpoint(project, editor);
     return pair.first != null && pair.second instanceof XLineBreakpointImpl;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java
index 65bfc25..76be112 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java
@@ -33,6 +33,7 @@
 
 class XBreakpointItem extends BreakpointItem {
   private final XBreakpoint<?> myBreakpoint;
+  private XLightBreakpointPropertiesPanel<XBreakpoint<?>> myPropertiesPanel;
 
   public XBreakpointItem(XBreakpoint<?> breakpoint) {
     myBreakpoint = breakpoint;
@@ -75,13 +76,21 @@
     return ((XBreakpointBase)myBreakpoint).getType().getDisplayText(myBreakpoint);
   }
 
+  @Override
+  public void saveState() {
+    if (myPropertiesPanel != null) {
+      myPropertiesPanel.saveProperties();
+    }
+  }
+
   public void doUpdateDetailView(DetailView panel, boolean editorOnly) {
     Project project = ((XBreakpointBase)myBreakpoint).getProject();
-    XLightBreakpointPropertiesPanel<XBreakpoint<?>> propertiesPanel = null;
+    saveState();
+    myPropertiesPanel = null;
     if (!editorOnly) {
-      propertiesPanel = new XLightBreakpointPropertiesPanel<XBreakpoint<?>>(project, getManager(), myBreakpoint, true);
+      myPropertiesPanel = new XLightBreakpointPropertiesPanel<XBreakpoint<?>>(project, getManager(), myBreakpoint, true);
 
-      panel.setPropertiesPanel(propertiesPanel.getMainPanel());
+      panel.setPropertiesPanel(myPropertiesPanel.getMainPanel());
     }
 
     XSourcePosition sourcePosition = myBreakpoint.getSourcePosition();
@@ -92,10 +101,10 @@
       panel.clearEditor();
     }
 
-    if (propertiesPanel != null) {
-      propertiesPanel.setDetailView(panel);
-      propertiesPanel.loadProperties();
-      propertiesPanel.getMainPanel().revalidate();
+    if (myPropertiesPanel != null) {
+      myPropertiesPanel.setDetailView(panel);
+      myPropertiesPanel.loadProperties();
+      myPropertiesPanel.getMainPanel().revalidate();
 
     }
 
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointChooser.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointChooser.java
index 1188613..563c614 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointChooser.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointChooser.java
@@ -126,7 +126,7 @@
         if (selected) {
           if (hackedSelection.get() != value) {
             hackedSelection.set(value);
-            myDetailController.selectionChanged();
+            myDetailController.updateDetailView();
           }
         }
       }
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItem.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItem.java
index 26439a7..f515bb6 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItem.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItem.java
@@ -39,6 +39,8 @@
 public abstract class BreakpointItem extends ItemWrapper implements Comparable<BreakpointItem>, Navigatable {
   public static final Key<Object> EDITOR_ONLY = Key.create("EditorOnly");
 
+  public abstract void saveState();
+
   public abstract Object getBreakpoint();
 
   public abstract boolean isEnabled();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointNoneItem.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointNoneItem.java
index 9c983c4..10b7d48 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointNoneItem.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointNoneItem.java
@@ -25,6 +25,11 @@
 
 public class BreakpointNoneItem extends BreakpointItem {
   @Override
+  public void saveState() {
+
+  }
+
+  @Override
   public Object getBreakpoint() {
     return null;
   }
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java
index a662cb4..6af4750 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java
@@ -36,6 +36,7 @@
 import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
 import com.intellij.xdebugger.impl.breakpoints.XBreakpointManagerImpl;
 import com.intellij.xdebugger.impl.breakpoints.XBreakpointsDialogState;
+import com.intellij.xdebugger.impl.breakpoints.ui.tree.BreakpointItemNode;
 import com.intellij.xdebugger.impl.breakpoints.ui.tree.BreakpointItemsTreeController;
 import com.intellij.xdebugger.impl.breakpoints.ui.tree.BreakpointsCheckboxTree;
 import org.jetbrains.annotations.NotNull;
@@ -198,7 +199,30 @@
   }
 
   private JComponent createMasterView() {
-    myTreeController = new BreakpointItemsTreeController(myRulesEnabled);
+    myTreeController = new BreakpointItemsTreeController(myRulesEnabled) {
+      @Override
+      public void nodeStateWillChangeImpl(CheckedTreeNode node) {
+        if (node instanceof BreakpointItemNode) {
+          ((BreakpointItemNode)node).getBreakpointItem().saveState();
+        }
+        super.nodeStateWillChangeImpl(node);
+      }
+
+      @Override
+      public void nodeStateDidChangeImpl(CheckedTreeNode node) {
+        super.nodeStateDidChangeImpl(node);
+        if (node instanceof BreakpointItemNode) {
+          myDetailController.doUpdateDetailView(true);
+        }
+      }
+
+      @Override
+      protected void selectionChangedImpl() {
+        super.selectionChangedImpl();
+        saveCurrentItem();
+        myDetailController.updateDetailView();
+      }
+    };
     JTree tree = new BreakpointsCheckboxTree(myProject, myTreeController);
 
     new AnAction("BreakpointDialog.GoToSource") {
@@ -216,16 +240,6 @@
       }
     }.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getShortcutSet(), tree);
 
-    tree.addMouseListener(new MouseAdapter() {
-      @Override
-      public void mouseClicked(MouseEvent event) {
-        if (event.getClickCount() == 2 && UIUtil.isActionClick(event, MouseEvent.MOUSE_CLICKED) && !UIUtil.isSelectionButtonDown(event) && !event.isConsumed()) {
-          navigate();
-          close(OK_EXIT_CODE);
-        }
-      }
-    });
-
     final DefaultActionGroup breakpointTypes = new DefaultActionGroup();
     for (BreakpointPanelProvider provider : myBreakpointsPanelProviders) {
       breakpointTypes.addAll(provider.getAddBreakpointActions(myProject));
@@ -268,8 +282,6 @@
     JPanel decoratedTree = decorator.createPanel();
     myTreeController.setTreeView(tree);
 
-    myDetailController.setTree(tree);
-
     myTreeController.buildTree(myBreakpointItems);
 
     initSelection(myBreakpointItems);
@@ -344,8 +356,16 @@
 
   @Override
   protected void dispose() {
+    saveCurrentItem();
     Disposer.dispose(myListenerDisposable);
     saveBreakpointsDialogState();
     super.dispose();
   }
+
+  private void saveCurrentItem() {
+    ItemWrapper item = myDetailController.getSelectedItem();
+    if (item instanceof BreakpointItem) {
+      ((BreakpointItem)item).saveState();
+    }
+  }
 }
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointPropertiesSubPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointPropertiesSubPanel.java
index 3ff9a41..4e53202d 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointPropertiesSubPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointPropertiesSubPanel.java
@@ -22,15 +22,7 @@
 import com.intellij.xdebugger.breakpoints.XBreakpointType;
 import org.jetbrains.annotations.NotNull;
 
-/**
- * Created by IntelliJ IDEA.
- * User: zajac
- * Date: 16.06.11
- * Time: 19:21
- * To change this template use File | Settings | File Templates.
- */
 public abstract class XBreakpointPropertiesSubPanel<B extends XBreakpoint<?>> {
-
   protected Project myProject;
   protected XBreakpointManager myBreakpointManager;
   protected B myBreakpoint;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointsTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointsTree.java
deleted file mode 100644
index 8610438..0000000
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointsTree.java
+++ /dev/null
@@ -1,285 +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.xdebugger.impl.breakpoints.ui;
-
-import com.intellij.ide.util.treeView.TreeState;
-import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.openapi.util.MultiValuesMap;
-import com.intellij.pom.Navigatable;
-import com.intellij.ui.CheckboxTree;
-import com.intellij.ui.CheckedTreeNode;
-import com.intellij.ui.SimpleTextAttributes;
-import com.intellij.util.ui.tree.TreeUtil;
-import com.intellij.xdebugger.breakpoints.XBreakpoint;
-import com.intellij.xdebugger.breakpoints.XBreakpointManager;
-import com.intellij.xdebugger.breakpoints.XBreakpointType;
-import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup;
-import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
-import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.TreeNode;
-import javax.swing.tree.TreePath;
-import java.util.*;
-
-/**
- * @author nik
- */
-public class XBreakpointsTree<B extends XBreakpoint<?>> extends CheckboxTree {
-  private final TreeNodeComparator myComparator;
-  private final CheckedTreeNode myRoot;
-  private DialogWrapper myParentDialog;
-  private final Map<B, BreakpointNode<B>> myNodes = new HashMap<B, BreakpointNode<B>>();
-  private List<XBreakpointGroupingRule<B, ?>> myGroupingRules;
-  private final Map<XBreakpointGroup, BreakpointsGroupNode> myGroupNodes = new HashMap<XBreakpointGroup, BreakpointsGroupNode>();
-  private final MultiValuesMap<XBreakpointGroupingRule<B, ?>, XBreakpointGroup> myGroups = new MultiValuesMap<XBreakpointGroupingRule<B,?>, XBreakpointGroup>();
-
-  private XBreakpointsTree(final XBreakpointType<B, ?> type, final CheckedTreeNode root,
-                           Collection<XBreakpointGroupingRule<B, ?>> groupingRules,
-                           DialogWrapper parentDialog,
-                           XBreakpointManager breakpointManager) {
-    super(new BreakpointsTreeCellRenderer(), root);
-    myRoot = root;
-    myParentDialog = parentDialog;
-    myComparator = new TreeNodeComparator<B>(type, breakpointManager);
-    setGroupingRulesInternal(groupingRules);
-
-    getEmptyText().setText("No " + type.getTitle());
-  }
-
-  private void setGroupingRulesInternal(final Collection<XBreakpointGroupingRule<B, ?>> groupingRules) {
-    myGroupingRules = new ArrayList<XBreakpointGroupingRule<B,?>>(groupingRules);
-    setShowsRootHandles(!groupingRules.isEmpty());
-  }
-
-  public static <B extends XBreakpoint<?>> XBreakpointsTree<B> createTree(final XBreakpointType<B, ?> type,
-                                                                          final Collection<XBreakpointGroupingRule<B, ?>> groupingRules,
-                                                                          DialogWrapper parentDialog, XBreakpointManager breakpointManager) {
-    return new XBreakpointsTree<B>(type, new CheckedTreeNode("root"), groupingRules, parentDialog, breakpointManager);
-  }
-
-  public void buildTree(@NotNull Collection<? extends B> breakpoints) {
-    final TreeState state = TreeState.createOn(this, myRoot);
-    myRoot.removeAllChildren();
-    myNodes.clear();
-    myGroupNodes.clear();
-    myGroups.clear();
-    for (B breakpoint : breakpoints) {
-      BreakpointNode<B> node = new BreakpointNode<B>(breakpoint);
-      CheckedTreeNode parent = getParentNode(breakpoint);
-      parent.add(node);
-      myNodes.put(breakpoint, node);
-    }
-    TreeUtil.sort(myRoot, myComparator);
-    ((DefaultTreeModel)getModel()).nodeStructureChanged(myRoot);
-    expandPath(new TreePath(myRoot));
-    state.applyTo(this, myRoot);
-  }
-
-
-  @NotNull
-  private CheckedTreeNode getParentNode(final B breakpoint) {
-    CheckedTreeNode parent = myRoot;
-    for (int i = 0; i < myGroupingRules.size(); i++) {
-      XBreakpointGroup group = getGroup(breakpoint, myGroupingRules.get(i));
-      if (group != null) {
-        parent = getOrCreateGroupNode(parent, group, i);
-      }
-    }
-    return parent;
-  }
-
-  private <G extends XBreakpointGroup> BreakpointsGroupNode<G> getOrCreateGroupNode(CheckedTreeNode parent, final G group,
-                                                                                       final int level) {
-    //noinspection unchecked
-    BreakpointsGroupNode<G> groupNode = (BreakpointsGroupNode<G>)myGroupNodes.get(group);
-    if (groupNode == null) {
-      groupNode = new BreakpointsGroupNode<G>(group, level);
-      myGroupNodes.put(group, groupNode);
-      parent.add(groupNode);
-    }
-    return groupNode;
-  }
-
-  @Override
-  protected void onDoubleClick(CheckedTreeNode node) {
-    if (node instanceof BreakpointNode<?>) {
-      final Navigatable navigatable = ((BreakpointNode)node).getBreakpoint().getNavigatable();
-      if (navigatable != null) {
-        navigatable.navigate(true);
-        myParentDialog.close(DialogWrapper.OK_EXIT_CODE);
-      }
-    }
-  }
-
-  @Nullable
-  private <G extends XBreakpointGroup> XBreakpointGroup getGroup(final B breakpoint, final XBreakpointGroupingRule<B, G> groupingRule) {
-    //noinspection unchecked
-    Collection<G> groups = (Collection<G>)myGroups.get(groupingRule);
-    if (groups == null) {
-      groups = Collections.emptyList();
-    }
-    G group = groupingRule.getGroup(breakpoint, groups);
-    if (group != null) {
-      myGroups.put(groupingRule, group);
-    }
-    return group;
-  }
-
-  @Override
-  protected void onNodeStateChanged(final CheckedTreeNode node) {
-    if (node instanceof BreakpointNode) {
-      ((BreakpointNode)node).getBreakpoint().setEnabled(node.isChecked());
-    }
-  }
-
-  public void setGroupingRules(List<XBreakpointGroupingRule<B, ?>> groupingRules) {
-    List<B> selectedBreakpoints = getSelectedBreakpoints();
-    List<B> allBreakpoints = new ArrayList<B>(myNodes.keySet());
-
-    setGroupingRulesInternal(groupingRules);
-    buildTree(allBreakpoints);
-
-    if (selectedBreakpoints.size() > 0) {
-      selectBreakpoint(selectedBreakpoints.get(0));
-    }
-  }
-
-  public List<B> getSelectedBreakpoints() {
-    final ArrayList<B> list = new ArrayList<B>();
-    TreePath[] selectionPaths = getSelectionPaths();
-    if (selectionPaths == null || selectionPaths.length == 0) return list;
-
-    for (TreePath selectionPath : selectionPaths) {
-      TreeUtil.traverseDepth((TreeNode)selectionPath.getLastPathComponent(), new TreeUtil.Traverse() {
-        public boolean accept(final Object node) {
-          if (node instanceof BreakpointNode) {
-            //noinspection unchecked
-            list.add(((BreakpointNode<B>)node).getBreakpoint());
-          }
-          return true;
-        }
-      });
-    }
-
-    return list;
-  }
-
-  public void selectBreakpoint(final B breakpoint) {
-    BreakpointNode<B> node = myNodes.get(breakpoint);
-    if (node != null) {
-      TreeUtil.selectNode(this, node);
-    }
-  }
-
-  private static class BreakpointsTreeCellRenderer extends CheckboxTreeCellRenderer {
-    @Override
-    public void customizeRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
-      if (value instanceof BreakpointNode) {
-        BreakpointNode node = (BreakpointNode)value;
-        XBreakpoint breakpoint = node.getBreakpoint();
-        String text = XBreakpointUtil.getDisplayText(breakpoint);
-        getTextRenderer().setIcon(node.getIcon());
-        getTextRenderer().append(text, node.getTextAttributes());
-      }
-      else if (value instanceof BreakpointsGroupNode) {
-        XBreakpointGroup group = ((BreakpointsGroupNode)value).getGroup();
-        getTextRenderer().setIcon(group.getIcon(expanded));
-        getTextRenderer().append(group.getName(), SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES);
-      }
-    }
-  }
-
-  private static class BreakpointsGroupNode<G extends XBreakpointGroup> extends CheckedTreeNode {
-    private final G myGroup;
-    private final int myLevel;
-
-    private BreakpointsGroupNode(G group, int level) {
-      super(group);
-      myLevel = level;
-      setChecked(false);
-      myGroup = group;
-    }
-
-    public G getGroup() {
-      return myGroup;
-    }
-
-    public int getLevel() {
-      return myLevel;
-    }
-  }
-  
-  private static class BreakpointNode<B extends XBreakpoint<?>> extends CheckedTreeNode {
-    private final B myBreakpoint;
-
-    private BreakpointNode(final B breakpoint) {
-      super(breakpoint);
-      myBreakpoint = breakpoint;
-      setChecked(breakpoint.isEnabled());
-    }
-
-    public B getBreakpoint() {
-      return myBreakpoint;
-    }
-
-    public Icon getIcon() {
-      XBreakpointType type = myBreakpoint.getType();
-      return isChecked() ? type.getEnabledIcon() : type.getDisabledIcon();
-    }
-
-    public SimpleTextAttributes getTextAttributes() {
-      return isChecked() ? SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES : SimpleTextAttributes.GRAYED_ATTRIBUTES;
-    }
-  }
-
-  private static class TreeNodeComparator<B extends XBreakpoint<?>> implements Comparator<TreeNode> {
-    private final Comparator<B> myBreakpointComparator;
-    private final XBreakpointManager myBreakpointManager;
-
-    public TreeNodeComparator(final XBreakpointType<B, ?> type, XBreakpointManager breakpointManager) {
-      myBreakpointManager = breakpointManager;
-      myBreakpointComparator = type.getBreakpointComparator();
-    }
-
-    public int compare(final TreeNode o1, final TreeNode o2) {
-      if (o1 instanceof BreakpointNode && o2 instanceof BreakpointNode) {
-        //noinspection unchecked
-        B b1 = (B)((BreakpointNode)o1).getBreakpoint();
-        //noinspection unchecked
-        B b2 = (B)((BreakpointNode)o2).getBreakpoint();
-        boolean default1 = myBreakpointManager.isDefaultBreakpoint(b1);
-        boolean default2 = myBreakpointManager.isDefaultBreakpoint(b2);
-        if (default1 && !default2) return -1;
-        if (!default1 && default2) return 1;
-        return myBreakpointComparator.compare(b1, b2);
-      }
-      if (o1 instanceof BreakpointsGroupNode && o2 instanceof BreakpointsGroupNode) {
-        final BreakpointsGroupNode group1 = (BreakpointsGroupNode)o1;
-        final BreakpointsGroupNode group2 = (BreakpointsGroupNode)o2;
-        if (group1.getLevel() != group2.getLevel()) {
-          return group1.getLevel() - group2.getLevel();
-        }
-        return group1.getGroup().compareTo(group2.getGroup());
-      }
-      return o1 instanceof BreakpointsGroupNode ? -1 : 1;
-    }
-  }
-
-}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.form b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.form
index a15e28b..ff5430f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.form
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.form
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.xdebugger.impl.breakpoints.ui.XLightBreakpointPropertiesPanel">
-  <grid id="27dc6" binding="myMainPanel" custom-create="true" layout-manager="GridLayoutManager" row-count="9" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+  <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="9" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
     <margin top="0" left="0" bottom="0" right="0"/>
     <constraints>
       <xy x="20" y="20" width="500" height="453"/>
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
index 6be7cd0..d382829 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
@@ -38,7 +38,6 @@
 import java.util.List;
 
 public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implements XSuspendPolicyPanel.Delegate {
-
   public boolean showMoreOptions() {
     return myShowMoreOptions;
   }
@@ -54,16 +53,6 @@
     }
   }
 
-  private void createUIComponents() {
-    myMainPanel = new JPanel() {
-      @Override
-      public void removeNotify() {
-        super.removeNotify();
-        saveProperties();
-      }
-    };
-  }
-
   public interface Delegate {
     void showMoreOptions();
   }
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.form b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.form
index 356145a..4c9a695 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.form
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.form
@@ -1,84 +1,52 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.xdebugger.impl.breakpoints.ui.XSuspendPolicyPanel">
-  <grid id="27dc6" binding="myContentPane" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+  <grid id="27dc6" binding="myContentPane" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
     <margin top="0" left="0" bottom="0" right="0"/>
     <constraints>
-      <xy x="20" y="20" width="537" height="59"/>
+      <xy x="20" y="20" width="537" height="57"/>
     </constraints>
     <properties/>
-    <border type="none"/>
+    <border type="etched" title-resource-bundle="messages/XDebuggerBundle" title-key="suspend.policy.panel.title"/>
     <children>
-      <grid id="e69ea" binding="mySuspendPolicyPanel" layout-manager="CardLayout" hgap="0" vgap="0">
+      <hspacer id="d9eab">
         <constraints>
-          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+          <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
         </constraints>
-        <properties/>
-        <clientProperties>
-          <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
-        </clientProperties>
-        <border type="etched" title-resource-bundle="messages/XDebuggerBundle" title-key="xbreakpoints.suspend.group.title"/>
-        <children>
-          <grid id="190d5" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <card name="checkbox"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <component id="ac150" class="javax.swing.JCheckBox" binding="mySuspendCheckBox" default-binding="true">
-                <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties>
-                  <selected value="true"/>
-                  <text resource-bundle="messages/XDebuggerBundle" key="xbreakpoints.suspend.checkbox"/>
-                </properties>
-              </component>
-            </children>
-          </grid>
-          <grid id="f5e5" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <card name="radioButtons"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <component id="aba21" class="javax.swing.JRadioButton" binding="mySuspendAllRadioButton">
-                <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties>
-                  <selected value="true"/>
-                  <text resource-bundle="messages/XDebuggerBundle" key="xbreakpoints.suspend.all.radio"/>
-                </properties>
-              </component>
-              <component id="91d9b" class="javax.swing.JRadioButton" binding="mySuspendThreadRadioButton">
-                <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties>
-                  <text resource-bundle="messages/XDebuggerBundle" key="xbreakpoints.suspend.thread.radio"/>
-                </properties>
-              </component>
-              <component id="fbfd7" class="javax.swing.JRadioButton" binding="mySuspendNoneRadioButton">
-                <constraints>
-                  <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties>
-                  <text resource-bundle="messages/XDebuggerBundle" key="xbreakpoints.suspend.none.radio"/>
-                </properties>
-              </component>
-              <hspacer id="d9eab">
-                <constraints>
-                  <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-                </constraints>
-              </hspacer>
-            </children>
-          </grid>
-        </children>
-      </grid>
+      </hspacer>
+      <component id="aba21" class="javax.swing.JRadioButton" binding="mySuspendAll">
+        <constraints>
+          <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <selected value="true"/>
+          <text resource-bundle="messages/XDebuggerBundle" key="suspend.policy.panel.all"/>
+        </properties>
+      </component>
+      <component id="91d9b" class="javax.swing.JRadioButton" binding="mySuspendThread">
+        <constraints>
+          <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text resource-bundle="messages/XDebuggerBundle" key="suspend.policy.panel.thread"/>
+        </properties>
+      </component>
+      <component id="ac150" class="javax.swing.JCheckBox" binding="mySuspendCheckBox" default-binding="true">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <selected value="true"/>
+          <text resource-bundle="messages/XDebuggerBundle" key="suspend.policy.panel.suspend"/>
+        </properties>
+      </component>
+      <component id="ac069" class="javax.swing.JButton" binding="myMakeDefaultButton" default-binding="true">
+        <constraints>
+          <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text resource-bundle="messages/XDebuggerBundle" key="suspend.policy.panel.makeDefault"/>
+        </properties>
+      </component>
     </children>
   </grid>
 </form>
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java
index a7bf087..c46914f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java
@@ -15,36 +15,29 @@
  */
 package com.intellij.xdebugger.impl.breakpoints.ui;
 
+import com.intellij.ide.util.PropertiesComponent;
 import com.intellij.openapi.project.Project;
 import com.intellij.xdebugger.breakpoints.SuspendPolicy;
 import com.intellij.xdebugger.breakpoints.XBreakpoint;
 import com.intellij.xdebugger.breakpoints.XBreakpointManager;
-import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.util.HashMap;
-import java.util.Map;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
 
-/**
- * Created by IntelliJ IDEA.
- * User: zajac
- * Date: 16.06.11
- * Time: 17:40
- * To change this template use File | Settings | File Templates.
- */
 public class XSuspendPolicyPanel<B extends XBreakpoint<?>> extends XBreakpointPropertiesSubPanel<B> {
-
-  private JPanel mySuspendPolicyPanel;
   private JCheckBox mySuspendCheckBox;
-  private JRadioButton mySuspendAllRadioButton;
-  private JRadioButton mySuspendThreadRadioButton;
-  private JRadioButton mySuspendNoneRadioButton;
+  private JRadioButton mySuspendAll;
+  private JRadioButton mySuspendThread;
+
   private JPanel myContentPane;
-  private Map<SuspendPolicy, JRadioButton> mySuspendRadioButtons;
+  private JButton myMakeDefaultButton;
+
+  private ButtonGroup mySuspendPolicyGroup;
 
   public interface Delegate {
     void showMoreOptionsIfNeeded();
@@ -52,61 +45,137 @@
 
   private Delegate myDelegate;
 
+  @Override
   public void init(Project project, final XBreakpointManager breakpointManager, @NotNull B breakpoint) {
     super.init(project, breakpointManager, breakpoint);
-    mySuspendRadioButtons = new HashMap<SuspendPolicy, JRadioButton>();
-    mySuspendRadioButtons.put(SuspendPolicy.ALL, mySuspendAllRadioButton);
-    mySuspendRadioButtons.put(SuspendPolicy.THREAD, mySuspendThreadRadioButton);
-    mySuspendRadioButtons.put(SuspendPolicy.NONE, mySuspendNoneRadioButton);
-    @NonNls String card = myBreakpointType.isSuspendThreadSupported() ? "radioButtons" : "checkbox";
-    ((CardLayout)mySuspendPolicyPanel.getLayout()).show(mySuspendPolicyPanel, card);
 
     mySuspendCheckBox.addActionListener(new ActionListener() {
       @Override
       public void actionPerformed(ActionEvent actionEvent) {
-        if (myDelegate != null && !mySuspendCheckBox.isSelected()) {
+        boolean selected = mySuspendCheckBox.isSelected();
+
+        if (myBreakpoint.getType().isSuspendThreadSupported()) {
+          changeEnableState(selected);
+        }
+
+        if (myDelegate != null && !selected) {
           myDelegate.showMoreOptionsIfNeeded();
         }
       }
     });
+
+    if (!myBreakpoint.getType().isSuspendThreadSupported()) {
+      return;
+    }
+
+    mySuspendPolicyGroup = new ButtonGroup();
+    mySuspendPolicyGroup.add(mySuspendAll);
+    mySuspendPolicyGroup.add(mySuspendThread);
+
+    updateSuspendPolicyFont(createSettingsKey());
+
+    ItemListener suspendPolicyChangeListener = new ItemListener() {
+      @Override
+      public void itemStateChanged(ItemEvent e) {
+        updateMakeDefaultEnableState();
+      }
+    };
+    updateMakeDefaultEnableState();
+
+    mySuspendAll.addItemListener(suspendPolicyChangeListener);
+    mySuspendThread.addItemListener(suspendPolicyChangeListener);
+
+    myMakeDefaultButton.addActionListener(new ActionListener() {
+      @Override
+      public void actionPerformed(ActionEvent e) {
+        SuspendPolicy suspendPolicy = getSelectedSuspendPolicy();
+        String settingsKey = createSettingsKey();
+        PropertiesComponent.getInstance().setValue(settingsKey, suspendPolicy.name());
+        updateSuspendPolicyFont(settingsKey);
+        if (SuspendPolicy.THREAD == suspendPolicy) {
+          mySuspendThread.requestFocus();
+        }
+        else {
+          mySuspendAll.requestFocus();
+        }
+        myMakeDefaultButton.setEnabled(false);
+      }
+    });
+  }
+
+  private void updateMakeDefaultEnableState() {
+    myMakeDefaultButton.setEnabled(!getSelectedSuspendPolicy().name().equalsIgnoreCase(PropertiesComponent.getInstance().getValue(createSettingsKey(), SuspendPolicy.ALL.name())));
+  }
+
+  private String createSettingsKey() {
+    return "debugger.suspend.policy-" + myBreakpointType.getId();
+  }
+
+  private void updateSuspendPolicyFont(String settingsKey) {
+    String defaultPolicy = PropertiesComponent.getInstance().getValue(settingsKey, SuspendPolicy.ALL.name());
+    Font font = mySuspendAll.getFont().deriveFont(Font.PLAIN);
+    Font boldFont = font.deriveFont(Font.BOLD);
+
+    mySuspendAll.setFont(SuspendPolicy.ALL.name().equalsIgnoreCase(defaultPolicy) ? boldFont : font);
+    mySuspendThread.setFont(SuspendPolicy.THREAD.name().equalsIgnoreCase(defaultPolicy) ? boldFont : font);
+  }
+
+  private void changeEnableState(boolean selected) {
+    mySuspendAll.setEnabled(selected);
+    mySuspendThread.setEnabled(selected);
+    if (selected) {
+      updateMakeDefaultEnableState();
+    }
+    else {
+      myMakeDefaultButton.setEnabled(false);
+    }
+  }
+
+  private void changeVisibleState(boolean suspendThreadSupported) {
+    mySuspendAll.setVisible(suspendThreadSupported);
+    mySuspendThread.setVisible(suspendThreadSupported);
+    myMakeDefaultButton.setVisible(suspendThreadSupported);
   }
 
   @Override
   public boolean lightVariant(boolean showAllOptions) {
-    mySuspendPolicyPanel.setBorder(null);
+    myContentPane.setBorder(null);
     return false;
   }
 
   @Override
   void loadProperties() {
     SuspendPolicy suspendPolicy = myBreakpoint.getSuspendPolicy();
-    mySuspendRadioButtons.get(suspendPolicy).setSelected(true);
-    final boolean selected = suspendPolicy != SuspendPolicy.NONE;
+    boolean selected = suspendPolicy != SuspendPolicy.NONE;
+    boolean suspendThreadSupported = myBreakpoint.getType().isSuspendThreadSupported();
+
+    changeVisibleState(suspendThreadSupported);
+    if (suspendThreadSupported) {
+      mySuspendPolicyGroup.setSelected(suspendPolicy == SuspendPolicy.THREAD ? mySuspendThread.getModel() : mySuspendAll.getModel(), true);
+      changeEnableState(selected);
+    }
+
     mySuspendCheckBox.setSelected(selected);
-    if (!selected) {
-      if (myDelegate != null) {
-        myDelegate.showMoreOptionsIfNeeded();
-      }
+    if (!selected && myDelegate != null) {
+      myDelegate.showMoreOptionsIfNeeded();
     }
   }
 
-  private SuspendPolicy getConfiguredSuspendPolicy() {
-    if (!myBreakpoint.getType().isSuspendThreadSupported()) {
-      return mySuspendCheckBox.isSelected() ? SuspendPolicy.ALL : SuspendPolicy.NONE;
+  private SuspendPolicy getSelectedSuspendPolicy() {
+    if (!mySuspendCheckBox.isSelected()) {
+      return SuspendPolicy.NONE;
     }
-
-    for (SuspendPolicy policy : mySuspendRadioButtons.keySet()) {
-      if (mySuspendRadioButtons.get(policy).isSelected()) {
-        return policy;
-      }
+    else if (myBreakpoint.getType().isSuspendThreadSupported()) {
+      return mySuspendAll.isSelected() ? SuspendPolicy.ALL : SuspendPolicy.THREAD;
     }
-    return SuspendPolicy.ALL;
+    else {
+      return SuspendPolicy.ALL;
+    }
   }
 
-
   @Override
   void saveProperties() {
-    myBreakpoint.setSuspendPolicy(getConfiguredSuspendPolicy());
+    myBreakpoint.setSuspendPolicy(getSelectedSuspendPolicy());
   }
 
   public Delegate getDelegate() {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemNode.java
index 8cbde4d..01d9482 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemNode.java
@@ -18,7 +18,7 @@
 import com.intellij.ui.CheckedTreeNode;
 import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem;
 
-class BreakpointItemNode extends CheckedTreeNode {
+public class BreakpointItemNode extends CheckedTreeNode {
   private final BreakpointItem myBreakpoint;
 
   BreakpointItemNode(final BreakpointItem breakpoint) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java
index 9ebdfea..babdd09 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java
@@ -27,6 +27,8 @@
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
 import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.DefaultTreeModel;
 import javax.swing.tree.TreeNode;
@@ -46,6 +48,7 @@
   private final MultiValuesMap<XBreakpointGroupingRule, XBreakpointGroup> myGroups = new MultiValuesMap<XBreakpointGroupingRule, XBreakpointGroup>();
 
   private JTree myTreeView;
+  protected boolean myInBuild;
 
   public BreakpointItemsTreeController(Collection<XBreakpointGroupingRule> groupingRules) {
     myRoot = new CheckedTreeNode("root");
@@ -58,12 +61,47 @@
 
   public void setTreeView(JTree treeView) {
     myTreeView = treeView;
+    myTreeView.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
+      @Override
+      public void valueChanged(TreeSelectionEvent event) {
+        selectionChanged();
+      }
+    });
     if (treeView instanceof BreakpointsCheckboxTree) {
       ((BreakpointsCheckboxTree)treeView).setDelegate(this);
     }
     myTreeView.setShowsRootHandles(!myGroupingRules.isEmpty());
   }
 
+  protected void selectionChanged() {
+    if (myInBuild) return;
+    selectionChangedImpl();
+  }
+
+  protected void selectionChangedImpl() {
+  }
+
+  @Override
+  public void nodeStateDidChange(CheckedTreeNode node) {
+    if (myInBuild) return;
+    nodeStateDidChangeImpl(node);
+  }
+
+  protected void nodeStateDidChangeImpl(CheckedTreeNode node) {
+    if (node instanceof BreakpointItemNode) {
+      ((BreakpointItemNode)node).getBreakpointItem().setEnabled(node.isChecked());
+    }
+  }
+
+  @Override
+  public void nodeStateWillChange(CheckedTreeNode node) {
+    if (myInBuild) return;
+    nodeStateWillChangeImpl(node);
+  }
+
+  protected void nodeStateWillChangeImpl(CheckedTreeNode node) {
+  }
+
   private void setGroupingRulesInternal(final Collection<XBreakpointGroupingRule> groupingRules) {
     myGroupingRules = new ArrayList<XBreakpointGroupingRule>(groupingRules);
   }
@@ -81,9 +119,11 @@
       myNodes.put(breakpoint, node);
     }
     TreeUtil.sort(myRoot, myComparator);
+    myInBuild = true;
     ((DefaultTreeModel)(myTreeView.getModel())).nodeStructureChanged(myRoot);
     state.applyTo(myTreeView, myRoot);
     TreeUtil.expandAll(myTreeView);
+    myInBuild = false;
   }
 
 
@@ -140,25 +180,15 @@
     return groupNode;
   }
 
-  @Override
-  public void nodeStateChanged(CheckedTreeNode node) {
-    if (node instanceof BreakpointItemNode) {
-      ((BreakpointItemNode)node).getBreakpointItem().setEnabled(node.isChecked());
-    }
-  }
-
   public void setGroupingRules(Collection<XBreakpointGroupingRule> groupingRules) {
     setGroupingRulesInternal(groupingRules);
     rebuildTree(new ArrayList<BreakpointItem>(myNodes.keySet()));
   }
 
   public void rebuildTree(Collection<BreakpointItem> items) {
-    List<BreakpointItem> selectedBreakpoints = getSelectedBreakpoints();
     TreePath path = myTreeView.getSelectionPath();
     buildTree(items);
-    if (selectedBreakpoints.size() > 0) {
-      selectBreakpointItem(selectedBreakpoints.get(0), path);
-    }
+    selectBreakpointItem(null, path);
   }
 
   public List<BreakpointItem> getSelectedBreakpoints() {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointsCheckboxTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointsCheckboxTree.java
index 7c113f5..c74e92d 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointsCheckboxTree.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointsCheckboxTree.java
@@ -21,17 +21,26 @@
 
 public class BreakpointsCheckboxTree extends CheckboxTree {
 
+  @Override
+  protected void nodeStateWillChange(CheckedTreeNode node) {
+    super.nodeStateWillChange(node);
+    if (myDelegate != null) {
+      myDelegate.nodeStateWillChange(node);
+    }
+  }
 
   @Override
   protected void onNodeStateChanged(CheckedTreeNode node) {
     super.onNodeStateChanged(node);
     if (myDelegate != null) {
-      myDelegate.nodeStateChanged(node);
+      myDelegate.nodeStateDidChange(node);
     }
   }
 
   interface Delegate {
-    void nodeStateChanged(CheckedTreeNode node);
+    void nodeStateDidChange(CheckedTreeNode node);
+
+    void nodeStateWillChange(CheckedTreeNode node);
   }
 
   public void setDelegate(Delegate delegate) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
index badb628..a9ccf69 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
@@ -83,7 +83,7 @@
         });
       }
     };
-    mySession.addSessionListener(mySessionListener);
+    mySession.addSessionListener(mySessionListener, myDisposable);
 
     myTreePanel = new XDebuggerTreePanel(session.getProject(), editorsProvider, myDisposable, sourcePosition, XDebuggerActions.EVALUATE_DIALOG_TREE_POPUP_GROUP,
                                          ((XDebugSessionImpl)session).getValueMarkers());
@@ -122,12 +122,6 @@
   }
 
   @Override
-  protected void dispose() {
-    mySession.removeSessionListener(mySessionListener);
-    super.dispose();
-  }
-
-  @Override
   protected void doOKAction() {
     evaluate();
   }
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java
new file mode 100644
index 0000000..85ff7b2
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java
@@ -0,0 +1,28 @@
+/*
+ * 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.xdebugger.impl.frame;
+
+import com.intellij.openapi.Disposable;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface XDebugView extends Disposable {
+  enum SessionEvent {PAUSED, BEFORE_RESUME, RESUMED, STOPPED, FRAME_CHANGED, SETTINGS_CHANGED}
+
+  void processSessionEvent(@NotNull SessionEvent event);
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewBase.java
deleted file mode 100644
index c09bcf5..0000000
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewBase.java
+++ /dev/null
@@ -1,90 +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.xdebugger.impl.frame;
-
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.ui.AppUIUtil;
-import com.intellij.xdebugger.XDebugSession;
-import com.intellij.xdebugger.XDebugSessionAdapter;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author nik
- */
-public abstract class XDebugViewBase implements Disposable {
-  protected enum SessionEvent {PAUSED, BEFORE_RESUME, RESUMED, STOPPED, FRAME_CHANGED, SETTINGS_CHANGED}
-
-  protected final XDebugSession mySession;
-  private final MyDebugSessionListener mySessionListener;
-
-  public XDebugViewBase(@NotNull final XDebugSession session, @Nullable Disposable parentDisposable) {
-    mySession = session;
-    mySessionListener = new MyDebugSessionListener();
-    mySession.addSessionListener(mySessionListener);
-    if (parentDisposable != null) {
-      Disposer.register(parentDisposable, this);
-    }
-  }
-
-  public void rebuildView() {
-    onSessionEvent(SessionEvent.SETTINGS_CHANGED);
-  }
-
-  private void onSessionEvent(final SessionEvent event) {
-    AppUIUtil.invokeLaterIfProjectAlive(mySession.getProject(), new Runnable() {
-      @Override
-      public void run() {
-        rebuildView(event);
-      }
-    });
-  }
-
-  protected abstract void rebuildView(final SessionEvent event);
-
-  @Override
-  public void dispose() {
-    mySession.removeSessionListener(mySessionListener);
-  }
-
-  private class MyDebugSessionListener extends XDebugSessionAdapter {
-    @Override
-    public void sessionPaused() {
-      onSessionEvent(SessionEvent.PAUSED);
-    }
-
-    @Override
-    public void sessionResumed() {
-      onSessionEvent(SessionEvent.RESUMED);
-    }
-
-    @Override
-    public void sessionStopped() {
-      onSessionEvent(SessionEvent.STOPPED);
-    }
-
-    @Override
-    public void stackFrameChanged() {
-      onSessionEvent(SessionEvent.FRAME_CHANGED);
-    }
-
-    @Override
-    public void beforeSessionResume() {
-      onSessionEvent(SessionEvent.BEFORE_RESUME);
-    }
-  }
-}
\ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewSessionListener.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewSessionListener.java
new file mode 100644
index 0000000..11b3020
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewSessionListener.java
@@ -0,0 +1,68 @@
+/*
+ * 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.xdebugger.impl.frame;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.ui.AppUIUtil;
+import com.intellij.xdebugger.XDebugSessionAdapter;
+import org.jetbrains.annotations.NotNull;
+
+/**
+* @author nik
+*/
+public class XDebugViewSessionListener extends XDebugSessionAdapter {
+  private XDebugView myDebugView;
+  private final Project myProject;
+
+  public XDebugViewSessionListener(@NotNull XDebugView debugView, @NotNull Project project) {
+    myDebugView = debugView;
+    myProject = project;
+  }
+
+  private void onSessionEvent(final @NotNull XDebugView.SessionEvent event) {
+    AppUIUtil.invokeLaterIfProjectAlive(myProject, new Runnable() {
+      @Override
+      public void run() {
+        myDebugView.processSessionEvent(event);
+      }
+    });
+  }
+
+  @Override
+  public void sessionPaused() {
+    onSessionEvent(XDebugView.SessionEvent.PAUSED);
+  }
+
+  @Override
+  public void sessionResumed() {
+    onSessionEvent(XDebugView.SessionEvent.RESUMED);
+  }
+
+  @Override
+  public void sessionStopped() {
+    onSessionEvent(XDebugView.SessionEvent.STOPPED);
+  }
+
+  @Override
+  public void stackFrameChanged() {
+    onSessionEvent(XDebugView.SessionEvent.FRAME_CHANGED);
+  }
+
+  @Override
+  public void beforeSessionResume() {
+    onSessionEvent(XDebugView.SessionEvent.BEFORE_RESUME);
+  }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
index 7d1c9a9..275015c 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
@@ -16,7 +16,6 @@
 package com.intellij.xdebugger.impl.frame;
 
 import com.intellij.ide.CommonActionsManager;
-import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.actionSystem.ActionPlaces;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
@@ -34,7 +33,6 @@
 import com.intellij.xdebugger.frame.XStackFrame;
 import com.intellij.xdebugger.frame.XSuspendContext;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import javax.swing.border.EmptyBorder;
@@ -51,19 +49,20 @@
 /**
  * @author nik
  */
-public class XFramesView extends XDebugViewBase {
+public class XFramesView implements XDebugView {
   private final JPanel myMainPanel;
   private final XDebuggerFramesList myFramesList;
   private final JComboBox myThreadComboBox;
   private final Set<XExecutionStack> myExecutionStacks = ContainerUtil.newHashSet();
+  @NotNull private final XDebugSession mySession;
   private XExecutionStack mySelectedStack;
   private boolean myListenersEnabled;
   private final Map<XExecutionStack, StackFramesListBuilder> myBuilders = new HashMap<XExecutionStack, StackFramesListBuilder>();
   private final ActionToolbarImpl myToolbar;
   private final Wrapper myThreadsPanel;
 
-  public XFramesView(@NotNull final XDebugSession session, @Nullable final Disposable parentDisposable) {
-    super(session, parentDisposable);
+  public XFramesView(@NotNull final XDebugSession session) {
+    mySession = session;
 
     myMainPanel = new JPanel(new BorderLayout());
 
@@ -97,7 +96,7 @@
     myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.EAST);
     myMainPanel.add(myThreadsPanel, BorderLayout.NORTH);
 
-    rebuildView(SessionEvent.RESUMED);
+    processSessionEvent(SessionEvent.RESUMED);
   }
 
   private ActionToolbarImpl createToolbar() {
@@ -125,7 +124,7 @@
   }
 
   @Override
-  protected void rebuildView(final SessionEvent event) {
+  public void processSessionEvent(@NotNull final SessionEvent event) {
     if (event == SessionEvent.BEFORE_RESUME) return;
     if (event == SessionEvent.FRAME_CHANGED) {
       XStackFrame currentStackFrame = mySession.getCurrentStackFrame();
@@ -191,6 +190,10 @@
     }
   }
 
+  @Override
+  public void dispose() {
+  }
+
   public XDebuggerFramesList getFramesList() {
     return myFramesList;
   }
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java
index 9eb5884..f7f32ba 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java
@@ -15,51 +15,31 @@
  */
 package com.intellij.xdebugger.impl.frame;
 
-import com.intellij.openapi.Disposable;
 import com.intellij.openapi.project.Project;
-import com.intellij.xdebugger.XDebuggerBundle;
+import com.intellij.ui.AppUIUtil;
 import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
 import com.intellij.xdebugger.frame.XStackFrame;
-import com.intellij.xdebugger.impl.actions.XDebuggerActions;
-import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
-import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
-import com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode;
-import com.intellij.xdebugger.impl.ui.tree.nodes.XStackFrameNode;
 import org.jetbrains.annotations.NotNull;
 
-import javax.swing.*;
-
 /**
  * @author nik
  */
-public class XStandaloneVariablesView implements Disposable {
-  private final XDebuggerTreePanel myDebuggerTreePanel;
+public class XStandaloneVariablesView extends XVariablesViewBase {
+  private final XStackFrame myStackFrame;
 
-  public XStandaloneVariablesView(@NotNull Project project, @NotNull XDebuggerEditorsProvider editorsProvider) {
-    myDebuggerTreePanel = new XDebuggerTreePanel(project, editorsProvider, this, null, XDebuggerActions.VARIABLES_TREE_POPUP_GROUP, null);
-    getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.variables.not.available"));
+  public XStandaloneVariablesView(@NotNull Project project, @NotNull XDebuggerEditorsProvider editorsProvider, @NotNull XStackFrame stackFrame) {
+    super(project, editorsProvider, null);
+    myStackFrame = stackFrame;
+    buildTreeAndRestoreState(stackFrame);
   }
 
-  public void showVariables(@NotNull XStackFrame stackFrame) {
-    getTree().setSourcePosition(stackFrame.getSourcePosition());
-    getTree().setRoot(new XStackFrameNode(getTree(), stackFrame), false);
-  }
-
-  public void showMessage(@NotNull String message) {
-    getTree().setSourcePosition(null);
-    getTree().setRoot(MessageTreeNode.createInfoMessage(getTree(), message), true);
-  }
-
-  private XDebuggerTree getTree() {
-    return myDebuggerTreePanel.getTree();
-  }
-
-  @Override
-  public void dispose() {
-
-  }
-
-  public JComponent getPanel() {
-    return myDebuggerTreePanel.getMainPanel();
+  public void rebuildView() {
+    AppUIUtil.invokeLaterIfProjectAlive(getTree().getProject(), new Runnable() {
+      @Override
+      public void run() {
+        saveCurrentTreeState(myStackFrame);
+        buildTreeAndRestoreState(myStackFrame);
+      }
+    });
   }
 }
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
index fb28bda..31b30a8 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
@@ -15,55 +15,34 @@
  */
 package com.intellij.xdebugger.impl.frame;
 
-import com.intellij.ide.dnd.DnDManager;
-import com.intellij.openapi.Disposable;
 import com.intellij.xdebugger.XDebugProcess;
 import com.intellij.xdebugger.XDebugSession;
-import com.intellij.xdebugger.XDebuggerBundle;
-import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
 import com.intellij.xdebugger.frame.XStackFrame;
 import com.intellij.xdebugger.impl.XDebugSessionImpl;
-import com.intellij.xdebugger.impl.actions.XDebuggerActions;
 import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
-import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
-import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeRestorer;
-import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState;
 import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
-import com.intellij.xdebugger.impl.ui.tree.nodes.XStackFrameNode;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
 
 import static com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode.createInfoMessage;
 
 /**
  * @author nik
  */
-public class XVariablesView extends XDebugViewBase {
-  private final XDebuggerTreePanel myDebuggerTreePanel;
-  private XDebuggerTreeState myTreeState;
-  private Object myFrameEqualityObject;
-  private XDebuggerTreeRestorer myTreeRestorer;
+public class XVariablesView extends XVariablesViewBase implements XDebugView {
+  @NotNull private final XDebugSession mySession;
 
-  public XVariablesView(@NotNull XDebugSession session, @Nullable final Disposable parentDisposable) {
-    super(session, parentDisposable);
-    XDebuggerEditorsProvider editorsProvider = session.getDebugProcess().getEditorsProvider();
-    XValueMarkers<?,?> markers = session instanceof XDebugSessionImpl ? ((XDebugSessionImpl)session).getValueMarkers() : null;
-    myDebuggerTreePanel = new XDebuggerTreePanel(session.getProject(), editorsProvider, this, null, XDebuggerActions.VARIABLES_TREE_POPUP_GROUP, markers);
-    myDebuggerTreePanel.getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.variables.not.available"));
-    DnDManager.getInstance().registerSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
+  public XVariablesView(@NotNull XDebugSession session) {
+    super(session.getProject(), session.getDebugProcess().getEditorsProvider(), ((XDebugSessionImpl)session).getValueMarkers());
+    mySession = session;
   }
 
   @Override
-  protected void rebuildView(final SessionEvent event) {
+  public void processSessionEvent(@NotNull final SessionEvent event) {
     XStackFrame stackFrame = mySession.getCurrentStackFrame();
-    XDebuggerTree tree = myDebuggerTreePanel.getTree();
+    XDebuggerTree tree = getTree();
 
     if (event == SessionEvent.BEFORE_RESUME || event == SessionEvent.SETTINGS_CHANGED) {
-      disposeTreeRestorer();
-      myFrameEqualityObject = stackFrame != null ? stackFrame.getEqualityObject() : null;
-      myTreeState = XDebuggerTreeState.saveState(tree);
+      saveCurrentTreeState(stackFrame);
       if (event == SessionEvent.BEFORE_RESUME) {
         return;
       }
@@ -71,16 +50,7 @@
 
     tree.markNodesObsolete();
     if (stackFrame != null) {
-      tree.setSourcePosition(stackFrame.getSourcePosition());
-      tree.setRoot(new XStackFrameNode(tree, stackFrame), false);
-      Object newEqualityObject = stackFrame.getEqualityObject();
-      if (myFrameEqualityObject != null &&
-          newEqualityObject != null &&
-          myFrameEqualityObject.equals(newEqualityObject) &&
-          myTreeState != null) {
-        disposeTreeRestorer();
-        myTreeRestorer = myTreeState.restoreState(tree);
-      }
+      buildTreeAndRestoreState(stackFrame);
     }
     else {
       tree.setSourcePosition(null);
@@ -90,38 +60,10 @@
         node = createInfoMessage(tree, "Frame is not available");
       }
       else {
-        if (mySession instanceof XDebugSession) {
-          XDebugProcess debugProcess = ((XDebugSession)mySession).getDebugProcess();
-
-          node = createInfoMessage(tree, debugProcess.getCurrentStateMessage(), debugProcess.getCurrentStateHyperlinkListener());
-        }
-        else {
-          node = createInfoMessage(tree, "Frame is not available");
-        }
+        XDebugProcess debugProcess = mySession.getDebugProcess();
+        node = createInfoMessage(tree, debugProcess.getCurrentStateMessage(), debugProcess.getCurrentStateHyperlinkListener());
       }
       tree.setRoot(node, true);
     }
   }
-
-  private void disposeTreeRestorer() {
-    if (myTreeRestorer != null) {
-      myTreeRestorer.dispose();
-      myTreeRestorer = null;
-    }
-  }
-
-  public XDebuggerTree getTree() {
-    return myDebuggerTreePanel.getTree();
-  }
-
-  public JComponent getPanel() {
-    return myDebuggerTreePanel.getMainPanel();
-  }
-
-  @Override
-  public void dispose() {
-    disposeTreeRestorer();
-    DnDManager.getInstance().unregisterSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
-    super.dispose();
-  }
 }
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
new file mode 100644
index 0000000..33a1639
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
@@ -0,0 +1,88 @@
+/*
+ * 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.xdebugger.impl.frame;
+
+import com.intellij.ide.dnd.DnDManager;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.project.Project;
+import com.intellij.xdebugger.XDebuggerBundle;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import com.intellij.xdebugger.frame.XStackFrame;
+import com.intellij.xdebugger.impl.actions.XDebuggerActions;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeRestorer;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XStackFrameNode;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * @author nik
+ */
+public abstract class XVariablesViewBase implements Disposable {
+  protected final XDebuggerTreePanel myDebuggerTreePanel;
+  private XDebuggerTreeState myTreeState;
+  private Object myFrameEqualityObject;
+  private XDebuggerTreeRestorer myTreeRestorer;
+
+  protected XVariablesViewBase(@NotNull Project project, @NotNull XDebuggerEditorsProvider editorsProvider, @Nullable XValueMarkers<?, ?> markers) {
+    myDebuggerTreePanel = new XDebuggerTreePanel(project, editorsProvider, this, null, XDebuggerActions.VARIABLES_TREE_POPUP_GROUP, markers);
+    myDebuggerTreePanel.getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.variables.not.available"));
+    DnDManager.getInstance().registerSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
+  }
+
+  protected void buildTreeAndRestoreState(@NotNull XStackFrame stackFrame) {
+    XDebuggerTree tree = myDebuggerTreePanel.getTree();
+    tree.setSourcePosition(stackFrame.getSourcePosition());
+    tree.setRoot(new XStackFrameNode(tree, stackFrame), false);
+    Object newEqualityObject = stackFrame.getEqualityObject();
+    if (myFrameEqualityObject != null && newEqualityObject != null && myFrameEqualityObject.equals(newEqualityObject)
+        && myTreeState != null) {
+      disposeTreeRestorer();
+      myTreeRestorer = myTreeState.restoreState(tree);
+    }
+  }
+
+  protected void saveCurrentTreeState(@Nullable XStackFrame stackFrame) {
+    disposeTreeRestorer();
+    myFrameEqualityObject = stackFrame != null ? stackFrame.getEqualityObject() : null;
+    myTreeState = XDebuggerTreeState.saveState(myDebuggerTreePanel.getTree());
+  }
+
+  private void disposeTreeRestorer() {
+    if (myTreeRestorer != null) {
+      myTreeRestorer.dispose();
+      myTreeRestorer = null;
+    }
+  }
+
+  public XDebuggerTree getTree() {
+    return myDebuggerTreePanel.getTree();
+  }
+
+  public JComponent getPanel() {
+    return myDebuggerTreePanel.getMainPanel();
+  }
+
+  @Override
+  public void dispose() {
+    disposeTreeRestorer();
+    DnDManager.getInstance().unregisterSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
+  }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
index 557d3fc..48defd3 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
@@ -19,9 +19,7 @@
 import com.intellij.ide.dnd.DnDEvent;
 import com.intellij.ide.dnd.DnDManager;
 import com.intellij.ide.dnd.DnDNativeTarget;
-import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.*;
-import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.SystemInfo;
 import com.intellij.ui.AnActionButton;
 import com.intellij.ui.AnActionButtonRunnable;
@@ -56,18 +54,17 @@
 /**
  * @author nik
  */
-public class XWatchesViewImpl extends XDebugViewBase implements DnDNativeTarget, XWatchesView {
+public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugView {
   private final XDebuggerTreePanel myTreePanel;
   private XDebuggerTreeState myTreeState;
   private XDebuggerTreeRestorer myTreeRestorer;
   private final WatchesRootNode myRootNode;
+  @NotNull private final XDebugSession mySession;
   private final XDebugSessionData mySessionData;
   private final JPanel myDecoratedPanel;
 
-  public XWatchesViewImpl(@NotNull final XDebugSession session,
-                          @NotNull final Disposable parentDisposable,
-                          final XDebugSessionData sessionData) {
-    super(session, parentDisposable);
+  public XWatchesViewImpl(@NotNull final XDebugSession session, final @NotNull XDebugSessionData sessionData) {
+    mySession = session;
     mySessionData = sessionData;
     myTreePanel = new XDebuggerTreePanel(session.getProject(), session.getDebugProcess().getEditorsProvider(), this, null,
                                          XDebuggerActions.WATCHES_TREE_POPUP_GROUP, ((XDebugSessionImpl)session).getValueMarkers());
@@ -82,12 +79,6 @@
     actionManager.getAction(XDebuggerActions.XEDIT_WATCH).registerCustomShortcutSet(f2Shortcut, tree);
 
     DnDManager.getInstance().registerTarget(this, tree);
-    Disposer.register(parentDisposable, new Disposable() {
-      @Override
-      public void dispose() {
-        DnDManager.getInstance().unregisterTarget(XWatchesViewImpl.this, myTreePanel.getTree());
-      }
-    });
     myRootNode = new WatchesRootNode(tree, session, this, sessionData.getWatchExpressions());
     tree.setRoot(myRootNode, false);
 
@@ -115,6 +106,11 @@
 
   }
 
+  @Override
+  public void dispose() {
+    DnDManager.getInstance().unregisterTarget(this, myTreePanel.getTree());
+  }
+
   private void executeAction(final String watch) {
     AnAction action = ActionManager.getInstance().getAction(watch);
     Presentation presentation = action.getTemplatePresentation().clone();
@@ -133,7 +129,7 @@
   }
 
   @Override
-  protected void rebuildView(final SessionEvent event) {
+  public void processSessionEvent(@NotNull final SessionEvent event) {
     XStackFrame stackFrame = mySession.getCurrentStackFrame();
     XDebuggerTree tree = myTreePanel.getTree();
 
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java
index ac556ad..4a40d8a 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java
@@ -31,6 +31,7 @@
 import com.intellij.ui.awt.RelativePoint;
 import com.intellij.xdebugger.XDebuggerManager;
 import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.XBreakpointAdapter;
 import com.intellij.xdebugger.breakpoints.XBreakpointListener;
 import com.intellij.xdebugger.breakpoints.XBreakpointManager;
 import com.intellij.xdebugger.frame.XFullValueEvaluator;
@@ -136,17 +137,13 @@
     popup.show(point);
   }
 
-
-
   public static void showXBreakpointEditorBalloon(final Project project,
                                                   @Nullable final Point point,
                                                   final JComponent component,
                                                   final boolean showAllOptions,
                                                   final XBreakpoint breakpoint) {
     final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
-    final XLightBreakpointPropertiesPanel propertiesPanel =
-      new XLightBreakpointPropertiesPanel(project, breakpointManager,
-                                          breakpoint, showAllOptions);
+    final XLightBreakpointPropertiesPanel<XBreakpoint<?>> propertiesPanel = new XLightBreakpointPropertiesPanel<XBreakpoint<?>>(project, breakpointManager, breakpoint, showAllOptions);
 
     final Ref<Balloon> balloonRef = Ref.create(null);
     final Ref<Boolean> isLoading = Ref.create(Boolean.FALSE);
@@ -164,49 +161,32 @@
       }
     });
 
-
     isLoading.set(Boolean.TRUE);
     propertiesPanel.loadProperties();
     isLoading.set(Boolean.FALSE);
 
-    final JComponent mainPanel = propertiesPanel.getMainPanel();
-
-    final Runnable viewBreakpoints = new Runnable() {
+    Runnable showMoreOptions = new Runnable() {
       @Override
       public void run() {
         propertiesPanel.saveProperties();
-        //showXBreakpointEditorBalloon(project, point, component, true, breakpoint);
         BreakpointsDialogFactory.getInstance(project).showDialog(breakpoint);
       }
     };
 
-    final Balloon balloon = showBreakpointEditor(project, mainPanel, breakpoint.getType().getDisplayText(breakpoint), point, component, viewBreakpoints,
-                                                 breakpoint);
+    final JComponent mainPanel = propertiesPanel.getMainPanel();
+    final Balloon balloon = showBreakpointEditor(project, mainPanel, point, component, showMoreOptions, breakpoint);
     balloonRef.set(balloon);
 
-
-    final XBreakpointListener<XBreakpoint<?>> breakpointListener = new XBreakpointListener<XBreakpoint<?>>() {
+    final XBreakpointListener<XBreakpoint<?>> breakpointListener = new XBreakpointAdapter<XBreakpoint<?>>() {
       @Override
-      public void breakpointAdded(@NotNull XBreakpoint<?> breakpoint1) {
-      }
-
-      @Override
-      public void breakpointRemoved(@NotNull XBreakpoint<?> breakpoint1) {
-        if (breakpoint1.equals(breakpoint)) {
+      public void breakpointRemoved(@NotNull XBreakpoint<?> removedBreakpoint) {
+        if (removedBreakpoint.equals(breakpoint)) {
           balloon.hide();
         }
       }
-
-      @Override
-      public void breakpointChanged(@NotNull XBreakpoint<?> breakpoint1) {
-      }
     };
 
-    balloon.addListener(new JBPopupListener() {
-      @Override
-      public void beforeShown(LightweightWindowEvent event) {
-      }
-
+    balloon.addListener(new JBPopupListener.Adapter() {
       @Override
       public void onClosed(LightweightWindowEvent event) {
         propertiesPanel.saveProperties();
@@ -214,12 +194,10 @@
       }
     });
 
-
-
-
     if (point == null) {
       balloon.showInCenterOf(component);
-    } else {
+    }
+    else {
       balloon.show(new RelativePoint(component, point), Balloon.Position.atRight);
     }
 
@@ -233,7 +211,6 @@
   }
 
   public static Balloon showBreakpointEditor(Project project, final JComponent mainPanel,
-                                             final String displayName,
                                              final Point whereToShow,
                                              final JComponent component,
                                              @Nullable final Runnable showMoreOptions, Object breakpoint) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
index 8779d02..e442654 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
@@ -33,7 +33,9 @@
 import com.intellij.openapi.actionSystem.*;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
 import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.ui.AppUIUtil;
 import com.intellij.ui.content.Content;
 import com.intellij.ui.content.tabs.PinToolwindowTabAction;
 import com.intellij.xdebugger.XDebugProcess;
@@ -57,7 +59,7 @@
  */
 public class XDebugSessionTab extends DebuggerSessionTabBase {
   private XWatchesViewImpl myWatchesView;
-  private final List<XDebugViewBase> myViews = new ArrayList<XDebugViewBase>();
+  private final List<XDebugView> myViews = new ArrayList<XDebugView>();
 
   public XDebugSessionTab(@NotNull final Project project, @NotNull final XDebugSessionImpl session, final @Nullable Icon icon,
                           ExecutionEnvironment environment, ProgramRunner runner) {
@@ -72,7 +74,7 @@
   }
 
   private Content createVariablesContent(final XDebugSession session) {
-    final XVariablesView variablesView = new XVariablesView(session, this);
+    final XVariablesView variablesView = new XVariablesView(session);
     myViews.add(variablesView);
     Content result = myUi.createContent(DebuggerContentInfo.VARIABLES_CONTENT, variablesView.getPanel(),
                                         XDebuggerBundle.message("debugger.session.tab.variables.title"),
@@ -86,7 +88,7 @@
   }
 
   private Content createWatchesContent(final XDebugSession session, final XDebugSessionData sessionData) {
-    myWatchesView = new XWatchesViewImpl(session, this, sessionData);
+    myWatchesView = new XWatchesViewImpl(session, sessionData);
     myViews.add(myWatchesView);
     Content watchesContent = myUi.createContent(DebuggerContentInfo.WATCHES_CONTENT, myWatchesView.getMainPanel(),
                                          XDebuggerBundle.message("debugger.session.tab.watches.title"), AllIcons.Debugger.Watches, null);
@@ -96,7 +98,7 @@
   }
 
   private Content createFramesContent(final XDebugSession session) {
-    final XFramesView framesView = new XFramesView(session, this);
+    final XFramesView framesView = new XFramesView(session);
     myViews.add(framesView);
     Content framesContent = myUi.createContent(DebuggerContentInfo.FRAME_CONTENT, framesView.getMainPanel(),
                                                XDebuggerBundle.message("debugger.session.tab.frames.title"), AllIcons.Debugger.Frame, null);
@@ -110,9 +112,14 @@
   }
 
   public void rebuildViews() {
-    for (XDebugViewBase view : myViews) {
-      view.rebuildView();
-    }
+    AppUIUtil.invokeLaterIfProjectAlive(getProject(), new Runnable() {
+      @Override
+      public void run() {
+        for (XDebugView view : myViews) {
+          view.processSessionEvent(XDebugView.SessionEvent.SETTINGS_CHANGED);
+        }
+      }
+    });
   }
 
   public XWatchesView getWatchesView() {
@@ -125,6 +132,11 @@
     myUi.addContent(createFramesContent(session), 0, PlaceInGrid.left, false);
     myUi.addContent(createVariablesContent(session), 0, PlaceInGrid.center, false);
     myUi.addContent(createWatchesContent(session, sessionData), 0, PlaceInGrid.right, false);
+    for (XDebugView view : myViews) {
+      Disposer.register(this, view);
+      session.addSessionListener(new XDebugViewSessionListener(view, getProject()), this);
+    }
+
     myUi.getContentManager().addDataProvider(new DataProvider() {
       @Nullable
       @Override
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java
index da91db3..c84d2a1 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java
@@ -32,7 +32,10 @@
 import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink;
 import com.intellij.xdebugger.impl.actions.XDebuggerActions;
 import com.intellij.xdebugger.impl.frame.XValueMarkers;
-import com.intellij.xdebugger.impl.ui.tree.nodes.*;
+import com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.RestorableStateNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -114,7 +117,13 @@
         }
       }
     });
-    new TreeSpeedSearch(this, SPEED_SEARCH_CONVERTER, true);
+
+    if (Boolean.valueOf(System.getProperty("xdebugger.variablesView.rss"))) {
+      new XDebuggerTreeSpeedSearch(this, SPEED_SEARCH_CONVERTER);
+    }
+    else {
+      new TreeSpeedSearch(this, SPEED_SEARCH_CONVERTER);
+    }
 
     final ActionManager actionManager = ActionManager.getInstance();
     addMouseListener(new PopupHandler() {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeSpeedSearch.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeSpeedSearch.java
new file mode 100644
index 0000000..0bc699a
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeSpeedSearch.java
@@ -0,0 +1,157 @@
+package com.intellij.xdebugger.impl.ui.tree;
+
+import com.intellij.ui.TreeSpeedSearch;
+import com.intellij.util.ObjectUtils;
+import com.intellij.util.containers.Convertor;
+import com.intellij.xdebugger.impl.ui.tree.nodes.RestorableStateNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+import java.util.LinkedList;
+import java.util.List;
+
+class XDebuggerTreeSpeedSearch extends TreeSpeedSearch implements XDebuggerTreeListener {
+  public XDebuggerTreeSpeedSearch(XDebuggerTree tree, Convertor<TreePath, String> toStringConvertor) {
+    super(tree, toStringConvertor, true);
+
+    //((XDebuggerTree)myComponent).addTreeListener(this);
+  }
+
+  @Nullable
+  @Override
+  protected Object findElement(String s) {
+    String string = s.trim();
+
+    XDebuggerTreeNode node = ObjectUtils.tryCast(myComponent.getLastSelectedPathComponent(), XDebuggerTreeNode.class);
+    if (node == null) {
+      node = ObjectUtils.tryCast(myComponent.getModel().getRoot(), XDebuggerTreeNode.class);
+      if (node == null) {
+        return null;
+      }
+    }
+    return findPath(string, node, true);
+  }
+
+  private Object findPath(String string, XDebuggerTreeNode node, boolean checkChildren) {
+    TreePath path = node.getPath();
+    if (isMatchingElement(path, string)) {
+      return path;
+    }
+
+    XDebuggerTreeNode parent = ObjectUtils.tryCast(node.getParent(), XDebuggerTreeNode.class);
+    int nodeIndex;
+    List<? extends TreeNode> parentChildren;
+    if (parent != null) {
+      parentChildren = parent.getChildren();
+      nodeIndex = parentChildren.indexOf(node);
+      if (nodeIndex != -1) {
+        for (int i = nodeIndex + 1; i < parentChildren.size(); i++) {
+          TreePath result = match(parentChildren.get(i), string);
+          if (result != null) {
+            return result;
+          }
+        }
+
+        for (int i = nodeIndex - 1; i >= 0; i--) {
+          TreePath result = match(parentChildren.get(i), string);
+          if (result != null) {
+            return result;
+          }
+        }
+      }
+    }
+    else {
+      nodeIndex = -1;
+      parentChildren = null;
+    }
+
+    // check children up to x level
+    if (checkChildren && !node.isLeaf()) {
+      TreePath result = findInChildren(node, string);
+      if (result != null) {
+        return result;
+      }
+    }
+
+    // check siblings children up to x level
+    if (parent != null) {
+      for (int i = nodeIndex + 1; i < parentChildren.size(); i++) {
+        TreePath result = findInChildren(parentChildren.get(i), string);
+        if (result != null) {
+          return result;
+        }
+      }
+
+      for (int i = nodeIndex - 1; i >= 0; i--) {
+        TreePath result = findInChildren(parentChildren.get(i), string);
+        if (result != null) {
+          return result;
+        }
+      }
+
+      return findPath(string, parent, false);
+    }
+
+    //myComponent.getSelectionPath()
+    return null;
+  }
+
+  private TreePath findInChildren(TreeNode node, String string) {
+    if (node.isLeaf() || !(node instanceof XDebuggerTreeNode)) {
+      return null;
+    }
+
+    LinkedList<XDebuggerTreeNode> queue = new LinkedList<XDebuggerTreeNode>();
+    queue.addLast((XDebuggerTreeNode)node);
+
+    int initialLevel = ((XDebuggerTreeNode)node).getPath().getPathCount();
+
+    while (!queue.isEmpty()) {
+      XDebuggerTreeNode p = queue.removeFirst();
+
+      if ((p.getPath().getPathCount() - initialLevel) > 3) {
+        return null;
+      }
+
+      List<? extends TreeNode> children = p.getChildren();
+      if (children.isEmpty()) {
+        continue;
+      }
+
+      for (TreeNode child : children) {
+        if (!(child instanceof XDebuggerTreeNode)) {
+          continue;
+        }
+
+        TreePath result = match(child, string);
+        if (result != null) {
+          return result;
+        }
+
+        if (!child.isLeaf()) {
+          queue.addLast((XDebuggerTreeNode)child);
+        }
+      }
+    }
+
+    return null;
+  }
+
+  @Nullable
+  private TreePath match(TreeNode node, String string) {
+    TreePath path = node instanceof XDebuggerTreeNode ? ((XDebuggerTreeNode)node).getPath() : null;
+    return isMatchingElement(path, string) ? path : null;
+  }
+
+  @Override
+  public void nodeLoaded(@NotNull RestorableStateNode node, String name) {
+  }
+
+  @Override
+  public void childrenLoaded(@NotNull XDebuggerTreeNode node, @NotNull List<XValueContainerNode<?>> children, boolean last) {
+  }
+}
\ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java
index 94d4093..8f12813 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java
@@ -68,8 +68,9 @@
     myEllipsis = false;
   }
 
+  @NotNull
   @Override
-  protected List<? extends TreeNode> getChildren() {
+  public List<? extends TreeNode> getChildren() {
     return Collections.emptyList();
   }
 
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java
index a7e8393..21ceb24 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java
@@ -76,8 +76,9 @@
     fireNodeStructureChanged();
   }
 
+  @NotNull
   @Override
-  protected List<? extends TreeNode> getChildren() {
+  public List<? extends TreeNode> getChildren() {
     return myChildren;
   }
 
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java
index d60c0683..5af339e 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java
@@ -87,7 +87,8 @@
     return Collections.enumeration(getChildren());
   }
 
-  protected abstract List<? extends TreeNode> getChildren();
+  @NotNull
+  public abstract List<? extends TreeNode> getChildren();
 
   protected void setIcon(final Icon icon) {
     myIcon = icon;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
index 55179e5..a7059a4 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
@@ -195,8 +195,9 @@
     fireNodesInserted(messages);
   }
 
+  @NotNull
   @Override
-  protected List<? extends TreeNode> getChildren() {
+  public List<? extends TreeNode> getChildren() {
     loadChildren();
 
     if (myCachedAllChildren == null) {
diff --git a/plugins/IdeaTestAssistant/src/META-INF/plugin.xml b/plugins/IdeaTestAssistant/src/META-INF/plugin.xml
index cc9c1ad..7f4d9a5 100644
--- a/plugins/IdeaTestAssistant/src/META-INF/plugin.xml
+++ b/plugins/IdeaTestAssistant/src/META-INF/plugin.xml
@@ -10,6 +10,9 @@
             class="com.intellij.testAssistant.NavigateToTestDataAction"
             text="Navigate to testdata" use-shortcut-of="GotoRelated">
     </action>
+    <action id="DumpCleanTestData" internal="true" class="com.intellij.internal.DumpCleanHighlightingTestdataAction">
+      <add-to-group group-id="Internal.Dump"/>
+    </action>
   </actions>
 
   <extensions defaultExtensionNs="com.intellij">
@@ -18,6 +21,7 @@
     <codeInsight.lineMarkerProvider language="Groovy" implementationClass="com.intellij.testAssistant.TestDataLineMarkerProvider"/>
     <fileEditorProvider implementation="com.intellij.testAssistant.TestDataGroupEditorProvider"/>
     <gotoRelatedProvider implementation="com.intellij.testAssistant.TestDataAsRelatedFileProvider"/>
+    <psi.referenceContributor implementation="com.intellij.testAssistant.TestDataReferenceContributor"/>
   </extensions>
 
   <project-components>
diff --git a/plugins/IdeaTestAssistant/src/com/intellij/internal/DumpCleanHighlightingTestdataAction.java b/plugins/IdeaTestAssistant/src/com/intellij/internal/DumpCleanHighlightingTestdataAction.java
new file mode 100644
index 0000000..5260028
--- /dev/null
+++ b/plugins/IdeaTestAssistant/src/com/intellij/internal/DumpCleanHighlightingTestdataAction.java
@@ -0,0 +1,99 @@
+/*
+ * 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.internal;
+
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.testFramework.ExpectedHighlightingData;
+
+import java.io.File;
+import java.io.IOException;
+
+public class DumpCleanHighlightingTestdataAction extends AnAction implements DumbAware {
+  private static final Logger LOG = Logger.getInstance("#" + DumpCleanHighlightingTestdataAction.class);
+
+  public DumpCleanHighlightingTestdataAction() {
+    super("Dump highlighting-markup-free data");
+  }
+
+  @Override
+  public void actionPerformed(final AnActionEvent event) {
+    final DataContext dataContext = event.getDataContext();
+    final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+    final PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(dataContext);
+    if (psiFile != null) {
+      final VirtualFile virtualFile = psiFile.getVirtualFile();
+      if (virtualFile != null) {
+        final Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
+        if (document != null) {
+          final ExpectedHighlightingData data = new ExpectedHighlightingData(document, true, true);
+          data.init();
+        }
+        return;
+      }
+    }
+    final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
+    descriptor.setTitle("Choose Directory");
+    descriptor.setDescription("Directory containing highlighting test data");
+    final VirtualFile dirToProcess = FileChooser.chooseFile(descriptor, project, null);
+    if (dirToProcess != null) {
+      LOG.assertTrue(project != null);
+      final FileChooserDescriptor targetDescriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
+      targetDescriptor.setTitle("Choose Directory");
+      targetDescriptor.setDescription("Directory where highlighting-markup-free copies would be placed");
+      final VirtualFile destinationFolder = FileChooser.chooseFile(targetDescriptor, project, null);
+      if (destinationFolder == dirToProcess) {
+        Messages.showErrorDialog(project, "Source and destination roots should differ", "Reject to Proceed");
+        return;
+      }
+      if (destinationFolder != null) {
+        final File destination = VfsUtilCore.virtualToIoFile(destinationFolder);
+        final VirtualFile[] files = dirToProcess.getChildren();
+        for (VirtualFile virtualFile : files) {
+          final Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
+          if (document != null) {
+            final ExpectedHighlightingData data = new ExpectedHighlightingData(document, true, true);
+            data.init();
+            final File file = new File(destination, virtualFile.getName());
+            try {
+              FileUtil.writeToFile(file, document.getText());
+            }
+            catch (IOException e) {
+              LOG.error(e);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  @Override
+  public void update(AnActionEvent e) {
+    e.getPresentation().setEnabled(CommonDataKeys.PROJECT.getData(e.getDataContext()) != null);
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataLineMarkerProvider.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataLineMarkerProvider.java
index 4f881e6..81d7543 100644
--- a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataLineMarkerProvider.java
+++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataLineMarkerProvider.java
@@ -38,6 +38,10 @@
  * @author yole
  */
 public class TestDataLineMarkerProvider implements LineMarkerProvider {
+  public static final String TEST_DATA_PATH_ANNOTATION_QUALIFIED_NAME = "com.intellij.testFramework.TestDataPath";
+  public static final String CONTENT_ROOT_VARIABLE = "$CONTENT_ROOT";
+  public static final String PROJECT_ROOT_VARIABLE = "$PROJECT_ROOT";
+
   public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
     if (ApplicationManager.getApplication().isUnitTestMode()) {
       return null;
@@ -80,7 +84,8 @@
 
   @Nullable
   public static String getTestDataBasePath(PsiClass psiClass) {
-    final PsiAnnotation annotation = AnnotationUtil.findAnnotationInHierarchy(psiClass, Collections.singleton("com.intellij.testFramework.TestDataPath"));
+    final PsiAnnotation annotation = AnnotationUtil.findAnnotationInHierarchy(psiClass,
+                                                                              Collections.singleton(TEST_DATA_PATH_ANNOTATION_QUALIFIED_NAME));
     if (annotation != null) {
       final PsiAnnotationMemberValue value = annotation.findAttributeValue(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME);
       if (value instanceof PsiExpression) {
@@ -89,7 +94,7 @@
         final Object constantValue = evaluationHelper.computeConstantExpression(value, false);
         if (constantValue instanceof String) {
           String path = (String) constantValue;
-          if (path.contains("$CONTENT_ROOT")) {
+          if (path.contains(CONTENT_ROOT_VARIABLE)) {
             final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
             final VirtualFile file = psiClass.getContainingFile().getVirtualFile();
             if (file == null) {
@@ -97,14 +102,14 @@
             }
             final VirtualFile contentRoot = fileIndex.getContentRootForFile(file);
             if (contentRoot == null) return null;
-            path = path.replace("$CONTENT_ROOT", contentRoot.getPath());
+            path = path.replace(CONTENT_ROOT_VARIABLE, contentRoot.getPath());
           }
-          if (path.contains("$PROJECT_ROOT")) {
+          if (path.contains(PROJECT_ROOT_VARIABLE)) {
             final VirtualFile baseDir = project.getBaseDir();
             if (baseDir == null) {
               return null;
             }
-            path = path.replace("$PROJECT_ROOT", baseDir.getPath());
+            path = path.replace(PROJECT_ROOT_VARIABLE, baseDir.getPath());
           }
           return path;
         }
diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceCollector.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceCollector.java
index ad7a448..3ee1864 100644
--- a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceCollector.java
+++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceCollector.java
@@ -23,12 +23,14 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.io.File;
 import java.util.*;
 
 /**
  * @author yole
  */
 public class TestDataReferenceCollector {
+  private static final String TEST_DATA_FILE_ANNOTATION_QUALIFIED_NAME = "com.intellij.testFramework.TestDataFile";
   private final String myTestDataPath;
   private final String myTestName;
   private final List<String> myLogMessages = new ArrayList<String>();
@@ -36,6 +38,9 @@
   private boolean myFoundTestDataParameters = false;
 
   public TestDataReferenceCollector(@Nullable String testDataPath, String testName) {
+    if (StringUtil.isNotEmpty(testDataPath) && StringUtil.endsWithChar(testDataPath, File.separatorChar)) {
+      testDataPath += File.separatorChar;
+    }
     myTestDataPath = testDataPath;
     myTestName = testName;
   }
@@ -80,7 +85,7 @@
           for (int i = 0, psiParametersLength = psiParameters.length; i < psiParametersLength; i++) {
             PsiParameter psiParameter = psiParameters[i];
             final PsiModifierList modifierList = psiParameter.getModifierList();
-            if (modifierList != null && modifierList.findAnnotation("com.intellij.testFramework.TestDataFile") != null) {
+            if (modifierList != null && modifierList.findAnnotation(TEST_DATA_FILE_ANNOTATION_QUALIFIED_NAME) != null) {
               myFoundTestDataParameters = true;
               processCallArgument(expression, argumentMap, result, i);
               haveAnnotatedParameters = true;
@@ -152,7 +157,6 @@
         if (initializer != null) {
           return evaluate(initializer, arguments);
         }
-
       }
     }
     else if (expression instanceof PsiMethodCallExpression) {
diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceContributor.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceContributor.java
new file mode 100644
index 0000000..28de8d3
--- /dev/null
+++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceContributor.java
@@ -0,0 +1,172 @@
+/*
+ * 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.testAssistant;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileInfoManager;
+import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
+import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
+import com.intellij.util.ProcessingContext;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import static com.intellij.patterns.PsiJavaPatterns.literalExpression;
+import static com.intellij.testAssistant.TestDataLineMarkerProvider.*;
+
+/**
+ * User: zolotov
+ * Date: 9/20/13
+ */
+public class TestDataReferenceContributor extends PsiReferenceContributor {
+  @Override
+  public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+    registrar.registerReferenceProvider(literalExpression().annotationParam(TEST_DATA_PATH_ANNOTATION_QUALIFIED_NAME),
+                                        new TestDataReferenceProvider());
+  }
+
+  private static class TestDataReferenceProvider extends PsiReferenceProvider {
+    @NotNull
+    @Override
+    public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull final ProcessingContext context) {
+      final TestDataReferenceSet referenceSet = new TestDataReferenceSet(element);
+      referenceSet.addCustomization(FileReferenceSet.DEFAULT_PATH_EVALUATOR_OPTION, FileReferenceSet.ABSOLUTE_TOP_LEVEL);
+      return referenceSet.getAllReferences();
+    }
+  }
+
+  private static class TestDataReferenceSet extends FileReferenceSet {
+    public TestDataReferenceSet(@NotNull PsiElement element) {
+      super(element);
+    }
+
+    @Override
+    public boolean isEmptyPathAllowed() {
+      return false;
+    }
+
+    @Override
+    public boolean isAbsolutePathReference() {
+      return super.isAbsolutePathReference() || StringUtil.startsWithChar(getPathString(), '$');
+    }
+
+    @Override
+    public FileReference createFileReference(TextRange range, int index, String text) {
+      return new TestDataReference(this, range, index, text);
+    }
+
+    @NotNull
+    @Override
+    public Collection<PsiFileSystemItem> computeDefaultContexts() {
+      final VirtualFile localSystemRoot = LocalFileSystem.getInstance().getRoot();
+      final PsiManager psiManager = PsiManager.getInstance(getElement().getProject());
+      final PsiDirectory psiRoot = psiManager.findDirectory(localSystemRoot);
+      if (psiRoot != null) {
+        return Collections.<PsiFileSystemItem>singleton(psiRoot);
+      }
+      return super.computeDefaultContexts();
+    }
+
+    @Override
+    protected Condition<PsiFileSystemItem> getReferenceCompletionFilter() {
+      return DIRECTORY_FILTER;
+    }
+  }
+
+  public static class TestDataReference extends FileReference {
+    public TestDataReference(@NotNull FileReferenceSet fileReferenceSet, TextRange range, int index, String text) {
+      super(fileReferenceSet, range, index, text);
+    }
+
+    @NotNull
+    @Override
+    public Object[] getVariants() {
+      if (getIndex() == 0 && !StringUtil.startsWithChar(getFileReferenceSet().getPathString(), '/')) {
+        Collection<Object> variants = ContainerUtil.newHashSet(super.getVariants());
+        final PsiDirectory projectPsiRoot = getProjectPsiRoot();
+        if (projectPsiRoot != null) {
+          variants.add(FileInfoManager.getFileLookupItem(projectPsiRoot, PROJECT_ROOT_VARIABLE, projectPsiRoot.getIcon(0))
+                         .withTypeText(projectPsiRoot.getVirtualFile().getPath(), true));
+        }
+
+        final PsiDirectory contentPsiRoot = getContentPsiRoot();
+        if (contentPsiRoot != null) {
+          variants.add(FileInfoManager.getFileLookupItem(contentPsiRoot, CONTENT_ROOT_VARIABLE, contentPsiRoot.getIcon(0))
+                         .withTypeText(contentPsiRoot.getVirtualFile().getPath(), true));
+        }
+        return variants.toArray(new Object[variants.size()]);
+      }
+      return super.getVariants();
+    }
+
+    @NotNull
+    @Override
+    protected ResolveResult[] innerResolve(boolean caseSensitive) {
+      if (getIndex() == 0 && StringUtil.startsWithChar(getText(), '$')) {
+        if (PROJECT_ROOT_VARIABLE.equals(getText())) {
+          final PsiDirectory projectPsiRoot = getProjectPsiRoot();
+          if (projectPsiRoot != null) {
+            return new ResolveResult[]{new PsiElementResolveResult(projectPsiRoot)};
+          }
+        }
+        else if (CONTENT_ROOT_VARIABLE.equals(getText())) {
+          final PsiDirectory contentPsiRoot = getContentPsiRoot();
+          if (contentPsiRoot != null) {
+            return new ResolveResult[]{new PsiElementResolveResult(contentPsiRoot)};
+          }
+        }
+      }
+      return super.innerResolve(caseSensitive);
+    }
+
+    @Nullable
+    private PsiDirectory getProjectPsiRoot() {
+      final Project project = getElement().getProject();
+      final VirtualFile projectDir = project.getBaseDir();
+      if (projectDir != null) {
+        final PsiManager psiManager = PsiManager.getInstance(project);
+        return psiManager.findDirectory(projectDir);
+      }
+      return null;
+    }
+
+    @Nullable
+    private PsiDirectory getContentPsiRoot() {
+      final Project project = getElement().getProject();
+      final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+      final VirtualFile file = getElement().getContainingFile().getOriginalFile().getVirtualFile();
+      if (file != null) {
+        final VirtualFile contentRoot = fileIndex.getContentRootForFile(file);
+        if (contentRoot != null) {
+          final PsiManager psiManager = PsiManager.getInstance(project);
+          return psiManager.findDirectory(contentRoot);
+        }
+      }
+      return null;
+    }
+  }
+}
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ContentRoot.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ContentRoot.java
new file mode 100644
index 0000000..220113d
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ContentRoot.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$C<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+  protected void doTest() {
+    configureByFile(getTestName(true) + ".java");
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ContentRoot_after.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ContentRoot_after.java
new file mode 100644
index 0000000..12ef5ce
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ContentRoot_after.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$CONTENT_ROOT<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+  protected void doTest() {
+    configureByFile(getTestName(true) + ".java");
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ProjectRoot.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ProjectRoot.java
new file mode 100644
index 0000000..2480621
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ProjectRoot.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$P<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+  protected void doTest() {
+    configureByFile(getTestName(true) + ".java");
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ProjectRoot_after.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ProjectRoot_after.java
new file mode 100644
index 0000000..73a9221
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ProjectRoot_after.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$PROJECT_ROOT<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+  protected void doTest() {
+    configureByFile(getTestName(true) + ".java");
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterContentRoot.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterContentRoot.java
new file mode 100644
index 0000000..409e8da
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterContentRoot.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$CONTENT_ROOT/c<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+  protected void doTest() {
+    configureByFile(getTestName(true) + ".java");
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterContentRoot_after.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterContentRoot_after.java
new file mode 100644
index 0000000..a3fff23
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterContentRoot_after.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$CONTENT_ROOT/contentRootSubdir<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+  protected void doTest() {
+    configureByFile(getTestName(true) + ".java");
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterProjectRoot.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterProjectRoot.java
new file mode 100644
index 0000000..397ed2e
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterProjectRoot.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$PROJECT_ROOT/pro<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+  protected void doTest() {
+    configureByFile(getTestName(true) + ".java");
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterProjectRoot_after.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterProjectRoot_after.java
new file mode 100644
index 0000000..0e4ed3d4
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterProjectRoot_after.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$PROJECT_ROOT/projectSubdir<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+  protected void doTest() {
+    configureByFile(getTestName(true) + ".java");
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ContentRootReference.java b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ContentRootReference.java
new file mode 100644
index 0000000..d176a36
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ContentRootReference.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$C<caret>ONTENT_ROOT/path")
+class ATest extends LightCodeInsightFixtureTestCase {
+  protected void doTest() {
+    configureByFile(getTestName(true) + ".java");
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ProjectRootReference.java b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ProjectRootReference.java
new file mode 100644
index 0000000..ccaf4a6
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ProjectRootReference.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$P<caret>ROJECT_ROOT/path")
+class ATest extends LightCodeInsightFixtureTestCase {
+  protected void doTest() {
+    configureByFile(getTestName(true) + ".java");
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ReferencesAfterContentRoot.java b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ReferencesAfterContentRoot.java
new file mode 100644
index 0000000..283cd36
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ReferencesAfterContentRoot.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$CONTENT_ROOT/contentRootSub<caret>dir")
+class ATest extends LightCodeInsightFixtureTestCase {
+  protected void doTest() {
+    configureByFile(getTestName(true) + ".java");
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ReferencesAfterProjectRoot.java b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ReferencesAfterProjectRoot.java
new file mode 100644
index 0000000..f718ad8
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ReferencesAfterProjectRoot.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$PROJECT_ROOT/pro<caret>jectSubdir/")
+class ATest extends LightCodeInsightFixtureTestCase {
+  protected void doTest() {
+    configureByFile(getTestName(true) + ".java");
+  }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathCompletionTest.java b/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathCompletionTest.java
new file mode 100644
index 0000000..9b0356c
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathCompletionTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.testAssistant;
+
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.testFramework.TestDataPath;
+
+/**
+ * User: zolotov
+ * Date: 9/23/13
+ */
+@TestDataPath("$CONTENT_ROOT/testData/completionTestDataPath")
+public class TestDataPathCompletionTest extends TestDataPathTestCase {
+  public void testProjectRoot() throws Exception {
+    doTest();
+  }
+
+  public void testReferencesAfterProjectRoot() throws Exception {
+    doTest();
+  }
+
+  public void testContentRoot() throws Exception {
+    doTest();
+  }
+
+  public void testReferencesAfterContentRoot() throws Exception {
+    doTest();
+  }
+
+  private void doTest() {
+    myFixture.configureByFile(getTestName(false) + ".java");
+    myFixture.completeBasic();
+    myFixture.checkResultByFile(getTestName(false) + "_after.java");
+  }
+
+  @Override
+  protected String getBasePath() {
+    return PluginPathManager.getPluginHomePathRelative("IdeaTestAssistant") + "/testData/completeTestDataPath";
+  }
+}
diff --git a/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathResolvingTest.java b/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathResolvingTest.java
new file mode 100644
index 0000000..7fbd5aa
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathResolvingTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.testAssistant;
+
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.psi.PsiFileSystemItem;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.PsiReference;
+import com.intellij.testFramework.TestDataPath;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * User: zolotov
+ * Date: 9/23/13
+ */
+@TestDataPath("$CONTENT_ROOT/testData/resolveTestDataPath/")
+public class TestDataPathResolvingTest extends TestDataPathTestCase {
+  public void testProjectRootReference() throws Exception {
+    doTest(PsiManager.getInstance(myFixture.getProject()).findDirectory(myFixture.getProject().getBaseDir()));
+  }
+
+  public void testReferencesAfterProjectRoot() throws Exception {
+    doTest(PsiManager.getInstance(myFixture.getProject()).findDirectory(myProjectSubdir));
+  }
+
+  public void testContentRootReference() throws Exception {
+    doTest(PsiManager.getInstance(myFixture.getProject()).findDirectory(myContentRoot));
+  }
+
+  public void testReferencesAfterContentRoot() throws Exception {
+    doTest(PsiManager.getInstance(myFixture.getProject()).findDirectory(myContentRootSubdir));
+  }
+
+  private void doTest(@Nullable PsiFileSystemItem expectedResolve) {
+    myFixture.configureByFile(getTestName(false) + ".java");
+    final PsiReference referenceAt = myFixture.getFile().findReferenceAt(myFixture.getEditor().getCaretModel().getOffset());
+    assertNotNull(referenceAt);
+    assertEquals(expectedResolve, referenceAt.resolve());
+  }
+
+  @Override
+  protected String getBasePath() {
+    return PluginPathManager.getPluginHomePathRelative("IdeaTestAssistant") + "/testData/resolveTestDataPath";
+  }
+}
diff --git a/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathTestCase.java b/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathTestCase.java
new file mode 100644
index 0000000..864985b
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathTestCase.java
@@ -0,0 +1,56 @@
+/*
+ * 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.testAssistant;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
+import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
+
+import java.io.IOException;
+
+/**
+ * User: zolotov
+ * Date: 9/23/13
+ */
+abstract public class TestDataPathTestCase extends JavaCodeInsightFixtureTestCase {
+  protected VirtualFile myContentRoot;
+  protected VirtualFile myContentRootSubdir;
+  protected VirtualFile myProjectSubdir;
+
+  public void setUp() throws Exception {
+    super.setUp();
+    myContentRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(myFixture.getTempDirPath());
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      @Override
+      public void run() {
+        try {
+          myProjectSubdir = myFixture.getProject().getBaseDir().createChildDirectory(this, "projectSubdir");
+          myContentRootSubdir = myContentRoot.createChildDirectory(this, "contentRootSubdir");
+        }
+        catch (IOException e) {
+          throw new RuntimeException(e);
+        }
+      }
+    });
+  }
+
+  @Override
+  protected void tuneFixture(JavaModuleFixtureBuilder moduleBuilder) throws Exception {
+    moduleBuilder.addContentRoot(myFixture.getTempDirPath());
+  }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
index 44b5be3..6abd21a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
@@ -1117,6 +1117,10 @@
                      key="absolute.alignment.in.user.interface.display.name" groupBundle="messages.InspectionsBundle"
                      groupKey="group.names.internationalization.issues" enabledByDefault="false" level="WARNING"
                      implementationClass="com.siyeh.ig.internationalization.AbsoluteAlignmentInUserInterfaceInspection"/>
+    <localInspection language="JAVA" shortName="UnnecessaryUnicodeEscape" bundle="com.siyeh.InspectionGadgetsBundle"
+                     key="unnecessary.unicode.escape.display.name" groupBundle="messages.InspectionsBundle"
+                     groupKey="group.names.internationalization.issues" enabledByDefault="false" level="WARNING"
+                     implementationClass="com.siyeh.ig.internationalization.UnnecessaryUnicodeEscapeInspection"/>
 
     <!--group.names.j2me.issues-->
     <localInspection language="JAVA" shortName="AbstractClassWithOnlyOneDirectInheritor" bundle="com.siyeh.InspectionGadgetsBundle"
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
index 90800e4..6dc0cb8 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
@@ -2040,4 +2040,6 @@
 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.only.report.multiple.option=Only report methods with multiple boolean parameters
\ No newline at end of file
+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}''
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspection.java
index 8a592c0..8461b1a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspection.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.
@@ -60,60 +60,76 @@
       final PsiParameter[] parameters = parameterList.getParameters();
       final PsiParameter parameter = parameters[0];
       final PsiCodeBlock body = method.getBody();
-      if (body == null) {
-        return;
-      }
-      if (isParameterChecked(body, parameter)) {
-        return;
-      }
-      if (isParameterCheckNotNeeded(body)) {
+      if (body == null || isParameterChecked(body, parameter) || isParameterCheckNotNeeded(body, parameter)) {
         return;
       }
       registerMethodError(method);
     }
 
-    private static boolean isParameterCheckNotNeeded(PsiCodeBlock body) {
-      final PsiStatement[] statements = body.getStatements();
-      if (statements.length == 0) {
-        return true;
-      }
-      if (statements.length != 1) {
-        return false;
-      }
-      final PsiStatement statement = statements[0];
-      if (!(statement instanceof PsiReturnStatement)) {
-        return false;
-      }
-      final PsiReturnStatement returnStatement = (PsiReturnStatement)statement;
-      final PsiExpression returnValue = returnStatement.getReturnValue();
-      final Object constant = ExpressionUtils.computeConstantExpression(returnValue);
-      return Boolean.FALSE.equals(constant);
-    }
-
     private static boolean isParameterChecked(PsiCodeBlock body, PsiParameter parameter) {
-      if (usesEqualsBuilderReflectionEquals(body)) {
-        return true;
-      }
       final ParameterClassCheckVisitor visitor = new ParameterClassCheckVisitor(parameter);
       body.accept(visitor);
       return visitor.isChecked();
     }
 
-    private static boolean usesEqualsBuilderReflectionEquals(PsiCodeBlock body) {
+    private static boolean isParameterCheckNotNeeded(PsiCodeBlock body, PsiParameter parameter) {
       final PsiStatement[] statements = body.getStatements();
+      if (statements.length == 0) {
+        return true; // incomplete code
+      }
       if (statements.length != 1) {
         return false;
       }
       final PsiStatement statement = statements[0];
       if (!(statement instanceof PsiReturnStatement)) {
-        return false;
+        return true; // incomplete code
       }
       final PsiReturnStatement returnStatement = (PsiReturnStatement)statement;
       final PsiExpression returnValue = returnStatement.getReturnValue();
-      if (!(returnValue instanceof PsiMethodCallExpression)) {
+      final Object constant = ExpressionUtils.computeConstantExpression(returnValue);
+      if (Boolean.FALSE.equals(constant)) {
+        return true; // incomplete code
+      }
+      if (isEqualsBuilderReflectionEquals(returnValue)) {
+        return true;
+      }
+      if (isIdentityEquals(returnValue, parameter)) {
+        return true;
+      }
+      return false;
+    }
+
+    private static boolean isIdentityEquals(PsiExpression expression, PsiParameter parameter) {
+      if (!(expression instanceof PsiBinaryExpression)) {
         return false;
       }
-      final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)returnValue;
+      final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression;
+      final PsiExpression lhs = binaryExpression.getLOperand();
+      final PsiExpression rhs = binaryExpression.getROperand();
+      return isIdentityEquals(lhs, rhs, parameter) || isIdentityEquals(rhs, lhs, parameter);
+    }
+
+    private static boolean isIdentityEquals(PsiExpression lhs, PsiExpression rhs, PsiParameter parameter) {
+      if (!(lhs instanceof PsiReferenceExpression)) {
+        return false;
+      }
+      final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)lhs;
+      final PsiElement target = referenceExpression.resolve();
+      if (target != parameter) {
+        return false;
+      }
+      if (!(rhs instanceof PsiThisExpression)) {
+        return false;
+      }
+      final PsiThisExpression thisExpression = (PsiThisExpression)rhs;
+      return thisExpression.getQualifier() == null;
+    }
+
+    private static boolean isEqualsBuilderReflectionEquals(PsiExpression expression) {
+      if (!(expression instanceof PsiMethodCallExpression)) {
+        return false;
+      }
+      final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
       final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
       @NonNls final String referenceName = methodExpression.getReferenceName();
       if (!"reflectionEquals".equals(referenceName)) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedRegexInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedRegexInspection.java
index e8e6755..c5c67ce 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedRegexInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedRegexInspection.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.
@@ -15,9 +15,10 @@
  */
 package com.siyeh.ig.bugs;
 
-import com.intellij.psi.*;
-import com.intellij.psi.util.ConstantExpressionUtil;
-import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiExpressionList;
+import com.intellij.psi.PsiMethodCallExpression;
+import com.intellij.psi.PsiReferenceExpression;
 import com.siyeh.InspectionGadgetsBundle;
 import com.siyeh.ig.BaseInspection;
 import com.siyeh.ig.BaseInspectionVisitor;
@@ -60,29 +61,39 @@
   private static class MalformedRegexVisitor extends BaseInspectionVisitor {
 
     @Override
-    public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
-      super.visitMethodCallExpression(expression);
-      final PsiExpressionList argumentList = expression.getArgumentList();
-      if (argumentList == null) {
+    public void visitMethodCallExpression(@NotNull PsiMethodCallExpression methodCallExpression) {
+      super.visitMethodCallExpression(methodCallExpression);
+      if (!MethodCallUtils.isCallToRegexMethod(methodCallExpression)) {
         return;
       }
+      final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
       final PsiExpression[] arguments = argumentList.getExpressions();
       if (arguments.length == 0) {
         return;
       }
-      final PsiExpression argument = arguments[0];
-      if (!ExpressionUtils.hasStringType(argument)) {
+      final PsiExpression firstArgument = arguments[0];
+      if (!ExpressionUtils.hasStringType(firstArgument)) {
         return;
       }
-      if (!PsiUtil.isConstantExpression(argument)) {
-        return;
-      }
-      final PsiType regexType = argument.getType();
-      final String value = (String)ConstantExpressionUtil.computeCastTo(argument, regexType);
+      final String value = (String)ExpressionUtils.computeConstantExpression(firstArgument);
       if (value == null) {
         return;
       }
-      if (!MethodCallUtils.isCallToRegexMethod(expression)) {
+      final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
+      if ("compile".equals(methodExpression.getReferenceName()) && arguments.length == 2) {
+        final PsiExpression secondArgument = arguments[1];
+        final Object flags = ExpressionUtils.computeConstantExpression(secondArgument);
+        if (flags instanceof Integer) {
+          try {
+            Pattern.compile(value, ((Integer)flags).intValue());
+          }
+          catch (PatternSyntaxException e) {
+            registerError(firstArgument, e.getDescription());
+          }
+          catch (NullPointerException e) {
+            registerError(firstArgument);
+          }
+        }
         return;
       }
       //noinspection UnusedCatchParameter,ProhibitedExceptionCaught
@@ -90,10 +101,10 @@
         Pattern.compile(value);
       }
       catch (PatternSyntaxException e) {
-        registerError(argument, e.getDescription());
+        registerError(firstArgument, e.getDescription());
       }
       catch (NullPointerException e) {
-        registerError(argument); // due to a bug in the sun regex code
+        registerError(firstArgument); // due to a bug in the sun regex code
       }
     }
   }
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspectionBase.java
index fe02f96..3a291bd 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspectionBase.java
@@ -36,7 +36,7 @@
   @SuppressWarnings({"PublicField"})
   public final ExternalizableStringSet updateNames =
     new ExternalizableStringSet("add", "clear", "drainTo", "insert", "load", "offer", "poll", "push", "put", "remove", "replace",
-                                "retain", "set", "take");
+                                "retain", "set", "take", "compute");
 
   private static boolean isEmptyCollectionInitializer(PsiExpression initializer) {
     if (!(initializer instanceof PsiNewExpression)) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
index 435dd24..550374f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.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.
@@ -140,7 +140,7 @@
     @Override
     public void visitVariable(@NotNull PsiVariable variable) {
       super.visitVariable(variable);
-      if (!(variable instanceof PsiLocalVariable)) {
+      if (!(variable instanceof PsiLocalVariable) || variable instanceof PsiResourceVariable) {
         return;
       }
       final PsiExpression initializer = variable.getInitializer();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspection.java
new file mode 100644
index 0000000..4e0176e
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspection.java
@@ -0,0 +1,166 @@
+/*
+ * 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.internationalization;
+
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.lang.injection.InjectedLanguageManager;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+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;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.*;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class UnnecessaryUnicodeEscapeInspection extends BaseInspection {
+  @Nls
+  @NotNull
+  @Override
+  public String getDisplayName() {
+    return InspectionGadgetsBundle.message("unnecessary.unicode.escape.display.name");
+  }
+
+  @NotNull
+  @Override
+  protected String buildErrorString(Object... infos) {
+    final Character c = (Character)infos[0];
+    return InspectionGadgetsBundle.message("unnecessary.unicode.escape.problem.descriptor", c);
+  }
+
+  @Nullable
+  @Override
+  protected InspectionGadgetsFix buildFix(Object... infos) {
+    return new UnnecessaryUnicodeEscapeFix(((Character) infos[0]).charValue());
+  }
+
+  private static class UnnecessaryUnicodeEscapeFix extends InspectionGadgetsFix {
+
+    private final char c;
+
+    public UnnecessaryUnicodeEscapeFix(char c) {
+      this.c = c;
+    }
+
+    @NotNull
+    @Override
+    public String getName() {
+      return "Replace with '" + c + "'";
+    }
+
+    @NotNull
+    @Override
+    public String getFamilyName() {
+      return "Replace with character";
+    }
+
+    @Override
+    protected void doFix(Project project, ProblemDescriptor descriptor) {
+      final TextRange textRange = descriptor.getTextRangeInElement();
+      final PsiElement element = descriptor.getPsiElement();
+      if (!(element instanceof PsiFile)) {
+        return;
+      }
+      final PsiFile file = (PsiFile)element;
+      final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
+      if (document == null) {
+        return;
+      }
+      document.replaceString(textRange.getStartOffset(), textRange.getEndOffset(), String.valueOf(c));
+    }
+  }
+
+  @Override
+  public BaseInspectionVisitor buildVisitor() {
+    return new UnnecessaryUnicodeEscapeVisitor();
+  }
+
+  private static class UnnecessaryUnicodeEscapeVisitor extends BaseInspectionVisitor {
+
+    @Override
+    public void visitFile(PsiFile file) {
+      super.visitFile(file);
+      if (InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file) || !file.isPhysical()) {
+        return;
+      }
+      final VirtualFile virtualFile = file.getVirtualFile();
+      final String text = file.getText();
+      final Charset charset = LoadTextUtil.extractCharsetFromFileContent(file.getProject(), virtualFile, text);
+      final CharsetEncoder encoder = charset.newEncoder().onUnmappableCharacter(CodingErrorAction.REPORT);
+      final CharBuffer charBuffer = CharBuffer.allocate(1);
+      final ByteBuffer byteBuffer = ByteBuffer.allocate(10);
+      final int length = text.length();
+      for (int i = 0; i < length; i++) {
+        final char c = text.charAt(i);
+        if (c != '\\') {
+          continue;
+        }
+        boolean isEscape = true;
+        int previousChar = i - 1;
+        while (previousChar >= 0 && text.charAt(previousChar) == '\\') {
+          isEscape = !isEscape;
+          previousChar--;
+        }
+        if (!isEscape) {
+          continue;
+        }
+        int nextChar = i;
+        do {
+          nextChar++;
+          if (nextChar >= length) {
+            break;
+          }
+        }
+        while (text.charAt(nextChar) == 'u'); // \uuuu0061 is a legal unicode escape
+        if (nextChar == i + 1 || nextChar + 3 >= length) {
+          continue;
+        }
+        if (StringUtil.isHexDigit(text.charAt(nextChar)) &&
+            StringUtil.isHexDigit(text.charAt(nextChar + 1)) &&
+            StringUtil.isHexDigit(text.charAt(nextChar + 2)) &&
+            StringUtil.isHexDigit(text.charAt(nextChar + 3))) {
+          final int escapeEnd = nextChar + 4;
+          final char d = (char)Integer.parseInt(text.substring(nextChar, escapeEnd), 16);
+          if (Character.isISOControl(d)) {
+            continue;
+          }
+          byteBuffer.clear();
+          charBuffer.clear();
+          charBuffer.put(d).rewind();
+          final CoderResult coderResult = encoder.encode(charBuffer, byteBuffer, true);
+          if (!coderResult.isUnmappable()) {
+            registerErrorAtOffset(file, i, escapeEnd - i, Character.valueOf(d));
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/HtmlTagCanBeJavadocTagInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/HtmlTagCanBeJavadocTagInspection.java
index f8dace6..e6d4648 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/HtmlTagCanBeJavadocTagInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/HtmlTagCanBeJavadocTagInspection.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011-2012 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.
@@ -16,12 +16,13 @@
 package com.siyeh.ig.javadoc;
 
 import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.JavaDocTokenType;
-import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiDocumentManager;
 import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiElementFactory;
-import com.intellij.psi.javadoc.PsiDocComment;
+import com.intellij.psi.PsiFile;
 import com.intellij.psi.javadoc.PsiDocToken;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.util.PsiTreeUtil;
@@ -52,23 +53,15 @@
 
   @Override
   protected InspectionGadgetsFix buildFix(Object... infos) {
-    final int offset = ((Integer)infos[0]).intValue();
-    return new HtmlTagCanBeJavaDocTagFix(offset);
+    return new HtmlTagCanBeJavaDocTagFix();
   }
 
   private static class HtmlTagCanBeJavaDocTagFix extends InspectionGadgetsFix {
 
-    private final int startIndex;
-
-    public HtmlTagCanBeJavaDocTagFix(int startIndex) {
-      this.startIndex = startIndex;
-    }
-
     @Override
     @NotNull
     public String getName() {
-      return InspectionGadgetsBundle.message(
-        "html.tag.can.be.javadoc.tag.quickfix");
+      return InspectionGadgetsBundle.message("html.tag.can.be.javadoc.tag.quickfix");
     }
     @Override
     @NotNull
@@ -78,60 +71,55 @@
 
     @Override
     protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
-      final PsiElement element = descriptor.getPsiElement();
-      final PsiDocComment comment = PsiTreeUtil.getParentOfType(element, PsiDocComment.class);
-      if (comment == null) {
+      final TextRange range = descriptor.getTextRangeInElement();
+      PsiElement element = descriptor.getPsiElement();
+      final PsiFile file = PsiTreeUtil.getParentOfType(element, PsiFile.class);
+      if (file == null) {
         return;
       }
-      @NonNls final StringBuilder newCommentText = new StringBuilder();
-      buildNewCommentText(comment, element, false, newCommentText);
-      final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
-      final PsiDocComment newComment = factory.createDocCommentFromText(newCommentText.toString());
-      comment.replace(newComment);
+      final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
+      if (document == null) {
+        return;
+      }
+      final int startOffset = range.getStartOffset();
+      final int replaceStartOffset = element.getTextOffset() + startOffset;
+      final int endOffset = range.getEndOffset();
+      @NonNls String text = element.getText();
+      if (!"<code>".equals(text.substring(startOffset, endOffset))) {
+        return;
+      }
+      @NonNls final StringBuilder newCommentText = new StringBuilder("{@code");
+      int endTag = text.indexOf("</code>", startOffset);
+      boolean first = true;
+      while (endTag < 0) {
+        appendElementText(text, endOffset, text.length(), first, newCommentText);
+        first = false;
+        element = element.getNextSibling();
+        if (element == null) return;
+        text = element.getText();
+        endTag = text.indexOf("</code>");
+      }
+      appendElementText(text, endOffset, endTag, first, newCommentText);
+      newCommentText.append('}');
+      final int replaceEndOffset = element.getTextOffset() + endTag + 7;
+      final String oldText = document.getText(new TextRange(replaceStartOffset, replaceEndOffset));
+      if (!oldText.startsWith("<code>") || !oldText.endsWith("</code>")) { // sanity check
+        return;
+      }
+      document.replaceString(replaceStartOffset, replaceEndOffset, newCommentText);
     }
 
-    private boolean buildNewCommentText(PsiElement element, PsiElement elementToReplace, boolean missingEndTag,
-                                        @NonNls StringBuilder newCommentText) {
-      final PsiElement[] children = element.getChildren();
-      if (children.length != 0) {
-        for (PsiElement child : children) {
-          missingEndTag = buildNewCommentText(child, elementToReplace, missingEndTag, newCommentText);
+    private static void appendElementText(String text, int startOffset, int endOffset, boolean first, StringBuilder out) {
+      if (first) {
+        final String substring = text.substring(startOffset, endOffset);
+        if (!substring.isEmpty() && !Character.isWhitespace(substring.charAt(0))) {
+          out.append(' ');
         }
-        return missingEndTag;
-      }
-      @NonNls final String text = element.getText();
-      if (element != elementToReplace) {
-        if (missingEndTag) {
-          final int endIndex = text.indexOf("</code>");
-          if (endIndex >= 0) {
-            final String codeText = text.substring(0, endIndex);
-            newCommentText.append(codeText);
-            newCommentText.append('}');
-            newCommentText.append(text.substring(endIndex + 7));
-            return false;
-          }
-        }
-        newCommentText.append(text);
+        out.append(substring);
       }
       else {
-        newCommentText.append(text.substring(0, startIndex));
-        newCommentText.append("{@code ");
-        final int endIndex = text.indexOf("</code>", startIndex);
-        if (endIndex >= 0) {
-          final String codeText = text.substring(startIndex + 6, endIndex);
-          newCommentText.append(codeText);
-          //StringUtil.replace(codeText, "}", "&#125;"));
-          newCommentText.append('}');
-          newCommentText.append(text.substring(endIndex + 7));
-        }
-        else {
-          final String codeText = text.substring(startIndex + 6);
-          newCommentText.append(codeText);
-          //StringUtil.replace(codeText, "}", "&#125;"));
-          return true;
-        }
+        out.append(text.substring(0, endOffset));
       }
-      return missingEndTag;
     }
   }
 
@@ -160,14 +148,14 @@
           return;
         }
         if (hasMatchingCloseTag(token, startIndex + 6)) {
-          registerErrorAtOffset(token, startIndex, 6, Integer.valueOf(startIndex));
+          registerErrorAtOffset(token, startIndex, 6);
         }
         startIndex++;
       }
     }
 
     private static boolean hasMatchingCloseTag(PsiElement element, int offset) {
-      final String text = element.getText();
+      @NonNls final String text = element.getText();
       final int endOffset1 = text.indexOf("</code>", offset);
       if (endOffset1 >= 0) {
         final int startOffset1 = text.indexOf("<code>", offset);
@@ -175,7 +163,7 @@
       }
       PsiElement sibling = element.getNextSibling();
       while (sibling != null) {
-        final String text1 = sibling.getText();
+        @NonNls final String text1 = sibling.getText();
         final int endOffset = text1.indexOf("</code>");
         if (endOffset >= 0) {
           final int startOffset = text1.indexOf("<code>");
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java
index 0de37c8..257ab04 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-201@ Bas Leijdekkers
+ * Copyright 2006-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.
@@ -16,6 +16,7 @@
 package com.siyeh.ig.style;
 
 import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
 import com.siyeh.InspectionGadgetsBundle;
 import com.siyeh.ig.BaseInspection;
 import com.siyeh.ig.BaseInspectionVisitor;
@@ -60,11 +61,6 @@
       if (parameterList == null) {
         return;
       }
-      if (parameterList.getTypeArguments().length > 0) {
-        // optimization: reference with type arguments are
-        // definitely not references to fields.
-        return;
-      }
       final PsiElement element = expression.resolve();
       if (!(element instanceof PsiField)) {
         return;
@@ -73,9 +69,13 @@
       if (field.hasModifierProperty(PsiModifier.STATIC)) {
         return;
       }
-      final PsiClass containingClass = field.getContainingClass();
-      if (containingClass instanceof PsiAnonymousClass) {
-        return;
+      final PsiClass fieldClass = field.getContainingClass();
+      if (fieldClass instanceof PsiAnonymousClass) {
+        final PsiClass expressionClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
+        if (expressionClass != null && !expressionClass.equals(fieldClass)) {
+          // qualified this expression not possible for anonymous class
+          return;
+        }
       }
       registerError(expression);
     }
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnicodeEscape.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnicodeEscape.html
new file mode 100644
index 0000000..0cb8778
--- /dev/null
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnicodeEscape.html
@@ -0,0 +1,9 @@
+<html>
+<body>
+Reports unicode escape sequences that are unnecessary, i.e. the file's encoding can handle the character without escaping it.
+Unicode control characters are not reported by this inspection.
+  <!-- tooltip end -->
+<p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/javadoc/html_tag_can_be_javadoc_tag/Second.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/javadoc/html_tag_can_be_javadoc_tag/Second.after.java
index 1added5..8d13805 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igfixes/javadoc/html_tag_can_be_javadoc_tag/Second.after.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/javadoc/html_tag_can_be_javadoc_tag/Second.after.java
@@ -3,7 +3,7 @@
 class Second {
 
   /**
-   * <code></code>{@code }
+   * <code></code>{@code}
    */
   void foo2() {}
 }
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java
index c7519ff..bf0af06 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java
@@ -96,3 +96,9 @@
     return ((Child)o).childField.equals(childField);
   }
 }
+class Six {
+  @Override
+  public boolean equals(Object obj) {
+    return this == obj;
+  }
+}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_regex/MalformedRegex.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_regex/MalformedRegex.java
new file mode 100644
index 0000000..9783f8f
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_regex/MalformedRegex.java
@@ -0,0 +1,12 @@
+import java.util.regex.Pattern;
+
+class MalformedRegex {
+  Pattern BACKSLASH_PATTERN = Pattern.compile("<error descr="Illegal/unsupported escape sequence">\</error>\" , Pattern.LITERAL);
+
+  private static final String ASTERISK = "<error descr="Dangling metacharacter">*</error>";
+
+  public void foo() {
+    "bar".matches(".*");
+    Pattern.compile(<warning descr="Regular expression 'ASTERISK' is malformed: Dangling meta character '*'">ASTERISK</warning>);
+  }
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java
index 529592f..8302df83 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java
@@ -109,4 +109,12 @@
             System.out.println(i);
         }
     }
+
+    void resourceVariable(boolean b) {
+        try (AutoCloseable ac = null) {
+            if (b) {
+                System.out.println(ac);
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/unnecessary_unicode_escape/UnnecessaryUnicodeEscape.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/unnecessary_unicode_escape/UnnecessaryUnicodeEscape.java
new file mode 100644
index 0000000..b258b17
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/unnecessary_unicode_escape/UnnecessaryUnicodeEscape.java
@@ -0,0 +1,6 @@
+package com.siyeh.igtest.internationalization.unnecessary_unicode_escape;
+
+class UnnecessaryUnicodeEscape {
+  // <warning descr="Unicode escape sequence '\uuuuuu0061' can be replaced with 'a'">\uuuuuu0061</warning><warning descr="Unicode escape sequence '\u0062' can be replaced with 'b'">\u0062</warning>
+  // control char & not representable char: \u0010 \u00e4
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java
index 6c7518d..ac24026 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java
@@ -22,4 +22,14 @@
       }
     };
   }
+
+  void simpleAnonymous() {
+    new Object() {
+      String s;
+
+      void foo() {
+        System.out.println(s);
+      }
+    };
+  }
 }
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/expected.xml
index f13588a..aa352ac 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/expected.xml
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/expected.xml
@@ -7,11 +7,17 @@
     <description>Instance field access &lt;code&gt;field&lt;/code&gt; is not qualified with 'this' #loc</description>
   </problem>
 
-
   <problem>
     <file>UnqualifiedFieldAccess.java</file>
     <line>9</line>
     <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Instance field access not qualified with 'this'</problem_class>
     <description>Instance field access &lt;code&gt;field&lt;/code&gt; is not qualified with 'this' #loc</description>
   </problem>
+
+  <problem>
+    <file>UnqualifiedFieldAccess.java</file>
+    <line>31</line>
+    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Instance field access not qualified with 'this'</problem_class>
+    <description>Instance field access &lt;code&gt;s&lt;/code&gt; is not qualified with 'this' #loc</description>
+  </problem>
 </problems>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
index 6f56e02..e045e8a 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
@@ -79,4 +79,46 @@
     myFixture.configureByText("X.java", newText.toString());
     myFixture.testHighlighting(true, false, false);
   }
+
+  @Override
+  protected String getBasePath() {
+    final Class<? extends LocalInspectionTool> inspectionClass = getInspection().getClass();
+    final String className = inspectionClass.getName();
+    final String[] words = className.split("\\.");
+    @NonNls final StringBuilder basePath = new StringBuilder("/plugins/InspectionGadgets/test/");
+    final int lastWordIndex = words.length - 1;
+    for (int i = 0; i < lastWordIndex; i++) {
+      final String word = words[i];
+      if (word.equals("ig")) {
+        basePath.append("igtest");
+      }
+      else {
+        basePath.append(word);
+      }
+      basePath.append('/');
+    }
+    String lastWord = words[lastWordIndex];
+    if (lastWord.endsWith("Inspection")) {
+      lastWord = lastWord.substring(0, lastWord.length() - 10);
+    }
+    final int length = lastWord.length();
+    for (int i = 0; i < length; i++) {
+      final char ch = lastWord.charAt(i);
+      if (Character.isUpperCase(ch)) {
+        if (i != 0) {
+          basePath.append('_');
+        }
+        basePath.append(Character.toLowerCase(ch));
+      }
+      else {
+        basePath.append(ch);
+      }
+    }
+    return basePath.toString();
+  }
+
+  protected final void doTest() {
+    myFixture.configureByFile(getTestName(false) + ".java");
+    myFixture.testHighlighting(true, false, false);
+  }
 }
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedRegexInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedRegexInspectionTest.java
new file mode 100644
index 0000000..68a1a06
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedRegexInspectionTest.java
@@ -0,0 +1,39 @@
+/**
+ * (c) 2013 Desert Island BV
+ * created: 20 09 2013
+ */
+package com.siyeh.ig.bugs;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.siyeh.ig.LightInspectionTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class MalformedRegexInspectionTest extends LightInspectionTestCase {
+
+  public void testMalformedRegex() {
+    doTest();
+  }
+
+  @Override
+  protected LocalInspectionTool getInspection() {
+    return new MalformedRegexInspection();
+  }
+
+  @Override
+  protected String[] getEnvironmentClasses() {
+    return new String[] {
+      "package java.util.regex;" +
+      "public class Pattern {" +
+      "  public static final int LITERAL = 0x10;" +
+      "  public static Pattern compile(String regex) {" +
+      "    return null;" +
+      "  }" +
+      "  public static Pattern compile(String regex, int flags) {" +
+      "    return null;" +
+      "  }" +
+      "}"
+    };
+  }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspectionTest.java
new file mode 100644
index 0000000..7079c5f
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspectionTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+/**
+ * (c) 2013 Desert Island BV
+ * created: 23 09 2013
+ */
+package com.siyeh.ig.internationalization;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.encoding.EncodingManager;
+import com.siyeh.ig.LightInspectionTestCase;
+
+import java.nio.charset.Charset;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class UnnecessaryUnicodeEscapeInspectionTest extends LightInspectionTestCase {
+
+  public void testUnnecessaryUnicodeEscape() {
+    myFixture.configureByFile(getTestName(false) + ".java");
+    final VirtualFile vFile = myFixture.getFile().getVirtualFile();
+    Charset ascii = CharsetToolkit.forName("US-ASCII");
+    EncodingManager.getInstance().setEncoding(vFile, ascii);
+    assertEquals(ascii, vFile.getCharset());
+    myFixture.testHighlighting(true, false, false);
+  }
+
+  @Override
+  protected LocalInspectionTool getInspection() {
+    return new UnnecessaryUnicodeEscapeInspection();
+  }
+}
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.java
index 887107e..e9083b06 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.java
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.java
@@ -20,8 +20,8 @@
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
 import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.options.Configurable;
 import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.JavaPsiFacade;
 import com.intellij.psi.PsiClass;
@@ -31,6 +31,7 @@
 import org.intellij.plugins.intelliLang.util.PsiUtilEx;
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.awt.*;
@@ -41,7 +42,7 @@
 /**
  * @author Gregory.Shrago
  */
-public class AdvancedSettingsUI implements Configurable {
+public class AdvancedSettingsUI implements SearchableConfigurable {
   private final Configuration.AdvancedConfiguration myConfiguration;
 
   @SuppressWarnings({"UnusedDeclaration", "FieldCanBeLocal"})
@@ -214,6 +215,18 @@
     return "reference.settings.injection.advanced";
   }
 
+  @NotNull
+  @Override
+  public String getId() {
+    return "IntelliLang.Advanced";
+  }
+
+  @Nullable
+  @Override
+  public Runnable enableSearch(String option) {
+    return null;
+  }
+
   private static class BrowseClassListener implements ActionListener {
     private final Project myProject;
     private final ReferenceEditorWithBrowseButton myField;
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
index 0d6a2be..bc54939 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
@@ -192,8 +192,10 @@
     JBPopup popup = new PopupChooserBuilder(list).setItemChoosenCallback(new Runnable() {
       public void run() {
         Injectable value = (Injectable)list.getSelectedValue();
-        onChosen.process(value);
-        PropertiesComponent.getInstance().setValue(LAST_INJECTED_LANGUAGE, value.getId());
+        if (value != null) {
+          onChosen.process(value);
+          PropertiesComponent.getInstance().setValue(LAST_INJECTED_LANGUAGE, value.getId());
+        }
       }
     }).setFilteringEnabled(new Function<Object, String>() {
       @Override
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java
index d921a2b0..b6eee7d 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java
@@ -88,6 +88,10 @@
    * see JLS 3.3. Unicode Escapes
    */
   private static int indexOfUnicodeEscape(String text, int offset) {
+    if (text == null) {
+      // apparently an editor can have a selection, but still null for selected text.
+      return -1;
+    }
     final int length = text.length();
     for (int i = 0; i < length; i++) {
       final char c = text.charAt(i);
@@ -111,7 +115,7 @@
         }
       }
       while (text.charAt(nextChar) == 'u'); // \uuuu0061 is a legal unicode escape
-      if (nextChar + 3 >= length) {
+      if (nextChar == i + 1 || nextChar + 3 >= length) {
         break;
       }
       if (StringUtil.isHexDigit(text.charAt(nextChar)) &&
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/CyclicInference_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/CyclicInference_after.java
new file mode 100644
index 0000000..dfa25f3
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/CyclicInference_after.java
@@ -0,0 +1,18 @@
+class Test2 {
+    class Y<T>{}
+    
+    interface I<X> {
+        X foo(Y<X> list);
+    }
+
+    static <T> I<T> bar(I<T> i){return i;}
+
+    {
+        bar(new I() {
+            @Override
+            public Object foo(Y x) {
+                <selection>return x;</selection>
+            }
+        });
+    }
+}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/unicode/unescape/U.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/unicode/unescape/U.java
new file mode 100644
index 0000000..9b64522
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/unicode/unescape/U.java
@@ -0,0 +1,3 @@
+class U {{
+  // <caret>\0183
+}}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java
index 09f7f44..21841d1 100644
--- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java
+++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java
@@ -44,7 +44,7 @@
   }
 
   public void testCyclicInference() {
-    assertIntentionNotAvailable();
+    doTest();
   }
 
   public void testNoFunctionalInterfaceFound() {
diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/unicode/UnicodeUnescapeIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/unicode/UnicodeUnescapeIntentionTest.java
index b474566..e5d8eff 100644
--- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/unicode/UnicodeUnescapeIntentionTest.java
+++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/unicode/UnicodeUnescapeIntentionTest.java
@@ -9,8 +9,9 @@
 public class UnicodeUnescapeIntentionTest extends IPPTestCase {
 
   public void testSimple() { doTest(); }
-  public void testNoException() { assertIntentionNotAvailable(); }
   public void testSelection() { doTest(); }
+  public void testNoException() { assertIntentionNotAvailable(); }
+  public void testU() { assertIntentionNotAvailable(); }
 
   @Override
   protected String getRelativePath() {
diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntBuildMessageView.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntBuildMessageView.java
index ca8f376..47f23f5 100644
--- a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntBuildMessageView.java
+++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntBuildMessageView.java
@@ -287,7 +287,7 @@
     new CloseListener(content, ijMessageView.getContentManager(), project);
     // Do not inline next two variabled. Seeking for NPE.
     ToolWindow messageToolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.MESSAGES_WINDOW);
-    messageToolWindow.activate(null);
+    messageToolWindow.activate(null, false);
     return messageView;
   }
 
diff --git a/plugins/devkit/jps-plugin/src/org/jetbrains/jps/devkit/model/JpsPluginModuleType.java b/plugins/devkit/jps-plugin/src/org/jetbrains/jps/devkit/model/JpsPluginModuleType.java
index 2cc4166..296fd24 100644
--- a/plugins/devkit/jps-plugin/src/org/jetbrains/jps/devkit/model/JpsPluginModuleType.java
+++ b/plugins/devkit/jps-plugin/src/org/jetbrains/jps/devkit/model/JpsPluginModuleType.java
@@ -16,12 +16,13 @@
 package org.jetbrains.jps.devkit.model;
 
 import org.jetbrains.jps.model.JpsSimpleElement;
+import org.jetbrains.jps.model.ex.JpsElementTypeBase;
 import org.jetbrains.jps.model.module.JpsModuleType;
 
 /**
  * @author nik
  */
-public class JpsPluginModuleType extends JpsModuleType<JpsSimpleElement<JpsPluginModuleProperties>> {
+public class JpsPluginModuleType extends JpsElementTypeBase<JpsSimpleElement<JpsPluginModuleProperties>> implements JpsModuleType<JpsSimpleElement<JpsPluginModuleProperties>> {
   public static final JpsPluginModuleType INSTANCE = new JpsPluginModuleType();
 
 }
diff --git a/plugins/devkit/src/build/PluginModuleBuildConfEditor.java b/plugins/devkit/src/build/PluginModuleBuildConfEditor.java
index 64e63d5..3e5a614 100644
--- a/plugins/devkit/src/build/PluginModuleBuildConfEditor.java
+++ b/plugins/devkit/src/build/PluginModuleBuildConfEditor.java
@@ -102,13 +102,10 @@
     if (myUseUserManifest.isSelected() && myManifest.getText() != null && !new File(myManifest.getText()).exists()){
       throw new ConfigurationException(DevKitBundle.message("error.file.not.found.message", myManifest.getText()));
     }
-    final File plugin = myBuildProperties.getPluginXmlPath() != null ? new File(myBuildProperties.getPluginXmlPath()) : null;
+    final File plugin = new File(myBuildProperties.getPluginXmlPath());
     final String newPluginPath = myPluginXML.getText() + File.separator + META_INF + File.separator + PLUGIN_XML;
-    if (plugin != null &&
-        plugin.exists() &&
-        !plugin.getPath().equals(newPluginPath) &&
-        Messages.showYesNoDialog(myModule.getProject(),
-                                 DevKitBundle.message("deployment.view.delete", plugin.getPath()),
+    if (plugin.exists() && !plugin.getPath().equals(newPluginPath) && 
+        Messages.showYesNoDialog(myModule.getProject(), DevKitBundle.message("deployment.view.delete", plugin.getPath()),
                                  DevKitBundle.message("deployment.cleanup", META_INF), null) == DialogWrapper.OK_EXIT_CODE) {
 
       CommandProcessor.getInstance().executeCommand(myModule.getProject(),
diff --git a/plugins/devkit/testSources/PluginProjectWizardTest.java b/plugins/devkit/testSources/PluginProjectWizardTest.java
index 6331769..603110a 100644
--- a/plugins/devkit/testSources/PluginProjectWizardTest.java
+++ b/plugins/devkit/testSources/PluginProjectWizardTest.java
@@ -19,7 +19,7 @@
 import com.intellij.ide.projectWizard.ProjectWizardTestCase;
 import com.intellij.openapi.module.JavaModuleType;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.vfs.VirtualFile;
 import org.jetbrains.idea.devkit.module.PluginModuleType;
 import org.jetbrains.idea.devkit.projectRoots.IdeaJdk;
@@ -34,7 +34,7 @@
     createSdk("devkit", IdeaJdk.getInstance());
     Project project = createProjectFromTemplate(JavaModuleType.JAVA_GROUP, PluginModuleType.getInstance().getName(), null);
     VirtualFile baseDir = project.getBaseDir();
-    VirtualFile virtualFile = VfsUtil.findRelativeFile("META-INF/plugin.xml", baseDir);
+    VirtualFile virtualFile = VfsUtilCore.findRelativeFile("META-INF/plugin.xml", baseDir);
     assertNotNull(virtualFile);
   }
 
diff --git a/plugins/eclipse/resources/META-INF/plugin.xml b/plugins/eclipse/resources/META-INF/plugin.xml
index a17e668..5145ea5 100644
--- a/plugins/eclipse/resources/META-INF/plugin.xml
+++ b/plugins/eclipse/resources/META-INF/plugin.xml
@@ -13,6 +13,10 @@
     <errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
     <fileTypeFactory implementation="org.jetbrains.idea.eclipse.config.EclipseFileTypeFactory"/>
     <syntaxHighlighter key="Eclipse" implementationClass="com.intellij.ide.highlighter.XmlFileHighlighter"/>
+    <schemeImporter 
+        name="Eclpse XML Profile"
+        implementationClass="org.jetbrains.idea.eclipse.importer.EclipseCodeStyleSchemeImporter"
+        schemeClass="com.intellij.psi.codeStyle.CodeStyleScheme"/>
   </extensions>
   <module-components>
     <component>
diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseCodeStyleSchemeImporter.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseCodeStyleSchemeImporter.java
new file mode 100644
index 0000000..c3d99b9
--- /dev/null
+++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseCodeStyleSchemeImporter.java
@@ -0,0 +1,220 @@
+/*
+ * 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.eclipse.importer;
+
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
+import com.intellij.openapi.options.SchemeImportException;
+import com.intellij.openapi.options.SchemeImporter;
+import com.intellij.psi.codeStyle.CodeStyleScheme;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+public class EclipseCodeStyleSchemeImporter implements SchemeImporter<CodeStyleScheme>, EclipseXmlProfileElements {
+
+  private static final Logger LOG = Logger.getInstance("#" + EclipseCodeStyleSchemeImporter.class.getName());
+  
+  private final static String PROGRAMMATIC_IMPORT_KEY = "<Programmatic>";
+  
+  private final EclipseImportMap myImportMap;
+
+  public EclipseCodeStyleSchemeImporter() {
+    myImportMap = new EclipseImportMap();
+    myImportMap.load();    
+  }
+
+  @Override
+  public String getSourceExtension() {
+    return "xml";
+  }
+
+  @NotNull
+  @Override
+  public String[] readSchemeNames(@NotNull InputStream inputStream) throws SchemeImportException {
+    final Set<String> names = new HashSet<String>();
+    EclipseXmlProfileReader reader = new EclipseXmlProfileReader(new EclipseXmlProfileReader.OptionHandler() {
+      @Override
+      public void handleOption(@NotNull String eclipseKey, @NotNull String value) throws SchemeImportException {
+        // Ignore
+      }
+      @Override
+      public void handleName(String name) {
+        names.add(name);
+      }
+    });
+    reader.readSettings(inputStream);
+    return ArrayUtil.toStringArray(names);
+  }
+
+  @Override
+  public void importScheme(@NotNull InputStream inputStream, final @Nullable String sourceScheme, final CodeStyleScheme scheme)
+    throws SchemeImportException {
+    final CodeStyleSettings settings = scheme.getCodeStyleSettings();
+    EclipseXmlProfileReader reader = new EclipseXmlProfileReader(new EclipseXmlProfileReader.OptionHandler() {
+      private String myCurrScheme;
+
+      @Override
+      public void handleOption(@NotNull String eclipseKey, @NotNull String value) throws SchemeImportException {
+        if (sourceScheme == null || myCurrScheme != null && myCurrScheme.equals(sourceScheme)) {
+          setCodeStyleOption(settings, eclipseKey, value);
+        }
+      }
+      @Override
+      public void handleName(String name) {
+        myCurrScheme = name;
+      }
+    });
+    reader.readSettings(inputStream);
+  }
+
+  private void setCodeStyleOption(@NotNull CodeStyleSettings settings, @NotNull String key, @NotNull String value)
+    throws SchemeImportException {
+    EclipseImportMap.ImportDescriptor importDescriptor = myImportMap.getImportDescriptor(key);
+    if (importDescriptor != null) {
+      try {
+        if (importDescriptor.isLanguageSpecific()) {
+          CommonCodeStyleSettings languageSettings = settings.getCommonSettings(importDescriptor.getLanguage());
+          if (languageSettings != null) {
+            if (importDescriptor.isIndentOptions()) {
+              CommonCodeStyleSettings.IndentOptions indentOptions = languageSettings.getIndentOptions();
+              if (indentOptions != null) {
+                setValue(indentOptions, key, importDescriptor.getFieldName(), value);
+              }
+            }
+            else {
+              setValue(languageSettings, key, importDescriptor.getFieldName(), value);
+            }
+          }
+        }
+        else {
+          setValue(settings, key, importDescriptor.getFieldName(), value);
+        }
+      }
+      catch (Exception e) {
+        throw new SchemeImportException(e);
+      }
+    }
+  }
+
+  private static void setValue(Object object, String key, String fieldName, String value) throws SchemeImportException {
+    if (PROGRAMMATIC_IMPORT_KEY.equalsIgnoreCase(fieldName)) {
+      setProgrammatically(object, key, value);
+      return;
+    }
+    try {
+      Field targetField = object.getClass().getField(fieldName);
+      Class<?> fieldType = targetField.getType();
+      if (fieldType.isPrimitive()) {
+        if (Boolean.TYPE.equals(fieldType)) {
+          targetField.setBoolean(object, valueToBoolean(key, value));
+        }
+        else if (Integer.TYPE.equals(fieldType)) {
+          targetField.setInt(object, valueToInt(value));
+        }
+      }
+      else if (fieldType.equals(String.class)) {
+        targetField.set(object, value);
+      }
+    }
+    catch (IllegalAccessException e) {
+      LOG.error(e);
+    }
+    catch (NoSuchFieldException e) {
+      LOG.error("Field '" + fieldName + "' does not exist in " + object.getClass().getName(), e); 
+    }    
+  }
+
+  private static boolean valueToBoolean(@NotNull String key, @NotNull String value) throws SchemeImportException {
+    if (VALUE_INSERT.equals(value) ||
+      VALUE_TRUE.equals(value)) {
+      return true;
+    }
+    if (key.contains("alignment") && value.matches("\\d*")) {
+      return isAlignmentOn(value);
+    }
+    if (!(VALUE_DO_NOT_INSERT.equals(value) ||
+          VALUE_FALSE.equals(value))) {
+      throw new SchemeImportException("Unrecognized boolean value: " + value + ", key: " + key);
+    }
+    return false;
+  }
+  
+  private static int valueToInt(@NotNull String value) {
+    if (VALUE_END_OF_LINE.equals(value)) return CommonCodeStyleSettings.END_OF_LINE;
+    if (VALUE_NEXT_LINE.equals(value)) return CommonCodeStyleSettings.NEXT_LINE;
+    if (VALUE_NEXT_LINE_SHIFTED.equals(value)) return CommonCodeStyleSettings.NEXT_LINE_SHIFTED;
+    if (VALUE_NEXT_LINE_IF_WRAPPED.equals(value)) return CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED;
+    return Integer.parseInt(value);
+  }
+
+  private static boolean isAlignmentOn(@NotNull String value) {
+    int packed = valueToInt(value);
+    return (packed & 2) != 0;
+  }
+  
+  private static void setProgrammatically(@NotNull Object object, @NotNull String key, @NotNull String value) throws SchemeImportException {
+    if (object instanceof CodeStyleSettings) {
+      CodeStyleSettings settings = (CodeStyleSettings)object;
+      if (OPTION_REMOVE_JAVADOC_BLANK_LINES.equals(key)) {
+        settings.JD_KEEP_EMPTY_LINES = !valueToBoolean(key, value);
+      }
+      else if (OPTION_NEW_LINE_AT_EOF.equals(key)) {
+        EditorSettingsExternalizable editorSettings = EditorSettingsExternalizable.getInstance();
+        editorSettings.setEnsureNewLineAtEOF(valueToBoolean(key, value));
+      }
+    }
+    else if (object instanceof CommonCodeStyleSettings) {
+      CommonCodeStyleSettings commonSettings = (CommonCodeStyleSettings)object;
+      if (OPTION_SPACE_AFTER_BINARY_OPERATOR.equals(key)) {
+        boolean addSpace = valueToBoolean(key, value);
+        commonSettings.SPACE_AROUND_ADDITIVE_OPERATORS = 
+        commonSettings.SPACE_AROUND_BITWISE_OPERATORS = 
+        commonSettings.SPACE_AROUND_LOGICAL_OPERATORS = 
+        commonSettings.SPACE_AROUND_MULTIPLICATIVE_OPERATORS =
+        commonSettings.SPACE_AROUND_RELATIONAL_OPERATORS =
+        commonSettings.SPACE_AROUND_SHIFT_OPERATORS =
+        commonSettings.SPACE_AROUND_EQUALITY_OPERATORS =
+          addSpace;
+      }
+      else if (OPTION_INDENT_CLASS_BODY_DECL.equals(key)) {
+        commonSettings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS = !valueToBoolean(key, value);
+      }
+    }
+    else if (object instanceof CommonCodeStyleSettings.IndentOptions) {
+      CommonCodeStyleSettings.IndentOptions indentOptions = (CommonCodeStyleSettings.IndentOptions)object;
+      if (OPTION_TAB_CHAR.equals(key)) {
+        if (TAB_CHAR_TAB.equals(value) || TAB_CHAR_MIXED.equals(value)) {
+          indentOptions.USE_TAB_CHARACTER = true;
+        }
+        else if (TAB_CHAR_SPACE.equals(value)) {
+          indentOptions.USE_TAB_CHARACTER = false;
+        }
+      }
+    }
+  }
+}
diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.java
new file mode 100644
index 0000000..35dde4d
--- /dev/null
+++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.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.idea.eclipse.importer;
+
+import com.intellij.openapi.diagnostic.Logger;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+public class EclipseImportMap {
+  private Properties myProperties;
+  private final static String MAP_PROPERTIES = "EclipseImportMap.properties";
+  private static final Logger LOG = Logger.getInstance("#" + EclipseImportMap.class.getName());
+
+  public EclipseImportMap() {
+    myProperties = new Properties();    
+  }
+
+  public void load() {
+    try {
+      InputStream sourceStream = getClass().getResourceAsStream(MAP_PROPERTIES);
+      try {
+        myProperties.load(sourceStream);
+      }
+      finally {
+        sourceStream.close();
+      }
+    }
+    catch (IOException e) {
+      LOG.error(e);
+    }
+  }
+  
+  @Nullable
+  public ImportDescriptor getImportDescriptor(String name) {
+    String rawData = myProperties.getProperty(name);
+    if (rawData != null && !rawData.trim().isEmpty()) {
+      if (rawData.contains(":")) {
+        String[] parameters = rawData.split(":");
+        if (parameters.length == 2) {
+          return new ImportDescriptor(parameters[0].trim(), parameters[1].trim());
+        }
+        else if (parameters.length == 3) {
+          boolean indentOptions = "indentOptions".equalsIgnoreCase(parameters[1].trim());
+          return new ImportDescriptor(parameters[0].trim(), parameters[2], indentOptions);
+        }
+      }
+      else {
+        return new ImportDescriptor(rawData.trim());
+      }
+    }
+    return null;
+  }
+  
+  public static class ImportDescriptor {
+    private String myLanguage;
+    private String myFieldName;
+    private boolean myIndentOptions;
+
+    public ImportDescriptor(String language, String fieldName, boolean indentOptions) {
+      myLanguage = language;
+      myFieldName = fieldName;
+      myIndentOptions = indentOptions;
+    }
+    
+    public ImportDescriptor(String language, String fieldName) {
+      this(language, fieldName, false);
+    }
+    
+    public ImportDescriptor(String fieldName) {
+      this(null, fieldName);
+    }
+
+    public String getLanguage() {
+      return myLanguage;
+    }
+
+    public String getFieldName() {
+      return myFieldName;
+    }
+
+    public boolean isIndentOptions() {
+      return myIndentOptions;
+    }
+    
+    public boolean isLanguageSpecific() {
+      return myLanguage != null;
+    }
+  }
+}
diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties
new file mode 100644
index 0000000..e4ac52c
--- /dev/null
+++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties
@@ -0,0 +1,289 @@
+# suppress inspection "UnusedProperty" for whole file
+#
+# A set of properties describing a map from Eclipse settings to equivalent Intellij IDEA ones.
+# Property value format:
+#   [Language:[IndentOptions:]]OPTION_NAME
+#
+# If Language is omitted, root CodeStyleSettings are used, otherwise CommonCodeStyleSettings for the specified Language.
+# OPTION_NAME = <programmatic> means that the value is set programmatically, probably for many target options at a time.
+#
+
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=Java:SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS
+#org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=
+#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=Java:SPACE_WITHIN_ARRAY_INITIALIZER_BRACES
+#org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=Java:ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=Java:SPACE_WITHIN_ANNOTATION_PARENTHESES
+org.eclipse.jdt.core.formatter.blank_lines_before_field=Java:BLANK_LINES_AROUND_FIELD
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=Java:SPACE_WITHIN_WHILE_PARENTHESES
+#org.eclipse.jdt.core.formatter.use_on_off_tags=
+#org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=Java:ELSE_ON_NEW_LINE
+#org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=
+#org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=
+#org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=
+#org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=
+#org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=
+#org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=Java:ALIGN_GROUP_FIELD_DECLARATIONS
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=Java:ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION
+#org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=Java:SPACE_BEFORE_FOR_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=Java:<Programmatic>
+#org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=
+#org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=
+#org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=Java:FINALLY_ON_NEW_LINE
+#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=Java:CATCH_ON_NEW_LINE
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=Java:SPACE_BEFORE_WHILE_PARENTHESES
+org.eclipse.jdt.core.formatter.blank_lines_after_package=Java:BLANK_LINES_AFTER_PACKAGE
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=
+org.eclipse.jdt.core.formatter.continuation_indentation=Java:IndentOptions:CONTINUATION_INDENT_SIZE
+#org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=Java:ALIGN_MULTILINE_PARAMETERS_IN_CALLS
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=
+#org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=
+#org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=
+org.eclipse.jdt.core.formatter.blank_lines_before_package=Java:BLANK_LINES_BEFORE_PACKAGE
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=
+#org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=
+#org.eclipse.jdt.core.formatter.comment.format_line_comments=
+#org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=
+#org.eclipse.jdt.core.formatter.join_wrapped_lines=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=
+#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=Java:SPACE_BEFORE_COMMA
+#org.eclipse.jdt.core.formatter.blank_lines_before_member_type=
+#org.eclipse.jdt.core.formatter.align_type_members_on_columns=
+#org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=Java:SPACE_WITHIN_FOR_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=Java:SPACE_BEFORE_METHOD_PARENTHESES
+#org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=Java:SPACE_WITHIN_SWITCH_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=Java:SPACE_AROUND_UNARY_OPERATOR
+#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=
+#org.eclipse.jdt.core.formatter.comment.indent_parameter_description=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=Java:SPACE_WITHIN_METHOD_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=Java:SPACE_WITHIN_SWITCH_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=
+#org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=
+org.eclipse.jdt.core.formatter.lineSplit=RIGHT_MARGIN
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=Java:SPACE_BEFORE_IF_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=Java:SPACE_WITHIN_BRACKETS
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=Java:SPACE_WITHIN_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaratio n=
+#org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=
+#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=
+org.eclipse.jdt.core.formatter.indentation.size=Java:IndentOptions:INDENT_SIZE
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=Java:SPACE_WITHIN_EMPTY_METHOD_PARENTHESES
+#org.eclipse.jdt.core.formatter.enabling_tag=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=Java:ALIGN_MULTILINE_EXTENDS_LIST
+org.eclipse.jdt.core.formatter.alignment_for_assignment=Java:ALIGN_MULTILINE_ASSIGNMENT
+org.eclipse.jdt.core.formatter.tabulation.char=Java:IndentOptions:<Programmatic>
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=
+#org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=
+#org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=
+#org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=
+org.eclipse.jdt.core.formatter.blank_lines_before_method=Java:BLANK_LINES_AROUND_METHOD
+#org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=
+#org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=
+#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=
+#org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=
+#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=
+#org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=Java:ALIGN_MULTILINE_PARAMETERS_IN_CALLS
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=Java:SPACE_WITHIN_METHOD_CALL_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=Java:SPACE_WITHIN_TRY_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=
+#org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=Java:SPACE_WITHIN_IF_PARENTHESES
+#org.eclipse.jdt.core.formatter.brace_position_for_switch=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=
+#org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=Java:SPACE_AFTER_QUEST
+#org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=Java:SPACE_WITHIN_TRY_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=
+#org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=
+#org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=Java:INDENT_CASE_FROM_SWITCH
+#org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=
+org.eclipse.jdt.core.formatter.brace_position_for_block=Java:BRACE_STYLE
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=Java:METHOD_BRACE_STYLE
+org.eclipse.jdt.core.formatter.compact_else_if=Java:SPECIAL_ELSE_IF_TREATMENT
+#org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=
+#org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=Java:SPACE_WITHIN_BRACKETS
+#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=
+#org.eclipse.jdt.core.formatter.comment.indent_root_tags=
+#org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=
+#org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=Java:SPACE_BEFORE_SWITCH_LBRACE
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=Java:SPACE_BEFORE_COMMA
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=
+org.eclipse.jdt.core.formatter.tabulation.size=Java:IndentOptions:TAB_SIZE
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=Java:ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE
+#org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=
+#org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=Java:SPACE_WITHIN_IF_PARENTHESES
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=<Programmatic>
+#org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=Java:SPACE_AROUND_ASSIGNMENT_OPERATORS
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=Java:SPACE_AROUND_ASSIGNMENT_OPERATORS
+#org.eclipse.jdt.core.formatter.indent_empty_lines=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=Java:SPACE_WITHIN_SYNCHRONIZED_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=Java:SPACE_AFTER_TYPE_CAST
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=Java:SPACE_AFTER_COMMA
+#org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=Java:KEEP_BLANK_LINES_IN_CODE
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=Java:SPACE_BEFORE_METHOD_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=Java:SPACE_WITHIN_CATCH_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=Java:SPACE_BEFORE_METHOD_CALL_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=Java:SPACE_WITHIN_BRACKETS
+#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=
+#org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=
+#org.eclipse.jdt.core.compiler.compliance=
+#org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=
+#org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=
+#org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=
+#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=Java:SPACE_WITHIN_CAST_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=Java:SPACE_AROUND_UNARY_OPERATOR
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=
+#org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=Java:KEEP_SIMPLE_BLOCKS_IN_ONE_LINE
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=
+#org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=<Programmatic>
+#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=
+#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=
+#org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=Java:ALIGN_MULTILINE_BINARY_OPERATION
+#org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=
+#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=Java:SPACE_WITHIN_WHILE_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=Java:SPACE_BEFORE_TRY_PARENTHESES
+#org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=
+#org.eclipse.jdt.core.formatter.insert_new_line_after_label=
+#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=
+#org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=Java:SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=Java:WHILE_ON_NEW_LINE
+#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=ENABLE_JAVADOC_FORMATTING
+#org.eclipse.jdt.core.formatter.comment.line_length=
+#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=
+#org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=Java:SPACE_BEFORE_SEMICOLON
+#org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=Java:BLANK_LINES_BEFORE_METHOD_BODY
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=Java:SPACE_BEFORE_COLON
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=Java:<Programmatic>
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=Java:BINARY_OPERATION_SIGN_ON_NEXT_LINE
+#org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=
+#org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=Java:SPACE_WITHIN_SYNCHRONIZED_PARENTHESES
+#org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=
+#org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=
+#org.eclipse.jdt.core.formatter.join_lines_in_comments=
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=Java:SPACE_BEFORE_QUEST
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=
+#org.eclipse.jdt.core.formatter.alignment_for_compact_if=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=
+#org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=
+#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=
+#org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=
+#org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=Java:BLANK_LINES_BEFORE_IMPORTS
+#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=
+#org.eclipse.jdt.core.formatter.comment.format_html=
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=Java:ALIGN_MULTILINE_THROWS_LIST
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=Java:SPACE_AFTER_COLON
+#org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=Java:SPACE_WITHIN_FOR_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=
+#org.eclipse.jdt.core.formatter.comment.format_source_code=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=Java:SPACE_BEFORE_SYNCHRONIZED_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=Java:ALIGN_MULTILINE_PARAMETERS
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=Java:SPACE_WITHIN_ARRAY_INITIALIZER_BRACES
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=Java:ALIGN_MULTILINE_RESOURCES
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=Java:IndentOptions:SMART_TABS
+#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=
+#org.eclipse.jdt.core.formatter.comment.format_header=
+#org.eclipse.jdt.core.formatter.comment.format_block_comments=
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=
+#org.eclipse.jdt.core.formatter.alignment_for_enum_constants=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=
+#org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=Java:SPACE_WITHIN_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=Java:SPACE_WITHIN_CATCH_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=Java:SPACE_BEFORE_SWITCH_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=Java:SPACE_WITHIN_METHOD_CALL_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=Java:CLASS_BRACE_STYLE
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=Java:SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE
+#org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=Java:SPACE_WITHIN_METHOD_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=Java:SPACE_BEFORE_CATCH_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=Java:SPACE_WITHIN_ANNOTATION_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=
+#org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=Java:BLANK_LINES_AFTER_IMPORTS
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=
+#org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=
+#org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=Java:KEEP_FIRST_COLUMN_COMMENT
+#org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=
+#org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=Java:KEEP_CONTROL_STATEMENT_IN_ONE_LINE
diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileElements.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileElements.java
new file mode 100644
index 0000000..b30a3a8
--- /dev/null
+++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileElements.java
@@ -0,0 +1,49 @@
+/*
+ * 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.eclipse.importer;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+@SuppressWarnings("UnusedDeclaration")
+public interface EclipseXmlProfileElements {
+  String PROFILES_TAG = "profiles";
+  String PROFILE_TAG = "profile";
+  String NAME_ATTR = "name";
+  String SETTING_TAG = "setting";
+  String ID_ATTR = "id";
+  String VALUE_ATTR = "value";
+  
+  String VALUE_INSERT = "insert";
+  String VALUE_DO_NOT_INSERT = "do not insert";
+  String VALUE_FALSE = "false";
+  String VALUE_TRUE = "true";
+  
+  String VALUE_NEXT_LINE = "next_line";
+  String VALUE_NEXT_LINE_SHIFTED = "next_line_shifted";
+  String VALUE_END_OF_LINE = "end_of_line";
+  String VALUE_NEXT_LINE_IF_WRAPPED = "next_line_on_wrap";
+
+  String TAB_CHAR_TAB = "tab";
+  String TAB_CHAR_SPACE = "space";
+  String TAB_CHAR_MIXED = "mixed";
+
+  String OPTION_SPACE_AFTER_BINARY_OPERATOR = "org.eclipse.jdt.core.formatter.insert_space_after_binary_operator";
+  String OPTION_REMOVE_JAVADOC_BLANK_LINES = "org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment";
+  String OPTION_NEW_LINE_AT_EOF = "org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing";
+  String OPTION_INDENT_CLASS_BODY_DECL = "org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header";
+  String OPTION_TAB_CHAR = "org.eclipse.jdt.core.formatter.tabulation.char";
+}
diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileReader.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileReader.java
new file mode 100644
index 0000000..4216e58
--- /dev/null
+++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileReader.java
@@ -0,0 +1,91 @@
+/*
+ * 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.eclipse.importer;
+
+import com.intellij.openapi.options.SchemeImportException;
+import org.jetbrains.annotations.NotNull;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import java.io.InputStream;
+
+/**
+ * Reads settings from Eclipse XML profile. The actual work is done by an implementor of <code>handleOption()</code> method.
+ * 
+ * @author Rustam Vishnyakov
+ */
+public class EclipseXmlProfileReader extends DefaultHandler implements EclipseXmlProfileElements {
+
+  private OptionHandler myOptionHandler;
+
+  protected EclipseXmlProfileReader(OptionHandler optionHandler) {
+    myOptionHandler = optionHandler;
+  }
+
+  /**
+   * Reads either basic profile info (name) or all the settings depending on whether <code>settings</code> parameter is null.
+   * 
+   * @param input The input stream to read from.
+   * @throws SchemeImportException
+   */
+  protected void readSettings(InputStream input) throws SchemeImportException {
+    SAXParserFactory spf = SAXParserFactory.newInstance();
+    spf.setValidating(false);
+    SAXParser parser;
+    try {
+      parser = spf.newSAXParser();
+      parser.parse(input, this);
+    }
+    catch (Exception e) {
+      throw new SchemeImportException(e);
+    }
+  }
+
+  @Override
+  public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+    if (PROFILE_TAG.equals(qName)) {
+      myOptionHandler.handleName(attributes.getValue(NAME_ATTR));
+    }
+    else if (SETTING_TAG.equals(qName)) {
+      String key = attributes.getValue(ID_ATTR);
+      String value = attributes.getValue(VALUE_ATTR);
+      if (key != null && value != null) {
+        try {
+          myOptionHandler.handleOption(key, value);
+        }
+        catch (SchemeImportException e) {
+          throw new SAXException(e);
+        }
+      }
+    }
+    else //noinspection StatementWithEmptyBody
+      if (PROFILES_TAG.equals(qName)) {
+      // Ignore
+    }
+    else {
+      throw new SAXException("Unknown XML element: " + qName);
+    }
+  }
+
+
+  interface OptionHandler {
+    void handleOption(@NotNull String eclipseKey, @NotNull String value) throws SchemeImportException;
+    void handleName(String name);
+  }
+}
diff --git a/plugins/eclipse/testData/import/settings/eclipse_exported.xml b/plugins/eclipse/testData/import/settings/eclipse_exported.xml
new file mode 100644
index 0000000..813c43b
--- /dev/null
+++ b/plugins/eclipse/testData/import/settings/eclipse_exported.xml
@@ -0,0 +1,291 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<profiles version="12">
+<profile kind="CodeFormatterProfile" name="MyOwn" version="12">
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
+<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line_shifted"/>
+<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line_on_wrap"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+</profile>
+</profiles>
diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java
new file mode 100644
index 0000000..30c309e
--- /dev/null
+++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java
@@ -0,0 +1,168 @@
+package org.jetbrains.idea.eclipse;
+
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
+import com.intellij.psi.codeStyle.CodeStyleScheme;
+import com.intellij.psi.codeStyle.CodeStyleSchemes;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.intellij.testFramework.PlatformTestCase;
+import org.jetbrains.idea.eclipse.importer.EclipseCodeStyleSchemeImporter;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+public class EclipseSettingsImportTest extends PlatformTestCase {
+  
+  private static String getTestDataPath() {
+    return PluginPathManager.getPluginHomePath("eclipse") + "/testData/import/settings/";
+  }
+  
+  public void testImportCodeStyleSettingsFromXmlProfile() throws Exception {
+    File input = new File(getTestDataPath() + "eclipse_exported.xml");
+    EclipseCodeStyleSchemeImporter codeStyleSchemeImporter = new EclipseCodeStyleSchemeImporter();
+    CodeStyleSchemes schemes = CodeStyleSchemes.getInstance();
+    CodeStyleScheme scheme = schemes.createNewScheme(getTestName(false), null);
+    CodeStyleSettings settings = scheme.getCodeStyleSettings();
+    
+    CommonCodeStyleSettings javaSettings = settings.getCommonSettings("Java");
+    CommonCodeStyleSettings.IndentOptions indentOptions = javaSettings.getIndentOptions();
+    javaSettings.SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS = false;
+    javaSettings.SPACE_WITHIN_ARRAY_INITIALIZER_BRACES = false;
+    javaSettings.ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE = true;
+    javaSettings.SPACE_WITHIN_ANNOTATION_PARENTHESES = true;
+    javaSettings.BLANK_LINES_AROUND_FIELD = -1;
+    javaSettings.SPACE_WITHIN_WHILE_PARENTHESES = true;
+    javaSettings.ELSE_ON_NEW_LINE = true;
+    javaSettings.ALIGN_GROUP_FIELD_DECLARATIONS = true;
+    javaSettings.SPACE_BEFORE_FOR_PARENTHESES = false;
+    javaSettings.SPACE_AROUND_ADDITIVE_OPERATORS = false;
+    javaSettings.SPACE_AROUND_BITWISE_OPERATORS = false;
+    javaSettings.SPACE_AROUND_EQUALITY_OPERATORS = false;
+    javaSettings.SPACE_AROUND_LOGICAL_OPERATORS = false;
+    javaSettings.FINALLY_ON_NEW_LINE = true;
+    javaSettings.CATCH_ON_NEW_LINE = true;
+    javaSettings.SPACE_BEFORE_WHILE_PARENTHESES = false;
+    javaSettings.BLANK_LINES_AFTER_PACKAGE = -1;
+    javaSettings.getIndentOptions().CONTINUATION_INDENT_SIZE = 0;
+    javaSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
+    javaSettings.BLANK_LINES_BEFORE_PACKAGE = -1;
+    javaSettings.SPACE_WITHIN_FOR_PARENTHESES = true;
+    javaSettings.ALIGN_MULTILINE_ASSIGNMENT = true;
+    javaSettings.SPACE_BEFORE_METHOD_PARENTHESES = true;
+    javaSettings.SPACE_WITHIN_CATCH_PARENTHESES = true;
+    javaSettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES = true;
+    javaSettings.SPACE_WITHIN_CAST_PARENTHESES = true;
+    javaSettings.SPACE_AROUND_UNARY_OPERATOR = true;
+    javaSettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = false;
+    EditorSettingsExternalizable editorSettings = EditorSettingsExternalizable.getInstance();
+    boolean currAddLineFeed = editorSettings.isEnsureNewLineAtEOF();
+    editorSettings.setEnsureNewLineAtEOF(true);
+    javaSettings.ALIGN_MULTILINE_BINARY_OPERATION = true;
+    javaSettings.SPACE_WITHIN_TRY_PARENTHESES = true;
+    javaSettings.SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES = true;
+    javaSettings.WHILE_ON_NEW_LINE = true;
+    settings.ENABLE_JAVADOC_FORMATTING = false;
+    javaSettings.SPACE_BEFORE_SEMICOLON = true;
+    javaSettings.BLANK_LINES_BEFORE_METHOD_BODY = -1;
+    javaSettings.SPACE_BEFORE_COLON = false;
+    javaSettings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS = true;
+    javaSettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE = false;
+    javaSettings.SPACE_WITHIN_SYNCHRONIZED_PARENTHESES = true;
+    javaSettings.SPACE_BEFORE_QUEST = false;
+    javaSettings.BLANK_LINES_BEFORE_IMPORTS = 0;
+    javaSettings.ALIGN_MULTILINE_THROWS_LIST = true;
+    javaSettings.SPACE_AFTER_COLON = false;
+    javaSettings.SPACE_WITHIN_FOR_PARENTHESES = true;
+    javaSettings.SPACE_BEFORE_SYNCHRONIZED_PARENTHESES = false;
+    javaSettings.ALIGN_MULTILINE_PARAMETERS = true;
+    javaSettings.ALIGN_MULTILINE_RESOURCES = true;
+    javaSettings.SPACE_BEFORE_SWITCH_PARENTHESES = false;
+    javaSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES = true;
+    javaSettings.CLASS_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE;
+    javaSettings.SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE = false;
+    javaSettings.SPACE_WITHIN_METHOD_PARENTHESES = true;
+    javaSettings.SPACE_BEFORE_CATCH_PARENTHESES = false;
+    javaSettings.SPACE_WITHIN_ANNOTATION_PARENTHESES = true;
+    javaSettings.BLANK_LINES_AFTER_IMPORTS = -1;
+    javaSettings.KEEP_FIRST_COLUMN_COMMENT = true;
+    javaSettings.KEEP_CONTROL_STATEMENT_IN_ONE_LINE = true;
+    indentOptions.USE_TAB_CHARACTER = false;
+    indentOptions.SMART_TABS = false;
+
+    InputStream inputStream = new FileInputStream(input);
+    try {
+      codeStyleSchemeImporter.importScheme(inputStream, null, scheme);
+
+      assertTrue(javaSettings.SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS);
+      assertTrue(javaSettings.SPACE_WITHIN_ARRAY_INITIALIZER_BRACES);
+      assertFalse(javaSettings.ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE);
+      assertFalse(javaSettings.SPACE_WITHIN_ANNOTATION_PARENTHESES);
+      assertEquals(0, javaSettings.BLANK_LINES_AROUND_FIELD);
+      assertFalse(javaSettings.SPACE_WITHIN_WHILE_PARENTHESES);
+      assertFalse(javaSettings.ELSE_ON_NEW_LINE);
+      assertFalse(javaSettings.ALIGN_GROUP_FIELD_DECLARATIONS);
+      assertTrue(javaSettings.SPACE_BEFORE_FOR_PARENTHESES);
+      assertTrue(javaSettings.SPACE_AROUND_ADDITIVE_OPERATORS);
+      assertTrue(javaSettings.SPACE_AROUND_BITWISE_OPERATORS);
+      assertTrue(javaSettings.SPACE_AROUND_EQUALITY_OPERATORS);
+      assertTrue(javaSettings.SPACE_AROUND_LOGICAL_OPERATORS);
+      assertFalse(javaSettings.FINALLY_ON_NEW_LINE);
+      assertFalse(javaSettings.CATCH_ON_NEW_LINE);
+      assertTrue(javaSettings.SPACE_BEFORE_WHILE_PARENTHESES);
+      assertEquals(1, javaSettings.BLANK_LINES_AFTER_PACKAGE);
+      assertEquals(2, javaSettings.getIndentOptions().CONTINUATION_INDENT_SIZE);
+      assertFalse(javaSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS);
+      assertEquals(0, javaSettings.BLANK_LINES_BEFORE_PACKAGE);
+      assertFalse(javaSettings.SPACE_WITHIN_FOR_PARENTHESES);
+      assertFalse(javaSettings.ALIGN_MULTILINE_ASSIGNMENT);
+      assertFalse(javaSettings.SPACE_BEFORE_METHOD_PARENTHESES);
+      assertFalse(javaSettings.SPACE_WITHIN_CATCH_PARENTHESES);
+      assertFalse(javaSettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES);
+      assertFalse(javaSettings.SPACE_WITHIN_CATCH_PARENTHESES);
+      assertFalse(javaSettings.SPACE_AROUND_UNARY_OPERATOR);
+      assertTrue(javaSettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
+      assertFalse(editorSettings.isEnsureNewLineAtEOF());
+      assertFalse(javaSettings.ALIGN_MULTILINE_BINARY_OPERATION);
+      assertFalse(javaSettings.SPACE_WITHIN_TRY_PARENTHESES);
+      assertFalse(javaSettings.SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES);
+      assertFalse(javaSettings.WHILE_ON_NEW_LINE);
+      assertTrue(settings.ENABLE_JAVADOC_FORMATTING);
+      assertFalse(javaSettings.SPACE_BEFORE_SEMICOLON);
+      assertEquals(0, javaSettings.BLANK_LINES_BEFORE_METHOD_BODY);
+      assertTrue(javaSettings.SPACE_BEFORE_COLON);
+      assertFalse(javaSettings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS);
+      assertTrue(javaSettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE);
+      assertFalse(javaSettings.SPACE_WITHIN_SYNCHRONIZED_PARENTHESES);
+      assertTrue(javaSettings.SPACE_BEFORE_QUEST);
+      assertEquals(1, javaSettings.BLANK_LINES_BEFORE_IMPORTS);
+      assertFalse(javaSettings.ALIGN_MULTILINE_THROWS_LIST);
+      assertTrue(javaSettings.SPACE_AFTER_COLON);
+      assertFalse(javaSettings.SPACE_WITHIN_FOR_PARENTHESES);
+      assertTrue(javaSettings.SPACE_BEFORE_SYNCHRONIZED_PARENTHESES);
+      assertFalse(javaSettings.ALIGN_MULTILINE_PARAMETERS);
+      assertFalse(javaSettings.ALIGN_MULTILINE_RESOURCES);
+      assertTrue(javaSettings.SPACE_BEFORE_SWITCH_PARENTHESES);
+      assertFalse(javaSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES);
+      assertEquals(CommonCodeStyleSettings.END_OF_LINE, javaSettings.CLASS_BRACE_STYLE);
+      assertTrue(javaSettings.SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE);
+      assertFalse(javaSettings.SPACE_WITHIN_METHOD_PARENTHESES);
+      assertTrue(javaSettings.SPACE_BEFORE_CATCH_PARENTHESES);
+      assertFalse(javaSettings.SPACE_WITHIN_ANNOTATION_PARENTHESES);
+      assertEquals(1, javaSettings.BLANK_LINES_AFTER_IMPORTS);
+      assertFalse(javaSettings.KEEP_FIRST_COLUMN_COMMENT);
+      assertFalse(javaSettings.KEEP_CONTROL_STATEMENT_IN_ONE_LINE);
+      assertTrue(indentOptions.USE_TAB_CHARACTER);
+      assertTrue(indentOptions.SMART_TABS);
+    }
+    finally {
+      inputStream.close();
+      schemes.deleteScheme(scheme);
+      editorSettings.setEnsureNewLineAtEOF(currAddLineFeed);
+    }
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
index b3b1cc6..8ef616b 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
@@ -22,6 +22,7 @@
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.settings.DistributionType;
 import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
 import org.jetbrains.plugins.gradle.settings.GradleSettings;
 import org.jetbrains.plugins.gradle.util.GradleEnvironment;
@@ -122,32 +123,34 @@
       return null;
     }
     GradleProjectSettings settings = GradleSettings.getInstance(project).getLinkedProjectSettings(linkedProjectPath);
-    if (settings == null) {
+    if (settings == null || settings.getDistributionType() == null) {
       return null;
     }
+    return getGradleHome(settings.getDistributionType(), linkedProjectPath, settings.getGradleHome());
+  }
 
+  @Nullable
+  public File getGradleHome(@NotNull DistributionType distributionType, @NotNull String linkedProjectPath, @Nullable String gradleHome) {
     File candidate = null;
-    if (settings.getDistributionType() != null) {
-      switch (settings.getDistributionType()) {
-        case LOCAL:
-          if (settings.getGradleHome() != null) {
-            candidate = new File(settings.getGradleHome());
-          }
-          break;
-        case DEFAULT_WRAPPED:
-          WrapperConfiguration wrapperConfiguration = GradleUtil.getWrapperConfiguration(linkedProjectPath);
-          candidate = getWrappedGradleHome(linkedProjectPath, wrapperConfiguration);
-          break;
-        case WRAPPED:
-          // not supported yet
-          break;
-        case BUNDLED:
-          WrapperConfiguration bundledWrapperSettings = new WrapperConfiguration();
-          DistributionLocator distributionLocator = new DistributionLocator();
-          bundledWrapperSettings.setDistribution(distributionLocator.getDistributionFor(GradleVersion.current()));
-          candidate = getWrappedGradleHome(linkedProjectPath, bundledWrapperSettings);
-          break;
-      }
+    switch (distributionType) {
+      case LOCAL:
+        if (gradleHome != null) {
+          candidate = new File(gradleHome);
+        }
+        break;
+      case DEFAULT_WRAPPED:
+        WrapperConfiguration wrapperConfiguration = GradleUtil.getWrapperConfiguration(linkedProjectPath);
+        candidate = getWrappedGradleHome(linkedProjectPath, wrapperConfiguration);
+        break;
+      case WRAPPED:
+        // not supported yet
+        break;
+      case BUNDLED:
+        WrapperConfiguration bundledWrapperSettings = new WrapperConfiguration();
+        DistributionLocator distributionLocator = new DistributionLocator();
+        bundledWrapperSettings.setDistribution(distributionLocator.getDistributionFor(GradleVersion.current()));
+        candidate = getWrappedGradleHome(linkedProjectPath, bundledWrapperSettings);
+        break;
     }
 
     File result = 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 c0873f7..9c9e361 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
@@ -444,9 +444,7 @@
     ProjectData projectData = rootProjectNode.getData();
     final String rootProjectPath = projectData.getLinkedExternalProjectPath();
     Map<String/* module name */, Collection<TaskData>> tasksByModule = ContainerUtilRt.newHashMap();
-    TObjectIntHashMap<Pair<String/* task name */, String /* task description */>> rootProjectTaskCandidates
-      = new TObjectIntHashMap<Pair<String, String>>();
-    final Collection<TaskData> rootProjectTasks = ContainerUtilRt.newArrayList();
+    Set<Pair<String/* task name */, String /* task description */>> rootProjectTaskCandidates = ContainerUtilRt.newHashSet();
     final DomainObjectSet<? extends IdeaModule> modules = project.getModules();
     for (IdeaModule module : modules) {
       String moduleConfigPath = GradleUtil.getConfigPath(module.getGradleProject(), rootProjectPath);
@@ -462,39 +460,28 @@
         }
 
         TaskData taskData = new TaskData(GradleConstants.SYSTEM_ID, name, moduleConfigPath, task.getDescription());
-        
-        if (rootProjectPath.equals(moduleConfigPath)) {
-          rootProjectTasks.add(taskData);
+
+        Collection<TaskData> tasks = tasksByModule.get(module.getName());
+        if (tasks == null) {
+          tasksByModule.put(module.getName(), tasks = ContainerUtilRt.newArrayList());
         }
-        else {
-          Collection<TaskData> tasks = tasksByModule.get(module.getName());
-          if (tasks == null) {
-            tasksByModule.put(module.getName(), tasks = ContainerUtilRt.newArrayList());
-          }
-          tasks.add(taskData);
-          Pair<String, String> key = Pair.create(name, task.getDescription());
-          rootProjectTaskCandidates.put(key, rootProjectTaskCandidates.get(key) + 1);
-        }
+        tasks.add(taskData);
+        rootProjectTaskCandidates.add(Pair.create(name, task.getDescription()));
       }
     }
-    rootProjectTaskCandidates.forEachEntry(new TObjectIntProcedure<Pair<String, String>>() {
-      @Override
-      public boolean execute(Pair<String, String> p, int occurrenceNumber) {
-        if (modules.size() == 1 || occurrenceNumber >= modules.size() - 1) {
-          rootProjectTasks.add(new TaskData(GradleConstants.SYSTEM_ID, p.first, rootProjectPath, p.second));
-        }
-        return true;
-      }
-    });
-    for (TaskData task : rootProjectTasks) {
-      rootProjectNode.createChild(ProjectKeys.TASK, task);
+
+    for(Pair<String, String> p : rootProjectTaskCandidates) {
+      rootProjectNode.createChild(ProjectKeys.TASK, new TaskData(GradleConstants.SYSTEM_ID, p.first, rootProjectPath, p.second));
     }
 
     Collection<DataNode<ModuleData>> moduleNodes = ExternalSystemApiUtil.findAll(rootProjectNode, ProjectKeys.MODULE);
     for (DataNode<ModuleData> moduleNode : moduleNodes) {
       ModuleData moduleData = moduleNode.getData();
-      if (rootProjectPath.equals(moduleData.getLinkedExternalProjectPath()) && !projectData.getName().equals(moduleData.getName())) {
-        moduleData.setName(projectData.getName());
+      if (rootProjectPath.equals(moduleData.getLinkedExternalProjectPath())) {
+        if (!projectData.getName().equals(moduleData.getName())) {
+          moduleData.setName(projectData.getName());
+        }
+        continue;
       }
       Collection<TaskData> tasks = tasksByModule.get(moduleData.getName());
       if (tasks != null && !tasks.isEmpty()) {
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 6bebf3a6..d5a20ed 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
@@ -22,11 +22,15 @@
  * @since 9/3/13
  */
 public final class GradleCommonClassNames {
+  @NonNls public static final String GRADLE_API_SCRIPT = "org.gradle.api.Script";
   @NonNls public static final String GRADLE_API_PROJECT = "org.gradle.api.Project";
   @NonNls public static final String GRADLE_API_CONFIGURATION_CONTAINER = "org.gradle.api.artifacts.ConfigurationContainer";
   @NonNls public static final String GRADLE_API_CONFIGURATION = "org.gradle.api.artifacts.Configuration";
   @NonNls public static final String GRADLE_API_ARTIFACT_HANDLER = "org.gradle.api.artifacts.dsl.ArtifactHandler";
   @NonNls public static final String GRADLE_API_DEPENDENCY_HANDLER = "org.gradle.api.artifacts.dsl.DependencyHandler";
+  @NonNls public static final String GRADLE_API_ARTIFACTS_EXTERNAL_MODULE_DEPENDENCY = "org.gradle.api.artifacts.ExternalModuleDependency";
+  @NonNls public static final String GRADLE_API_ARTIFACTS_MODULE_DEPENDENCY = "org.gradle.api.artifacts.ModuleDependency";
+  @NonNls public static final String GRADLE_API_ARTIFACTS_DEPENDENCY_ARTIFACT = "org.gradle.api.artifacts.DependencyArtifact";
   @NonNls public static final String GRADLE_API_REPOSITORY_HANDLER = "org.gradle.api.artifacts.dsl.RepositoryHandler";
   @NonNls public static final String GRADLE_API_SOURCE_DIRECTORY_SET = "org.gradle.api.file.SourceDirectorySet";
   @NonNls public static final String GRADLE_API_SOURCE_SET = "org.gradle.api.tasks.SourceSet";
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java
index 161e4c7..7685a25 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java
@@ -15,75 +15,72 @@
  */
 package org.jetbrains.plugins.gradle.service.resolve;
 
-import com.intellij.psi.*;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.ResolveState;
 import com.intellij.psi.scope.PsiScopeProcessor;
-import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
 import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
-import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
-import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter;
 
 import java.util.List;
+import java.util.Set;
 
 /**
  * @author Denis Zhdanov
  * @since 8/14/13 12:58 PM
  */
 public class GradleDependenciesContributor implements GradleMethodContextContributor {
+  private final static Set<String> BUILD_SCRIPT_BLOCKS = ContainerUtil.newHashSet(
+    "subprojects",
+    "allprojects",
+    "buildscript"
+  );
 
   @Override
   public void process(@NotNull List<String> methodCallInfo,
                       @NotNull PsiScopeProcessor processor,
                       @NotNull ResolveState state,
                       @NotNull PsiElement place) {
-    if (methodCallInfo.isEmpty()) {
-      return;
+    if (methodCallInfo.isEmpty()) return;
+
+    String methodCall = ContainerUtil.getLastItem(methodCallInfo);
+    if (methodCall == null) return;
+
+    if (methodCallInfo.size() > 1 && BUILD_SCRIPT_BLOCKS.contains(methodCall)) {
+      methodCallInfo.remove(methodCallInfo.size() - 1);
+      methodCall = ContainerUtil.getLastItem(methodCallInfo);
     }
 
-    int i = methodCallInfo.indexOf("dependencies");
-    if (i != 1) {
-      return;
-    }
+    if (!StringUtil.equals(methodCall, "dependencies")) return;
 
-    // Assuming that the method call is addition of new dependency into configuration.
-    GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
-    PsiClass contributorClass =
-      psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_DEPENDENCY_HANDLER, place.getResolveScope());
-    if (contributorClass == null) {
-      return;
-    }
-    processDependencyAddition(methodCallInfo.get(0), contributorClass, processor, state, place);
-  }
-
-  private static void processDependencyAddition(@NotNull String gradleConfigurationName,
-                                                @NotNull PsiClass dependencyHandlerClass,
-                                                @NotNull PsiScopeProcessor processor,
-                                                @NotNull ResolveState state,
-                                                @NotNull PsiElement place) {
-    GrLightMethodBuilder builder = new GrLightMethodBuilder(place.getManager(), gradleConfigurationName);
-    PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getManager().getProject());
-    PsiType type = new PsiArrayType(factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope()));
-    builder.addParameter(new GrLightParameter("dependencyInfo", type, builder));
-    processor.execute(builder, state);
-
-    GrMethodCall call = PsiTreeUtil.getParentOfType(place, GrMethodCall.class);
-    if (call == null) {
-      return;
-    }
-    GrArgumentList args = call.getArgumentList();
-    if (args == null) {
-      return;
-    }
-
-    int argsCount = GradleResolverUtil.getGrMethodArumentsCount(args);
-    argsCount++; // Configuration name is delivered as an argument.
-
-    for (PsiMethod method : dependencyHandlerClass.findMethodsByName("add", false)) {
-      if (method.getParameterList().getParametersCount() == argsCount) {
-        builder.setNavigationElement(method);
+    final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
+    if (methodCallInfo.size() == 2) {
+      PsiClass psiClass =
+        psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_ARTIFACTS_EXTERNAL_MODULE_DEPENDENCY, place.getResolveScope());
+      if (psiClass != null) {
+        psiClass.processDeclarations(processor, state, null, place);
       }
+      // Assuming that the method call is addition of new dependency into configuration.
+      PsiClass contributorClass =
+        psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_DEPENDENCY_HANDLER, place.getResolveScope());
+      if (contributorClass == null) return;
+      GradleResolverUtil.processMethod(methodCallInfo.get(0), contributorClass, processor, state, place, "add");
+    }
+    else if (methodCallInfo.size() == 3) {
+      GradleResolverUtil.processDeclarations(psiManager, processor, state, place,
+                                             GradleCommonClassNames.GRADLE_API_DEPENDENCY_HANDLER,
+                                             GradleCommonClassNames.GRADLE_API_ARTIFACTS_EXTERNAL_MODULE_DEPENDENCY,
+                                             GradleCommonClassNames.GRADLE_API_ARTIFACTS_DEPENDENCY_ARTIFACT,
+                                             GradleCommonClassNames.GRADLE_API_PROJECT);
+    }
+    else if (methodCallInfo.size() == 4) {
+      // Assuming that the method call is addition of new dependency into configuration.
+      PsiClass contributorClass =
+        psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_DEPENDENCY_HANDLER, place.getResolveScope());
+      if (contributorClass == null) return;
+      GradleResolverUtil.processMethod(methodCallInfo.get(0), contributorClass, processor, state, place, "add");
     }
   }
 }
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java
index c44810e..ace5839 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java
@@ -17,11 +17,14 @@
 
 import com.intellij.psi.*;
 import com.intellij.psi.scope.PsiScopeProcessor;
+import com.intellij.psi.util.PsiTreeUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
 import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceExpressionImpl;
 import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrImplicitVariableImpl;
 import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
@@ -77,10 +80,73 @@
     GrLightParameter closureParameter = new GrLightParameter("closure", closureType, methodWithClosure);
     methodWithClosure.addParameter(closureParameter);
 
-    if (returnType != null) {
-      PsiClassType retType = factory.createTypeByFQClassName(returnType, place.getResolveScope());
-      methodWithClosure.setReturnType(retType);
-    }
+    PsiClassType retType = factory.createTypeByFQClassName(
+      returnType != null ? returnType : CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope());
+    methodWithClosure.setReturnType(retType);
     return methodWithClosure;
   }
+
+  public static void processMethod(@NotNull String gradleConfigurationName,
+                                   @NotNull PsiClass dependencyHandlerClass,
+                                   @NotNull PsiScopeProcessor processor,
+                                   @NotNull ResolveState state,
+                                   @NotNull PsiElement place) {
+    processMethod(gradleConfigurationName, dependencyHandlerClass, processor, state, place, null);
+  }
+
+  public static void processMethod(@NotNull String gradleConfigurationName,
+                                   @NotNull PsiClass dependencyHandlerClass,
+                                   @NotNull PsiScopeProcessor processor,
+                                   @NotNull ResolveState state,
+                                   @NotNull PsiElement place,
+                                   @Nullable String defaultMethodName) {
+    GrLightMethodBuilder builder = new GrLightMethodBuilder(place.getManager(), gradleConfigurationName);
+    PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getManager().getProject());
+    PsiType type = new PsiArrayType(factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope()));
+    builder.addParameter(new GrLightParameter("param", type, builder));
+    PsiClassType retType = factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope());
+    builder.setReturnType(retType);
+    processor.execute(builder, state);
+
+    GrMethodCall call = PsiTreeUtil.getParentOfType(place, GrMethodCall.class);
+    if (call == null) {
+      return;
+    }
+    GrArgumentList args = call.getArgumentList();
+    if (args == null) {
+      return;
+    }
+
+    int argsCount = getGrMethodArumentsCount(args);
+    argsCount++; // Configuration name is delivered as an argument.
+
+    for (PsiMethod method : dependencyHandlerClass.findMethodsByName(gradleConfigurationName, false)) {
+      if (method.getParameterList().getParametersCount() == argsCount) {
+        builder.setNavigationElement(method);
+        return;
+      }
+    }
+
+    if (defaultMethodName != null) {
+      for (PsiMethod method : dependencyHandlerClass.findMethodsByName(defaultMethodName, false)) {
+        if (method.getParameterList().getParametersCount() == argsCount) {
+          builder.setNavigationElement(method);
+          return;
+        }
+      }
+    }
+  }
+
+  public static void processDeclarations(@NotNull GroovyPsiManager psiManager,
+                                         @NotNull PsiScopeProcessor processor,
+                                         @NotNull ResolveState state,
+                                         @NotNull PsiElement place,
+                                         @NotNull String... fqNames) {
+    for (String fqName : fqNames) {
+      PsiClass psiClass = psiManager.findClassWithCache(fqName, place.getResolveScope());
+      if (psiClass != null) {
+        psiClass.processDeclarations(processor, state, null, place);
+      }
+    }
+  }
 }
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java
index 655a05f..8599392 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java
@@ -75,6 +75,7 @@
     MyState state = new MyState();
     fillState(state);
     state.serviceDirectoryPath = myServiceDirectoryPath;
+    state.gradleVmOptions = myGradleVmOptions;
     return state;
   }
 
@@ -82,6 +83,7 @@
   public void loadState(MyState state) {
     super.loadState(state);
     myServiceDirectoryPath = state.serviceDirectoryPath;
+    myGradleVmOptions = state.gradleVmOptions;
   }
 
   /**
@@ -130,6 +132,7 @@
 
     private Set<GradleProjectSettings> myProjectSettings = ContainerUtilRt.newTreeSet();
     public String serviceDirectoryPath;
+    public String gradleVmOptions;
 
     @AbstractCollection(surroundWithTag = false, elementTypes = {GradleProjectSettings.class})
     public Set<GradleProjectSettings> getLinkedExternalProjectsSettings() {
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 9ae01a8..bc60ac5 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -167,7 +167,7 @@
     <groovyFrameworkConfigNotification implementation="org.jetbrains.plugins.groovy.griffon.GriffonConfigureNotification"/>
     <defaultImportContributor implementation="org.jetbrains.plugins.groovy.griffon.GriffonDefaultImportContributor"/>
 
-    <groovyShellRunner implementation="org.jetbrains.plugins.groovy.console.DefaultGroovyShellRunner" order="last"/>
+    <groovyShellRunner implementation="org.jetbrains.plugins.groovy.console.GroovyConsoleRunner" order="last"/>
 
     <closureCompleter implementation="org.jetbrains.plugins.groovy.lang.completion.GdslClosureCompleter"/>
     <closureCompleter implementation="org.jetbrains.plugins.groovy.lang.completion.EachWithIndexClosureCompleter"/>
@@ -1444,6 +1444,8 @@
                                      implementation="org.jetbrains.plugins.groovy.springloaded.SpringLoadedPositionManagerFactory"/>
     <codeStyle.ReferenceAdjuster language="Groovy" implementationClass="org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster"/>
     <codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.groovy.jarFinder.GroovyFindJarQuickFixProvider"/>
+    <lang.refactoringSupport.classMembersRefactoringSupport language="Groovy"
+                                                            implementationClass="org.jetbrains.plugins.groovy.refactoring.classMembers.GroovyClassMembersRefactoringSupport"/>
   </extensions>
 
   <extensions defaultExtensionNs="com.intellij.debugger">
@@ -1547,13 +1549,20 @@
             icon="JetgroovyIcons.Groovy.GroovyDoc">
       <add-to-group group-id="ToolsMenu" anchor="last"/>
     </action>
-    <action id="Groovy.Console"
+    <action id="Groovy.Shell"
             class="org.jetbrains.plugins.groovy.console.GroovyShellAction"
             text="Groovy Shell..." description="Launch Groovy Shell"
             icon="JetgroovyIcons.Groovy.Groovy_16x16">
       <add-to-group group-id="ToolsMenu" anchor="last"/>
     </action>
 
+    <action id="Groovy.Console"
+            class="org.jetbrains.plugins.groovy.console.GroovyConsoleAction"
+            text="Groovy Console..." description="Launch Groovy Console"
+            icon="JetgroovyIcons.Groovy.Groovy_16x16">
+      <add-to-group group-id="ToolsMenu" anchor="last"/>
+    </action>
+
     <group id="Mvc.Actions" popup="true" class="org.jetbrains.plugins.groovy.mvc.MvcActionGroup">
       <action id="Mvc.Upgrade"
               class="org.jetbrains.plugins.groovy.mvc.MvcUpgradeAction"
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties
index 05ba87c..a2704e2 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties
@@ -368,3 +368,4 @@
 annotation.attribute.expected=Annotation attribute expected
 highlight.constructor.calls.of.a.non.static.inner.classes.without.enclosing.instance.passed=Highlight constructor calls of non-static inner classes without enclosing instance passed
 doc.end.expected='*/' expected
+mixing.private.and.public.protected.methods.of.the.same.name=Mixing private and public/protected methods of the same name
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
index 748f7c8..de7bb9e 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
@@ -391,6 +391,39 @@
     checkConstructors(myHolder, typeDefinition);
 
     checkAnnotationCollector(myHolder, typeDefinition);
+
+    checkSameNameMethodsWithDifferentAccessModifiers(myHolder, typeDefinition.getCodeMethods());
+  }
+
+  private static void checkSameNameMethodsWithDifferentAccessModifiers(AnnotationHolder holder, GrMethod[] methods) {
+    MultiMap<String, GrMethod> map = MultiMap.create();
+    for (GrMethod method : methods) {
+      map.putValue(method.getName(), method);
+    }
+
+    for (Map.Entry<String, Collection<GrMethod>> entry : map.entrySet()) {
+      Collection<GrMethod> collection = entry.getValue();
+      if (collection.size() > 1 && !sameAccessModifier(collection)) {
+        for (GrMethod method : collection) {
+          holder.createErrorAnnotation(GrHighlightUtil.getMethodHeaderTextRange(method), GroovyBundle.message("mixing.private.and.public.protected.methods.of.the.same.name"));
+        }
+      }
+    }
+  }
+
+  private static boolean sameAccessModifier(Collection<GrMethod> collection) {
+    Iterator<GrMethod> iterator = collection.iterator();
+    GrMethod method = iterator.next();
+    boolean  privateAccess = PsiModifier.PRIVATE.equals(VisibilityUtil.getVisibilityModifier(method.getModifierList()));
+
+    while (iterator.hasNext()) {
+      GrMethod next = iterator.next();
+      if (privateAccess != PsiModifier.PRIVATE.equals(VisibilityUtil.getVisibilityModifier(next.getModifierList()))) {
+        return false;
+      }
+    }
+
+    return true;
   }
 
   private static void checkAnnotationCollector(AnnotationHolder holder, GrTypeDefinition definition) {
@@ -1345,6 +1378,7 @@
     final PsiClass scriptClass = file.getScriptClass();
     if (scriptClass != null) {
       checkDuplicateMethod(scriptClass, myHolder);
+      checkSameNameMethodsWithDifferentAccessModifiers(myHolder, file.getCodeMethods());
     }
   }
 
@@ -1430,6 +1464,7 @@
   private boolean checkAnnotationAttributeValue(GrAnnotationMemberValue value, PsiElement toHighlight) {
     if (value instanceof GrLiteral) return false;
     if (value instanceof GrClosableBlock) return false;
+    if (value instanceof GrAnnotation) return false;
 
     if (value instanceof GrReferenceExpression) {
       PsiElement resolved = ((GrReferenceExpression)value).resolve();
@@ -1619,7 +1654,7 @@
 
   private static void checkGrDocReferenceElement(AnnotationHolder holder, PsiElement element) {
     ASTNode node = element.getNode();
-    if (node != null && TokenSets.BUILT_IN_TYPE.contains(node.getElementType())) {
+    if (node != null && TokenSets.BUILT_IN_TYPES.contains(node.getElementType())) {
       Annotation annotation = holder.createInfoAnnotation(element, null);
       annotation.setTextAttributes(KEYWORD);
     }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/DefaultGroovyShellRunner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/DefaultGroovyShellRunner.java
index 58b672d1..39aa7a0 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/DefaultGroovyShellRunner.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/DefaultGroovyShellRunner.java
@@ -19,6 +19,7 @@
 import com.intellij.execution.configurations.JavaParameters;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.JavaPsiFacade;
 import com.intellij.psi.search.GlobalSearchScope;
@@ -51,15 +52,14 @@
     boolean useBundled = !hasGroovyAll(module);
     DefaultGroovyScriptRunner.configureGenericGroovyRunner(res, module, "org.codehaus.groovy.tools.shell.Main", false, true);
     if (useBundled) {
-      String parent = GroovyUtils.getBundledGroovyJar().getParent();
-      String groovyHome = parent + File.separator + "groovy";
-      File libDir = new File(groovyHome + File.separator + "lib");
+      String libRoot = GroovyUtils.getBundledGroovyJar().getParent();
+      File libDir = new File(libRoot + "/groovy/lib");
       assert libDir.isDirectory();
       for (File file : libDir.listFiles()) {
         res.getClassPath().add(file);
       }
 
-      GroovyScriptRunner.setGroovyHome(res, groovyHome);
+      GroovyScriptRunner.setGroovyHome(res, FileUtil.toCanonicalPath(libRoot  + "/groovy"));
     }
     res.setWorkingDirectory(getWorkingDirectory(module));
 
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyConsoleAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyConsoleAction.java
new file mode 100644
index 0000000..308f932
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyConsoleAction.java
@@ -0,0 +1,52 @@
+/*
+ * 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.console;
+
+import com.intellij.execution.console.LanguageConsoleImpl;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.intellij.testFramework.LightVirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.GroovyFileType;
+import org.jetbrains.plugins.groovy.debugger.fragments.GroovyCodeFragment;
+
+/**
+ * Created by Max Medvedev on 9/20/13
+ */
+public class GroovyConsoleAction extends GroovyShellActionBase {
+  @Override
+  protected GroovyShellRunner getRunner(Module module) {
+    return GroovyShellRunner.getAppropriateRunner(module);
+  }
+
+  @Override
+  public String getTitle() {
+    return "Groovy Console";
+  }
+
+  @Override
+  protected LanguageConsoleImpl createConsole(Project project, String title) {
+    return new LanguageConsoleImpl(project, title, GroovyFileType.GROOVY_LANGUAGE) {
+      @NotNull
+      @Override
+      protected PsiFile createFile(@NotNull LightVirtualFile virtualFile, @NotNull Document document, @NotNull Project project) {
+        return new GroovyCodeFragment(getProject(), virtualFile);
+      }
+    };
+  }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyConsoleRunner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyConsoleRunner.java
new file mode 100644
index 0000000..bf46a21
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyConsoleRunner.java
@@ -0,0 +1,95 @@
+/*
+ * 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.console;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.JavaParameters;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.PathsList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.config.AbstractConfigUtils;
+import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
+import org.jetbrains.plugins.groovy.runner.DefaultGroovyScriptRunner;
+import org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfiguration;
+import org.jetbrains.plugins.groovy.runner.GroovyScriptRunner;
+import org.jetbrains.plugins.groovy.util.GroovyUtils;
+import org.jetbrains.plugins.groovy.util.LibrariesUtil;
+
+/**
+ * @author Max Medvedev
+ */
+public class GroovyConsoleRunner extends GroovyShellRunner {
+  @NotNull
+  @Override
+  public String getWorkingDirectory(@NotNull Module module) {
+    VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
+    return contentRoots[0].getPath();
+  }
+
+  @NotNull
+  @Override
+  public JavaParameters createJavaParameters(@NotNull Module module) throws ExecutionException {
+    JavaParameters res = GroovyScriptRunConfiguration.createJavaParametersWithSdk(module);
+    DefaultGroovyScriptRunner.configureGenericGroovyRunner(res, module, "groovy.ui.GroovyMain", !hasGroovyAll(module), true);
+    PathsList list = GroovyScriptRunner.getClassPathFromRootModel(module, true, res, true, res.getClassPath());
+    if (list != null) {
+      res.getClassPath().addAll(list.getPathList());
+    }
+    res.getProgramParametersList().addAll("-p", GroovyScriptRunner.getPathInConf("console.txt"));
+    //res.getVMParametersList().add("-Xdebug"); res.getVMParametersList().add("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5239");
+    res.setWorkingDirectory(getWorkingDirectory(module));
+
+    return res;
+  }
+
+  @Override
+  public boolean canRun(@NotNull Module module) {
+    VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
+    return contentRoots.length > 0;
+  }
+
+  @NotNull
+  @Override
+  public String getTitle(@NotNull Module module) {
+    String homePath = LibrariesUtil.getGroovyHomePath(module);
+    boolean bundled = false;
+    if (homePath == null || !hasGroovyAll(module)) {
+      homePath = GroovyUtils.getBundledGroovyJar().getParentFile().getParent();
+      bundled = true;
+    }
+    String version = GroovyConfigUtils.getInstance().getSDKVersion(homePath);
+    return version == AbstractConfigUtils.UNDEFINED_VERSION ? "" : " (" + (bundled ? "Bundled " : "") + "Groovy " + version + ")";
+  }
+
+  private static boolean hasGroovyAll(Module module) {
+    GlobalSearchScope scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module);
+    JavaPsiFacade facade = JavaPsiFacade.getInstance(module.getProject());
+    return (facade.findClass("org.apache.commons.cli.CommandLineParser", scope) != null ||
+            facade.findClass("groovyjarjarcommonscli.CommandLineParser", scope) != null) &&
+           facade.findClass("groovy.ui.GroovyMain", scope) != null;
+  }
+
+  @NotNull
+  @Override
+  public String transformUserInput(@NotNull String userInput) {
+    return StringUtil.replace(userInput, "\n", "###\\n");
+  }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellAction.java
index 289977c..835687a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellAction.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellAction.java
@@ -15,218 +15,49 @@
  */
 package org.jetbrains.plugins.groovy.console;
 
-import com.intellij.execution.ExecutionException;
-import com.intellij.execution.configurations.JavaParameters;
-import com.intellij.execution.console.ConsoleHistoryController;
-import com.intellij.execution.console.LanguageConsoleViewImpl;
-import com.intellij.execution.process.OSProcessHandler;
-import com.intellij.execution.runners.AbstractConsoleRunnerWithHistory;
-import com.intellij.execution.runners.ConsoleExecuteActionHandler;
-import com.intellij.ide.util.PropertiesComponent;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.compiler.CompileContext;
-import com.intellij.openapi.compiler.CompileStatusNotification;
-import com.intellij.openapi.compiler.CompilerManager;
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.JavaSdkType;
-import com.intellij.openapi.projectRoots.JdkUtil;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.projectRoots.SdkTypeId;
-import com.intellij.openapi.roots.ModuleRootManager;
-import com.intellij.openapi.roots.ui.configuration.ModulesAlphaComparator;
-import com.intellij.openapi.ui.Messages;
-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.util.Key;
-import com.intellij.util.PlatformIcons;
-import icons.JetgroovyIcons;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl;
-import org.jetbrains.plugins.groovy.util.GroovyUtils;
-
-import java.util.*;
 
 /**
  * @author peter
  */
-public class GroovyShellAction extends DumbAwareAction {
-  private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.console.GroovyShellAction");
-
-  private static final String GROOVY_SHELL_LAST_MODULE = "Groovy.Shell.LastModule";
-  public static final Key<Boolean> GROOVY_SHELL_FILE = Key.create("GROOVY_SHELL_FILE");
-
-  private static List<Module> getGroovyCompatibleModules(Project project) {
-    ArrayList<Module> result = new ArrayList<Module>();
-    for (Module module : ModuleManager.getInstance(project).getModules()) {
-      if (GroovyUtils.isSuitableModule(module)) {
-        Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
-        if (sdk != null && sdk.getSdkType() instanceof JavaSdkType) {
-          result.add(module);
-        }
-      }
-    }
-    return result;
+public class GroovyShellAction extends GroovyShellActionBase {
+  protected GroovyShellRunner getRunner(Module module) {
+    return new DefaultGroovyShellRunner();
   }
 
   @Override
-  public void update(AnActionEvent e) {
-    final Project project = e.getData(CommonDataKeys.PROJECT);
-
-    boolean enabled = project != null && !getGroovyCompatibleModules(project).isEmpty();
-
-    e.getPresentation().setEnabled(enabled);
-    e.getPresentation().setVisible(enabled);
+  public String getTitle() {
+    return "Groovy Shell";
   }
 
   @Override
-  public void actionPerformed(AnActionEvent e) {
-    final Project project = e.getData(CommonDataKeys.PROJECT);
-    assert project != null;
+  protected GroovyShellConsoleImpl createConsole(Project project, String title) {
+    final GroovyShellConsoleImpl console = new GroovyShellConsoleImpl(project, title);
 
-    CompilerManager.getInstance(project).make(new CompileStatusNotification() {
+    /*UiNotifyConnector.doWhenFirstShown(console.getComponent(), new Runnable() {
       @Override
-      public void finished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
-        if (aborted) return;
-
-        final Project project = compileContext.getProject();
-
-        if (errors == 0 ||
-            Messages.showYesNoDialog(project, "Compilation failed with errors. Do you want to run Groovy shell anyway?", "Groovy Shell",
-                                     JetgroovyIcons.Groovy.Groovy_32x32) == Messages.YES) {
-          runGroovyShell(project);
-        }
-      }
-    });
-  }
-
-  private static void runGroovyShell(Project project) {
-    List<Module> modules = new ArrayList<Module>();
-    final Map<Module, String> versions = new HashMap<Module, String>();
-
-    for (Module module : getGroovyCompatibleModules(project)) {
-      GroovyShellRunner runner = GroovyShellRunner.getAppropriateRunner(module);
-      if (runner != null) {
-        modules.add(module);
-        versions.put(module, runner.getTitle(module));
-      }
-    }
-
-    if (modules.size() == 1) {
-      doRun(modules.get(0));
-      return;
-    }
-
-    Collections.sort(modules, ModulesAlphaComparator.INSTANCE);
-
-    BaseListPopupStep<Module> step =
-      new BaseListPopupStep<Module>("Which module to use classpath of?", modules, PlatformIcons.CONTENT_ROOT_ICON_CLOSED) {
-        @NotNull
-        @Override
-        public String getTextFor(Module value) {
-          return value.getName() + versions.get(value);
-        }
-
-        @Override
-        public String getIndexedString(Module value) {
-          return value.getName();
-        }
-
-        @Override
-        public boolean isSpeedSearchEnabled() {
-          return true;
-        }
-
-        @Override
-        public PopupStep onChosen(Module selectedValue, boolean finalChoice) {
-          PropertiesComponent.getInstance(selectedValue.getProject()).setValue(GROOVY_SHELL_LAST_MODULE, selectedValue.getName());
-          doRun(selectedValue);
-          return null;
-        }
-      };
-    for (int i = 0; i < modules.size(); i++) {
-      Module module = modules.get(i);
-      if (module.getName().equals(PropertiesComponent.getInstance(project).getValue(GROOVY_SHELL_LAST_MODULE))) {
-        step.setDefaultOptionIndex(i);
-        break;
-      }
-    }
-    JBPopupFactory.getInstance().createListPopup(step).showCenteredInCurrentWindow(project);
-  }
-
-  private static void doRun(final Module module) {
-    final GroovyShellRunner shellRunner = GroovyShellRunner.getAppropriateRunner(module);
-    if (shellRunner == null) return;
-
-    AbstractConsoleRunnerWithHistory<GroovyConsoleView> runner =
-      new AbstractConsoleRunnerWithHistory<GroovyConsoleView>(module.getProject(), "Groovy Shell", shellRunner.getWorkingDirectory(module)) {
-
-        @Override
-        protected GroovyConsoleView createConsoleView() {
-          GroovyConsoleView res = new GroovyConsoleView(getProject());
-
-          GroovyFileImpl file = (GroovyFileImpl)res.getConsole().getFile();
-          assert file.getContext() == null;
-          file.putUserData(GROOVY_SHELL_FILE, Boolean.TRUE);
-
-          file.setContext(shellRunner.getContext(module));
-
-          return res;
-        }
-
-        @Override
-        protected Process createProcess() throws ExecutionException {
-          JavaParameters javaParameters = shellRunner.createJavaParameters(module);
-
-          final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
-          assert sdk != null;
-          SdkTypeId sdkType = sdk.getSdkType();
-          assert sdkType instanceof JavaSdkType;
-          final String exePath = ((JavaSdkType)sdkType).getVMExecutablePath(sdk);
-
-          return JdkUtil.setupJVMCommandLine(exePath, javaParameters, true).createProcess();
-        }
-
-        @Override
-        protected OSProcessHandler createProcessHandler(Process process) {
-          return new OSProcessHandler(process);
-        }
-
-        @NotNull
-        @Override
-        protected ConsoleExecuteActionHandler createConsoleExecuteActionHandler() {
-          ConsoleExecuteActionHandler handler = new ConsoleExecuteActionHandler(getProcessHandler(), false) {
+      public void run() {
+        final String key = "groovy.shell.is.really.groovy.shell";
+        if (!PropertiesComponent.getInstance().isTrueValue(key)) {
+          final Alarm alarm = new Alarm();
+          alarm.addRequest(new Runnable() {
             @Override
-            public void processLine(String line) {
-              super.processLine(shellRunner.transformUserInput(line));
-            }
+            public void run() {
+              GotItMessage.createMessage("Groovy Shell & Groovy Console", "<html><div align='left'>Use 'Groovy Console' action (Tools | Groovy Console...) to run <a href='http://'>Groovy Console</a><br>Use 'Groovy Shell' action (Tools | Groovy Shell...) to invoke <a href=\"http://groovy.codehaus.org/Groovy+Shell\">Groovy Shell</a></div></html>")
+                .setDisposable(console)
+                .show(new RelativePoint(console.getComponent(), new Point(10, 0)), Balloon.Position.above);
 
-            @Override
-            public String getEmptyExecuteAction() {
-              return "Groovy.Shell.Execute";
+              PropertiesComponent.getInstance().setValue(key, String.valueOf(true));
+              Disposer.dispose(alarm);
             }
-          };
-          new ConsoleHistoryController("Groovy Shell", null, getLanguageConsole(), handler.getConsoleHistoryModel()).install();
-          return handler;
+          }, 2000);
         }
-      };
-    try {
-      runner.initAndRun();
-    }
-    catch (ExecutionException e1) {
-      LOG.info(e1);
-      Messages.showErrorDialog(module.getProject(), e1.getMessage(), "Cannot Run Groovy Shell");
-    }
-  }
 
-  private static class GroovyConsoleView extends LanguageConsoleViewImpl {
-    protected GroovyConsoleView(final Project project) {
-      super(new GroovyShellConsoleImpl(project, "Groovy Console"));
-    }
+      }
+    })*/;
+
+
+    return console;
   }
 }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellActionBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellActionBase.java
new file mode 100644
index 0000000..54f8d51
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellActionBase.java
@@ -0,0 +1,249 @@
+/*
+ * 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.console;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.JavaParameters;
+import com.intellij.execution.console.ConsoleHistoryController;
+import com.intellij.execution.console.LanguageConsoleImpl;
+import com.intellij.execution.console.LanguageConsoleView;
+import com.intellij.execution.console.LanguageConsoleViewImpl;
+import com.intellij.execution.process.OSProcessHandler;
+import com.intellij.execution.runners.AbstractConsoleRunnerWithHistory;
+import com.intellij.execution.runners.ConsoleExecuteActionHandler;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileStatusNotification;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.JavaSdkType;
+import com.intellij.openapi.projectRoots.JdkUtil;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkTypeId;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ui.configuration.ModulesAlphaComparator;
+import com.intellij.openapi.ui.Messages;
+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.util.Key;
+import com.intellij.util.PlatformIcons;
+import icons.JetgroovyIcons;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl;
+import org.jetbrains.plugins.groovy.util.GroovyUtils;
+
+import java.util.*;
+
+/**
+ * Created by Max Medvedev on 9/20/13
+ */
+public abstract class GroovyShellActionBase extends DumbAwareAction {
+  private static final Logger LOG = Logger.getInstance(GroovyShellActionBase.class);
+
+  public static final Key<Boolean> GROOVY_SHELL_FILE = Key.create("GROOVY_SHELL_FILE");
+  private static final String GROOVY_SHELL_LAST_MODULE = "Groovy.Shell.LastModule";
+
+  private static List<Module> getGroovyCompatibleModules(Project project) {
+    ArrayList<Module> result = new ArrayList<Module>();
+    for (Module module : ModuleManager.getInstance(project).getModules()) {
+      if (GroovyUtils.isSuitableModule(module)) {
+        Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
+        if (sdk != null && sdk.getSdkType() instanceof JavaSdkType) {
+          result.add(module);
+        }
+      }
+    }
+    return result;
+  }
+
+  @Override
+  public void update(AnActionEvent e) {
+    final Project project = e.getData(CommonDataKeys.PROJECT);
+
+    boolean enabled = project != null && !getGroovyCompatibleModules(project).isEmpty();
+
+    e.getPresentation().setEnabled(enabled);
+    e.getPresentation().setVisible(enabled);
+  }
+
+  @Override
+  public void actionPerformed(AnActionEvent e) {
+    final Project project = e.getData(CommonDataKeys.PROJECT);
+    assert project != null;
+
+    CompilerManager.getInstance(project).make(new CompileStatusNotification() {
+      @Override
+      public void finished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
+        if (aborted) return;
+
+        final Project project = compileContext.getProject();
+
+        if (errors == 0 ||
+            Messages.showYesNoDialog(project, "Compilation failed with errors. Do you want to run " + getTitle() + " anyway?", getTitle(),
+                                     JetgroovyIcons.Groovy.Groovy_32x32) == Messages.YES) {
+          runGroovyShell(project);
+        }
+      }
+    });
+  }
+
+  private void runGroovyShell(Project project) {
+    List<Module> modules = new ArrayList<Module>();
+    final Map<Module, String> versions = new HashMap<Module, String>();
+
+    for (Module module : getGroovyCompatibleModules(project)) {
+      GroovyShellRunner runner = GroovyShellRunner.getAppropriateRunner(module);
+      if (runner != null) {
+        modules.add(module);
+        versions.put(module, runner.getTitle(module));
+      }
+    }
+
+    if (modules.size() == 1) {
+      doRun(modules.get(0));
+      return;
+    }
+
+    Collections.sort(modules, ModulesAlphaComparator.INSTANCE);
+
+    BaseListPopupStep<Module> step =
+      new BaseListPopupStep<Module>("Which module to use classpath of?", modules, PlatformIcons.CONTENT_ROOT_ICON_CLOSED) {
+        @NotNull
+        @Override
+        public String getTextFor(Module value) {
+          return value.getName() + versions.get(value);
+        }
+
+        @Override
+        public String getIndexedString(Module value) {
+          return value.getName();
+        }
+
+        @Override
+        public boolean isSpeedSearchEnabled() {
+          return true;
+        }
+
+        @Override
+        public PopupStep onChosen(Module selectedValue, boolean finalChoice) {
+          PropertiesComponent.getInstance(selectedValue.getProject()).setValue(GROOVY_SHELL_LAST_MODULE, selectedValue.getName());
+          doRun(selectedValue);
+          return null;
+        }
+      };
+
+    for (int i = 0; i < modules.size(); i++) {
+      Module module = modules.get(i);
+      if (module.getName().equals(PropertiesComponent.getInstance(project).getValue(GROOVY_SHELL_LAST_MODULE))) {
+        step.setDefaultOptionIndex(i);
+        break;
+      }
+    }
+    JBPopupFactory.getInstance().createListPopup(step).showCenteredInCurrentWindow(project);
+  }
+
+  protected void doRun(final Module module) {
+    final GroovyShellRunner shellRunner = getRunner(module);
+    if (shellRunner == null) return;
+
+    AbstractConsoleRunnerWithHistory<LanguageConsoleView> runner = new GroovyConsoleRunner(getTitle(), shellRunner, module, "Groovy.Shell.Execute");
+    try {
+      runner.initAndRun();
+    }
+    catch (ExecutionException e) {
+      LOG.info(e);
+      Messages.showErrorDialog(module.getProject(), e.getMessage(), "Cannot Run " + getTitle());
+    }
+  }
+
+  protected abstract GroovyShellRunner getRunner(Module module);
+
+  public abstract String getTitle();
+
+  protected abstract LanguageConsoleImpl createConsole(Project project, String title);
+
+  private class GroovyConsoleRunner extends AbstractConsoleRunnerWithHistory<LanguageConsoleView> {
+    private final String myEmptyExecuteAction;
+    private GroovyShellRunner myShellRunner;
+    private Module myModule;
+
+    private GroovyConsoleRunner(@NotNull String consoleTitle,
+                                @NotNull GroovyShellRunner shellRunner,
+                                @NotNull Module module,
+                                @NotNull String emptyExecuteAction) {
+      super(module.getProject(), consoleTitle, shellRunner.getWorkingDirectory(module));
+      myShellRunner = shellRunner;
+      myModule = module;
+      myEmptyExecuteAction = emptyExecuteAction;
+    }
+
+    @Override
+    protected LanguageConsoleView createConsoleView() {
+      LanguageConsoleView res = new LanguageConsoleViewImpl(createConsole(getProject(), getConsoleTitle()));
+
+      GroovyFileImpl file = (GroovyFileImpl)res.getConsole().getFile();
+      assert file.getContext() == null;
+      file.putUserData(GROOVY_SHELL_FILE, Boolean.TRUE);
+
+      file.setContext(myShellRunner.getContext(myModule));
+
+      return res;
+    }
+
+    @Override
+    protected Process createProcess() throws ExecutionException {
+      JavaParameters javaParameters = myShellRunner.createJavaParameters(myModule);
+
+      final Sdk sdk = ModuleRootManager.getInstance(myModule).getSdk();
+      assert sdk != null;
+      SdkTypeId sdkType = sdk.getSdkType();
+      assert sdkType instanceof JavaSdkType;
+      final String exePath = ((JavaSdkType)sdkType).getVMExecutablePath(sdk);
+
+      return JdkUtil.setupJVMCommandLine(exePath, javaParameters, true).createProcess();
+    }
+
+    @Override
+    protected OSProcessHandler createProcessHandler(Process process) {
+      return new OSProcessHandler(process);
+    }
+
+    @NotNull
+    @Override
+    protected ConsoleExecuteActionHandler createConsoleExecuteActionHandler() {
+      ConsoleExecuteActionHandler handler = new ConsoleExecuteActionHandler(getProcessHandler(), false) {
+        @Override
+        public void processLine(String line) {
+          super.processLine(myShellRunner.transformUserInput(line));
+        }
+
+        @Override
+        public String getEmptyExecuteAction() {
+          return myEmptyExecuteAction;
+        }
+      };
+      new ConsoleHistoryController(getConsoleTitle(), null, getLanguageConsole(), handler.getConsoleHistoryModel()).install();
+      return handler;
+    }
+  }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java
index 55286f6..c105fc6c 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java
@@ -526,7 +526,7 @@
     if (myType2 == mSEMI) return;
 
     if (typeDefinitionBody != null) { //check variable definitions only inside class body
-      if ((myType1 == VARIABLE_DEFINITION || isSemiAfter(VARIABLE_DEFINITION)) && METHOD_DEFS.contains(myType2)) {
+      if ((myType1 == VARIABLE_DEFINITION || isSemiAfter(VARIABLE_DEFINITION)) && TokenSets.METHOD_DEFS.contains(myType2)) {
         final int minBlankLines = Math.max(
           isInterface ? mySettings.BLANK_LINES_AROUND_METHOD_IN_INTERFACE : mySettings.BLANK_LINES_AROUND_METHOD,
           isInterface ? mySettings.BLANK_LINES_AROUND_FIELD_IN_INTERFACE : mySettings.BLANK_LINES_AROUND_FIELD
@@ -542,15 +542,30 @@
       }
     }
 
-    if (METHOD_DEFS.contains(myType1) || isSemiAfter(METHOD_DEFS) || METHOD_DEFS.contains((myType2))) {
+    if (TokenSets.METHOD_DEFS.contains(myType1) || isSemiAfter(TokenSets.METHOD_DEFS) || TokenSets.METHOD_DEFS.contains((myType2))) {
       if (myType1 == GROOVY_DOC_COMMENT) {
         createLF(true);
+        return;
       }
       else {
         final int minBlankLines = isInterface ? mySettings.BLANK_LINES_AROUND_METHOD_IN_INTERFACE : mySettings.BLANK_LINES_AROUND_METHOD;
         myResult = Spacing.createSpacing(0, 0, minBlankLines + 1, mySettings.KEEP_LINE_BREAKS, keepBlankLines());
+        return;
       }
     }
+
+    if (TokenSets.TYPE_DEFINITIONS.contains(myType1) || isSemiAfter(TokenSets.TYPE_DEFINITIONS) || TokenSets.TYPE_DEFINITIONS.contains((myType2)) ) {
+      if (myType1 == GROOVY_DOC_COMMENT) {
+        createLF(true);
+        return;
+      }
+      else {
+        final int minBlankLines = mySettings.BLANK_LINES_AROUND_CLASS;
+        myResult = Spacing.createSpacing(0, 0, minBlankLines + 1, mySettings.KEEP_LINE_BREAKS, keepBlankLines());
+        return;
+      }
+
+    }
   }
 
   @Override
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovyWrappingProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovyWrappingProcessor.java
index 272540d..67281f0 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovyWrappingProcessor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovyWrappingProcessor.java
@@ -255,7 +255,7 @@
       return mySettings.CLASS_ANNOTATION_WRAP;
     }
 
-    if (METHOD_DEFS.contains(containerType)) {
+    if (TokenSets.METHOD_DEFS.contains(containerType)) {
       return mySettings.METHOD_ANNOTATION_WRAP;
     }
 
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonFramework.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonFramework.java
index 9808af8..0499c68 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonFramework.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonFramework.java
@@ -36,24 +36,25 @@
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.changes.ChangeListManager;
 import com.intellij.openapi.vcs.changes.IgnoredBeanFactory;
-import com.intellij.openapi.vfs.JarFileSystem;
 import com.intellij.openapi.vfs.VfsUtil;
 import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.PsiManager;
+import com.intellij.util.containers.MultiMap;
 import gnu.trove.TIntArrayList;
 import icons.JetgroovyIcons;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 import org.jetbrains.plugins.groovy.GroovyFileType;
 import org.jetbrains.plugins.groovy.mvc.*;
 
 import javax.swing.*;
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -76,7 +77,7 @@
   }
 
   public boolean hasSupport(@NotNull Module module) {
-    return getSdkRoot(module) != null && findAppRoot(module) != null && !isAuxModule(module);
+    return findAppRoot(module) != null && !isAuxModule(module) && getSdkRoot(module) != null;
   }
 
   @Override
@@ -417,6 +418,11 @@
   }
 
   private static class GriffonProjectStructure extends MvcProjectStructure {
+
+    public static final String[] TEST_DIRS = new String[]{"unit", "integration", "shared"};
+    public static final String[] SRC_DIR_SUBFOLDER = new String[]{"main", "cli"};
+    public static final String[] GRIFFON_APP_SOURCE_ROOTS = new String[]{"models", "views", "controllers", "services", "conf", "lifecycle"};
+
     public GriffonProjectStructure(Module module, final boolean auxModule) {
       super(module, auxModule, getUserHomeGriffon(), GriffonFramework.getInstance().getSdkWorkDir(module));
     }
@@ -426,65 +432,51 @@
       return GRIFFON_USER_LIBRARY;
     }
 
-    public String[] getSourceFolders() {
-      List<String> sourceFolders = new ArrayList<String>();
+    public MultiMap<JpsModuleSourceRootType<?>, String> getSourceFolders() {
+      MultiMap<JpsModuleSourceRootType<?>, String> res = new MultiMap<JpsModuleSourceRootType<?>, String>();
 
-      for (VirtualFile file : ModuleRootManager.getInstance(myModule).getContentRoots()) {
-        handleSrc(file.findChild("src"), sourceFolders);
-        VirtualFile griffonApp = file.findChild("griffon-app");
-        handleGriffonApp(griffonApp, sourceFolders);
-        List<GriffonSourceInspector.GriffonSource> sources =
-          GriffonSourceInspector.processModuleMetadata(myModule);
-        for (GriffonSourceInspector.GriffonSource source : sources) {
-          sourceFolders.add(source.getPath());
+      for (VirtualFile root : ModuleRootManager.getInstance(myModule).getContentRoots()) {
+        VirtualFile srcDir = root.findChild("src");
+        if (srcDir != null) {
+          for (String child : SRC_DIR_SUBFOLDER) {
+            if (srcDir.findChild(child) != null) {
+              res.putValue(JavaSourceRootType.SOURCE, "src/" + child);
+            }
+          }
         }
+
+        VirtualFile griffonApp = root.findChild("griffon-app");
         if (griffonApp != null) {
-          for (VirtualFile child : file.getChildren()) {
+          for (String child : GRIFFON_APP_SOURCE_ROOTS) {
+            if (griffonApp.findChild(child) != null) {
+              res.putValue(JavaSourceRootType.SOURCE, "griffon-app/" + child);
+            }
+          }
+
+          for (VirtualFile child : root.getChildren()) {
             if (child.getNameWithoutExtension().endsWith("GriffonAddon")) {
-              sourceFolders.add("");
+              res.putValue(JavaSourceRootType.SOURCE, "");
               break;
             }
           }
         }
-      }
-      return sourceFolders.toArray(new String[sourceFolders.size()]);
-    }
 
-    private void handleGriffonApp(VirtualFile griffonApp, List<String> sourceFolders) {
-      if (griffonApp == null) return;
-      // Add standard artifacts, i.e, models, views, controllers, services, conf, lifecycle
-      for (String child : new String[]{"models", "views", "controllers", "services", "conf", "lifecycle"}) {
-        if (griffonApp.findChild(child) != null) {
-          sourceFolders.add("griffon-app/" + child);
+        List<GriffonSourceInspector.GriffonSource> sources = GriffonSourceInspector.processModuleMetadata(myModule);
+        for (GriffonSourceInspector.GriffonSource source : sources) {
+          res.putValue(JavaSourceRootType.SOURCE, source.getPath());
+        }
+
+        VirtualFile testDir = root.findChild("test");
+        if (testDir != null) {
+          for (String child : TEST_DIRS) {
+            if (testDir.findChild(child) != null) {
+              res.putValue(JavaSourceRootType.TEST_SOURCE, "test/" + child);
+            }
+          }
         }
       }
-    }
 
-    private void handleSrc(VirtualFile src, List<String> sourceFolders) {
-      if (src == null) return;
-      for (String child : new String[]{"main", "cli"}) {
-        if (src.findChild(child) != null) {
-          sourceFolders.add("src/" + child);
-        }
-      }
-    }
-
-    private void handleTest(VirtualFile test, List<String> sourceFolders) {
-      if (test == null) return;
-      for (String child : new String[]{"unit", "integration", "shared"}) {
-        if (test.findChild(child) != null) {
-          sourceFolders.add("test/" + child);
-        }
-      }
-    }
-
-    public String[] getTestFolders() {
-      List<String> sourceFolders = new ArrayList<String>();
-
-      for (VirtualFile file : ModuleRootManager.getInstance(myModule).getContentRoots()) {
-        handleTest(file.findChild("test"), sourceFolders);
-      }
-      return sourceFolders.toArray(new String[sourceFolders.size()]);
+      return res;
     }
 
     public String[] getInvalidSourceFolders() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySlashyStringLexer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySlashyStringLexer.java
index 01e9127..65ec015 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySlashyStringLexer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySlashyStringLexer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 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.
@@ -21,6 +21,7 @@
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.StringEscapesTokenTypes;
 import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
 
@@ -41,7 +42,7 @@
   }
 
   @Override
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     if (buffer.length()<endOffset) {
       LogMessageEx.error(LOG, "buffer Length: " + buffer.length() + ", endOffset: " + endOffset, buffer.toString());
     }
@@ -107,6 +108,7 @@
     myTokenType = locateToken();
   }
 
+  @NotNull
   @Override
   public CharSequence getBufferSequence() {
     return myBuffer;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitElseIfIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitElseIfIntention.java
index 497b269..3773b97 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitElseIfIntention.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitElseIfIntention.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.
@@ -21,8 +21,9 @@
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.plugins.groovy.intentions.base.Intention;
-import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils;
 import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
 
@@ -33,11 +34,17 @@
     return new SplitElseIfPredicate();
   }
 
-  public void processIntention(@NotNull PsiElement element, Project project, Editor editor)
-      throws IncorrectOperationException {
+  public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException {
     final GrIfStatement parentStatement = (GrIfStatement) element;
     final GrStatement elseBranch = parentStatement.getElseBranch();
-    IntentionUtils.replaceStatement("if(" + parentStatement.getCondition().getText()+ ")"+ parentStatement.getThenBranch().getText() +
-        "else{\n" + elseBranch.getText() +"\n}", parentStatement);
+
+    GrIfStatement ifStatement = (GrIfStatement)parentStatement.copy();
+
+    GrBlockStatement blockStatement = GroovyPsiElementFactory.getInstance(project).createBlockStatementFromText("{\nabc()\n}", null);
+    GrBlockStatement newBlock = ifStatement.replaceElseBranch(blockStatement);
+
+    newBlock.getBlock().getStatements()[0].replace(elseBranch);
+
+    parentStatement.replaceWithStatement(ifStatement);
   }
 }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionConfidence.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionConfidence.java
index bae24c8..2a178ea 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionConfidence.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionConfidence.java
@@ -1,9 +1,12 @@
 /*
- * Copyright 2000-2010 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.
  * 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.
@@ -12,6 +15,7 @@
  */
 package org.jetbrains.plugins.groovy.lang.completion;
 
+import com.intellij.codeInsight.CodeInsightSettings;
 import com.intellij.codeInsight.completion.CompletionConfidence;
 import com.intellij.codeInsight.completion.CompletionParameters;
 import com.intellij.patterns.ElementPattern;
@@ -21,6 +25,7 @@
 import com.intellij.util.ThreeState;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.plugins.groovy.console.GroovyShellAction;
+import org.jetbrains.plugins.groovy.console.GroovyShellActionBase;
 import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
 import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
 import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
@@ -70,7 +75,7 @@
       final GrExpression qualifier = ref.getQualifierExpression();
       if (qualifier == null) {
         if (isPossibleClosureParameter(ref)) return ThreeState.NO;
-        if (parameters.getOriginalFile().getUserData(GroovyShellAction.GROOVY_SHELL_FILE) == Boolean.TRUE) {
+        if (parameters.getOriginalFile().getUserData(GroovyShellActionBase.GROOVY_SHELL_FILE) == Boolean.TRUE) {
           return ThreeState.NO;
         }
 
@@ -93,6 +98,10 @@
   @NotNull
   @Override
   public ThreeState shouldSkipAutopopup(@NotNull PsiElement contextElement, @NotNull PsiFile psiFile, int offset) {
+    if (CodeInsightSettings.getInstance().SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS && psiFile.getUserData(GroovyShellAction.GROOVY_SHELL_FILE) == Boolean.TRUE) {
+      return ThreeState.YES;
+    }
+
     if (com.intellij.psi.impl.PsiImplUtil.isLeafElementOfType(contextElement, TokenSets.STRING_LITERALS)) {
       @SuppressWarnings("ConstantConditions")
       PsiElement parent = contextElement.getParent();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/lexer/GroovyDocLexer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/lexer/GroovyDocLexer.java
index 6bfba48..b60cce1 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/lexer/GroovyDocLexer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/lexer/GroovyDocLexer.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.
@@ -24,6 +24,7 @@
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.tree.TokenSet;
 import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.NotNull;
 
 import java.io.IOException;
 
@@ -87,7 +88,7 @@
       myFlexLexer = lexer;
     }
 
-    public final void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+    public final void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
       myBuffer = buffer;
       myBufferIndex = startOffset;
       myBufferEndOffset = endOffset;
@@ -100,6 +101,7 @@
       return myState;
     }
 
+    @NotNull
     public CharSequence getBufferSequence() {
       return myBuffer;
     }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java
index d2505b9..1285548 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java
@@ -74,7 +74,7 @@
       mDOLLAR_SLASH_REGEX_LITERAL
   );
 
-  public static final TokenSet BUILT_IN_TYPE = TokenSet.create(
+  public static final TokenSet BUILT_IN_TYPES = TokenSet.create(
       kVOID,
       kBOOLEAN,
       kBYTE,
@@ -217,4 +217,10 @@
   public static final TokenSet CODE_REFERENCE_ELEMENT_NAME_TOKENS = TokenSet.create(mIDENT, kDEF,  kIN, kAS);
 
   public static final TokenSet BLOCK_SET = TokenSet.create(CLOSABLE_BLOCK, BLOCK_STATEMENT, CONSTRUCTOR_BODY, OPEN_BLOCK, ENUM_BODY, CLASS_BODY);
+  public static final TokenSet METHOD_DEFS = TokenSet.create(METHOD_DEFINITION, CONSTRUCTOR_DEFINITION, ANNOTATION_METHOD);
+  public static final TokenSet VARIABLES = TokenSet.create(VARIABLE, FIELD);
+  public static final TokenSet TYPE_ELEMENTS = TokenSet.create(CLASS_TYPE_ELEMENT, ARRAY_TYPE, BUILT_IN_TYPE, TYPE_ARGUMENT, DISJUNCTION_TYPE_ELEMENT);
+
+
+  public static final TokenSet TYPE_DEFINITIONS = TokenSet.create(CLASS_DEFINITION, ENUM_DEFINITION, INTERFACE_DEFINITION, ANNOTATION_DEFINITION);
 }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java
index cbf640c..699393b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java
@@ -18,7 +18,6 @@
 
 import com.intellij.lang.ASTNode;
 import com.intellij.psi.stubs.*;
-import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.tree.TokenSet;
 import com.intellij.util.io.StringRef;
 import org.jetbrains.annotations.NotNull;
@@ -420,7 +419,6 @@
         return new GrVariableDeclarationImpl(stub);
       }
     };
-  IElementType MULTIPLE_VARIABLE_DEFINITION = new GroovyElementType("multivariable definition");
   GroovyElementType TUPLE_DECLARATION = new GroovyElementType("tuple declaration");
   GroovyElementType TUPLE_EXPRESSION = new GroovyElementType("tuple expression");
 
@@ -433,9 +431,4 @@
 
   //types
   GroovyElementType CLASS_TYPE_ELEMENT = new GroovyElementType("class type element"); //node
-
-  TokenSet METHOD_DEFS = TokenSet.create(METHOD_DEFINITION, CONSTRUCTOR_DEFINITION, ANNOTATION_METHOD);
-  TokenSet VARIABLES = TokenSet.create(VARIABLE, FIELD);
-  TokenSet TYPE_ELEMENTS = TokenSet.create(CLASS_TYPE_ELEMENT, ARRAY_TYPE, BUILT_IN_TYPE, TYPE_ARGUMENT, DISJUNCTION_TYPE_ELEMENT);
-
 }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParserDefinition.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParserDefinition.java
index bcde7ee..bb1ba34 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParserDefinition.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParserDefinition.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.
@@ -99,6 +99,8 @@
     if (lType == mNLS || lType == mGDOC_COMMENT_START) {
       return MAY;
     }
+    if (lType == mGT) return MUST;
+    if (rType == mLT) return MUST;
 
     final IElementType parentType = left.getTreeParent().getElementType();
     if (parentType == GSTRING ||
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java
index 16328d8f..5fb6053 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.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.
@@ -68,7 +68,7 @@
 
     Modifiers.parse(builder, parser);
 
-    boolean isBuiltInType = TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType());
+    boolean isBuiltInType = TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType());
 
     PsiBuilder.Marker typeSpec = builder.mark();
     TypeSpec.parseStrict(builder, false);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/Declaration.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/Declaration.java
index 7642ef0..195a58a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/Declaration.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/Declaration.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.
@@ -134,7 +134,7 @@
 
   private static boolean isCall(@NotNull PsiBuilder builder) {
     if (builder.eof()) return false;
-    if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType())) return false;
+    if (TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType())) return false;
 
     final String text = builder.getTokenText();
     if (StringUtil.isEmpty(text)) return false;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.java
index 44f9fa6..c4dc86f 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.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.
@@ -69,7 +69,7 @@
       marker.rollbackTo();
       return FAIL;
     }
-    if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType()) || mIDENT.equals(builder.getTokenType())) {
+    if (TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType()) || mIDENT.equals(builder.getTokenType())) {
       final ReferenceElement.ReferenceElementResult result = TypeSpec.parseStrict(builder, true);
       if (result == FAIL) {
         marker.rollbackTo();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java
index 59ff837..f785fe6 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java
@@ -43,7 +43,7 @@
   public static IElementType parsePrimaryExpression(PsiBuilder builder, GroovyParser parser, boolean literalsAsRefExprs) {
 
     final IElementType tokenType = builder.getTokenType();
-    if (TokenSets.BUILT_IN_TYPE.contains(tokenType)) {
+    if (TokenSets.BUILT_IN_TYPES.contains(tokenType)) {
       ParserUtils.eatElement(builder, BUILT_IN_TYPE_EXPRESSION);
       return BUILT_IN_TYPE_EXPRESSION;
     }
@@ -110,7 +110,7 @@
     ParserUtils.getToken(builder, mNLS);
     PsiBuilder.Marker rb = builder.mark();
     TypeArguments.parseTypeArguments(builder, false);
-    if (!TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType()) && mIDENT != builder.getTokenType()) {
+    if (!TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType()) && mIDENT != builder.getTokenType()) {
       rb.rollbackTo();
     }
     else {
@@ -119,7 +119,7 @@
 
     PsiBuilder.Marker anonymousMarker = builder.mark();
     String name = null;
-    if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType())) {
+    if (TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType())) {
       ParserUtils.eatElement(builder, BUILT_IN_TYPE);
     }
     else if (TokenSets.CODE_REFERENCE_ELEMENT_NAME_TOKENS.contains(builder.getTokenType())) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeSpec.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeSpec.java
index ff293ed..3f936b1 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeSpec.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeSpec.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.
@@ -37,7 +37,7 @@
   }
 
   public static ReferenceElementResult parse(PsiBuilder builder, boolean isUpper, final boolean expressionPossible) {
-    if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType())) {
+    if (TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType())) {
       return parseBuiltInType(builder);
     }
     if (builder.getTokenType() == mIDENT) {
@@ -117,7 +117,7 @@
    * @return
    */
   public static ReferenceElementResult parseStrict(PsiBuilder builder, boolean expressionPossible) {
-    if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType())) {
+    if (TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType())) {
       return parseBuiltInTypeStrict(builder);
     }
     else if (builder.getTokenType() == mIDENT) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrQualifiedReference.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrQualifiedReference.java
index 5d0369d..bb48e12 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrQualifiedReference.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrQualifiedReference.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 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.
@@ -16,7 +16,6 @@
 package org.jetbrains.plugins.groovy.lang.psi;
 
 import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiQualifiedReference;
 import com.intellij.psi.PsiQualifiedReferenceElement;
 import org.jetbrains.annotations.Nullable;
 
@@ -31,4 +30,6 @@
 
   @Nullable
   PsiElement getReferenceNameElement();
+
+  boolean isQualified();
 }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyFileBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyFileBase.java
index 9162723..7bbd22b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyFileBase.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyFileBase.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.
@@ -53,7 +53,7 @@
 
   GrTopLevelDefinition[] getTopLevelDefinitions();
 
-  GrMethod[] getTopLevelMethods();
+  GrMethod[] getCodeMethods();
 
   GrMethod[] getMethods();
 
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrReferenceExpression.java
index 0781a02..91c4c31 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrReferenceExpression.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrReferenceExpression.java
@@ -32,8 +32,6 @@
   @Nullable
   GrExpression getQualifierExpression();
 
-  boolean isQualified();
-
   @Nullable
   IElementType getDotTokenType();
 
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSuperReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSuperReferenceExpression.java
deleted file mode 100644
index e140a96..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSuperReferenceExpression.java
+++ /dev/null
@@ -1,8 +0,0 @@
-
-package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions;
-
-/**
- * @author ilyas
- */
-public interface GrSuperReferenceExpression extends GrThisSuperReferenceExpression {
-}
\ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisReferenceExpression.java
deleted file mode 100644
index 7e6f3f7..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisReferenceExpression.java
+++ /dev/null
@@ -1,8 +0,0 @@
-
-package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions;
-
-/**
- * @author ilyas
- */
-public interface GrThisReferenceExpression extends GrThisSuperReferenceExpression {
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java
deleted file mode 100644
index 3284a9c..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2000-2010 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.psi.api.statements.expressions;
-
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiPolyVariantReference;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference;
-
-/**
- * @author Maxim.Medvedev
- */
-public interface GrThisSuperReferenceExpression extends GrExpression, PsiPolyVariantReference, GrQualifiedReference<GrReferenceExpression> {
-  @NotNull
-  @Override
-  PsiElement getReferenceNameElement();
-
-  @NotNull
-  @Override
-  String getReferenceName();
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrReferenceElementImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrReferenceElementImpl.java
index 5295cf3..ada7e75 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrReferenceElementImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrReferenceElementImpl.java
@@ -86,7 +86,7 @@
         newNameNode = factory.createLiteralFromValue(newElementName).getFirstChild().getNode();
       }
       assert newNameNode != null && node != null;
-      node.getTreeParent().replaceChild(node, newNameNode);
+      getNode().replaceChild(node, newNameNode);
     }
 
     return this;
@@ -191,4 +191,7 @@
     return whiteSpaceAndComments;
   }
 
+  public boolean isQualified() {
+    return getQualifier() != null;
+  }
 }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java
index eae43a0..9641abf 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java
@@ -104,7 +104,7 @@
     return findChildrenByClass(GrTopLevelDefinition.class);
   }
 
-  public GrMethod[] getTopLevelMethods() {
+  public GrMethod[] getCodeMethods() {
     final StubElement<?> stub = getStub();
     if (stub != null) {
       return stub.getChildrenByType(GroovyElementTypes.METHOD_DEFINITION, GrMethod.ARRAY_FACTORY);
@@ -118,7 +118,7 @@
     if (myMethods == null) {
       List<GrMethod> result = new ArrayList<GrMethod>();
       
-      GrMethod[] methods = getTopLevelMethods();
+      GrMethod[] methods = getCodeMethods();
       for (GrMethod method : methods) {
         final GrReflectedMethod[] reflectedMethods = method.getReflectedMethods();
         if (reflectedMethods.length > 0) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java
index 2084a80..c482aea 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java
@@ -194,6 +194,14 @@
       }
     }
 
+    if (owner instanceof GrMethod && owner.getParent() instanceof GrTypeDefinitionBody) {
+      PsiElement parent = owner.getParent().getParent();
+      if (parent instanceof PsiClass && ((PsiClass)parent).isInterface()) {
+        if (GrModifier.ABSTRACT.equals(modifier)) return true;
+        if (GrModifier.PUBLIC.equals(modifier)) return true;
+      }
+    }
+
     if (modifierList.hasExplicitModifier(modifier)) {
       return true;
     }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
index 688fad5..1ab1a1a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
@@ -30,6 +30,7 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
+import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
 import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
 import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
 import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
@@ -184,7 +185,7 @@
 
   @NotNull
   public GrVariable[] getVariables() {
-    return getStubOrPsiChildren(GroovyElementTypes.VARIABLES, GrVariable.ARRAY_FACTORY);
+    return getStubOrPsiChildren(TokenSets.VARIABLES, GrVariable.ARRAY_FACTORY);
   }
 
   public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
index 7bfdf31..583ba9b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
@@ -857,10 +857,6 @@
     return findExpressionChild(this);
   }
 
-  public boolean isQualified() {
-    return getQualifierExpression() != null;
-  }
-
   @Nullable
   public PsiElement getDotToken() {
     return findChildByType(TokenSets.DOTS);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java
deleted file mode 100644
index 61365ae..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java
+++ /dev/null
@@ -1,118 +0,0 @@
-
-/*
- * Copyright 2000-2011 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.psi.impl.statements.expressions;
-
-import com.intellij.lang.ASTNode;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.NullableFunction;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
-import org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil;
-
-/**
- * @author ilyas
- */
-public class GrSuperReferenceExpressionImpl extends GrThisSuperReferenceExpressionBase implements GrSuperReferenceExpression {
-
-  private static final NullableFunction<GrSuperReferenceExpressionImpl, PsiType> TYPE_CALCULATOR =
-    new NullableFunction<GrSuperReferenceExpressionImpl, PsiType>() {
-      @Override
-      public PsiType fun(GrSuperReferenceExpressionImpl ref) {
-        final GrReferenceExpression qualifier = ref.getQualifier();
-        if (qualifier == null) {
-          GroovyPsiElement context = PsiTreeUtil.getParentOfType(ref, GrTypeDefinition.class, GroovyFileBase.class);
-          if (context instanceof GrTypeDefinition) {
-            final PsiClass superClass = ((GrTypeDefinition)context).getSuperClass();
-            if (superClass != null) {
-              return JavaPsiFacade.getInstance(ref.getProject()).getElementFactory().createType(superClass);
-            }
-          }
-          else if (context instanceof GroovyFileBase) {
-            PsiClass scriptClass = ((GroovyFileBase)context).getScriptClass();
-            if (scriptClass != null) {
-              PsiClass superClass = scriptClass.getSuperClass();
-              if (superClass != null) {
-                return JavaPsiFacade.getInstance(ref.getProject()).getElementFactory().createType(superClass);
-              }
-            }
-            return GrClassImplUtil.getGroovyObjectType(ref);
-          }
-        }
-        else {
-          final PsiElement resolved = qualifier.resolve();
-          if (resolved instanceof PsiClass) {
-            return ref.getSuperType((PsiClass)resolved);
-          }
-        }
-        return null;
-      }
-    };
-
-  public GrSuperReferenceExpressionImpl(@NotNull ASTNode node) {
-    super(node);
-  }
-
-  public void accept(GroovyElementVisitor visitor) {
-  }
-
-  public String toString() {
-    return "'super' reference expression";
-  }
-
-  public PsiType getType() {
-    return TypeInferenceHelper.getCurrentContext().getExpressionType(this, TYPE_CALCULATOR);
-      
-  }
-
-  @Nullable
-  private PsiType getSuperType(PsiClass aClass) {
-    if (aClass.isInterface()) {
-      return PsiType.getJavaLangObject(getManager(), getResolveScope());
-    }
-    if (aClass instanceof GrAnonymousClassDefinition) {
-      final PsiClassType baseClassType = ((GrAnonymousClassDefinition)aClass).getBaseClassType();
-      final PsiClass psiClass = baseClassType.resolve();
-      if (psiClass != null && !psiClass.isInterface()) {
-        return baseClassType;
-      }
-
-      return PsiType.getJavaLangObject(getManager(), getResolveScope());
-    }
-
-    if (CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) return null;
-    PsiClassType[] superTypes = aClass.getExtendsListTypes();
-    if (superTypes.length == 0) {
-      return PsiType.getJavaLangObject(getManager(), getResolveScope());
-    }
-
-    return superTypes[0];
-  }
-
-  @Override
-  public String getReferenceName() {
-    return "super";
-  }
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java
deleted file mode 100644
index 88ab149..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
-* Copyright 2000-2011 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.psi.impl.statements.expressions;
-
-import com.intellij.lang.ASTNode;
-import com.intellij.psi.*;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.NullableFunction;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
-import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
-import org.jetbrains.plugins.groovy.lang.psi.util.StaticChecker;
-
-/**
- * @author ilyas
- */
-public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressionBase implements GrThisReferenceExpression {
-
-  private static final NullableFunction<GrThisReferenceExpressionImpl, PsiType> TYPE_CALCULATOR =
-    new NullableFunction<GrThisReferenceExpressionImpl, PsiType>() {
-      @Override
-      public PsiType fun(GrThisReferenceExpressionImpl ref) {
-        if (ref.getQualifier() == null) {
-          return resolveNonQualified(ref);
-        }
-        else {
-          return resolveQualified(ref);
-        }
-      }
-
-      @Nullable
-      private PsiType resolveQualified(GrThisReferenceExpressionImpl ref) {
-        GrReferenceExpression qualifier = ref.getQualifier();
-        assert qualifier != null;
-        final PsiElement resolved = qualifier.resolve();
-        try {
-          PsiElementFactory factory = JavaPsiFacade.getElementFactory(ref.getProject());
-          if (resolved instanceof PsiClass) {
-            return factory.createType((PsiClass)resolved);
-          }
-          else {
-            return factory.createTypeFromText(qualifier.getText(), ref);
-          }
-        }
-        catch (IncorrectOperationException e) {
-          return null;
-        }
-      }
-
-      @Nullable
-      private PsiType resolveNonQualified(GrThisReferenceExpressionImpl ref) {
-        PsiClass context = PsiUtil.getContextClass(ref);
-        if (context != null) {
-          return ref.createType(context);
-        }
-        else {
-          return null;
-        }
-      }
-    };
-
-  public GrThisReferenceExpressionImpl(@NotNull ASTNode node) {
-    super(node);
-  }
-
-  public void accept(GroovyElementVisitor visitor) {
-  }
-
-  public String toString() {
-    return "'this' reference expression";
-  }
-
-  public PsiType getType() {
-    return TypeInferenceHelper.getCurrentContext().getExpressionType(this, TYPE_CALCULATOR);
-  }
-
-  private PsiType createType(@NotNull PsiClass context) {
-    final JavaPsiFacade facade = JavaPsiFacade.getInstance(context.getProject());
-    PsiElementFactory elementFactory = facade.getElementFactory();
-
-    if (!StaticChecker.isInStaticContext(this)) return elementFactory.createType(context);
-
-    //create instance of java.lang.Class<CurrentClass>
-    if (context instanceof PsiAnonymousClass) {
-      final PsiClassType type = ((PsiAnonymousClass)context).getBaseClassType();
-      final PsiClass aClass = facade.findClass(CommonClassNames.JAVA_LANG_CLASS, context.getResolveScope());
-      if (aClass != null) {
-        return elementFactory.createType(aClass, type);
-      }
-      else {
-        return elementFactory.createTypeFromText(CommonClassNames.JAVA_LANG_CLASS + "<" + type.getCanonicalText() + ">", this);
-      }
-    }
-    return elementFactory.createTypeFromText(CommonClassNames.JAVA_LANG_CLASS + "<" + context.getName() + ">", this);
-  }
-
-  @NotNull
-  @Override
-  public String getReferenceName() {
-    return "this";
-  }
-
-  @Override
-  protected PsiElement resolveInner() {
-    final PsiElement resolved = super.resolveInner();
-    if (resolved != null) return resolved;
-    final GrReferenceExpression qualifier = getQualifier();
-    if (qualifier != null) {
-      return qualifier.resolve();
-    }
-
-    return PsiUtil.getContextClass(this);
-  }
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java
deleted file mode 100644
index 15e0ea7..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
-
-import com.intellij.lang.ASTNode;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiReference;
-import com.intellij.psi.ResolveResult;
-import com.intellij.psi.impl.source.resolve.ResolveCache;
-import com.intellij.psi.tree.TokenSet;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.IncorrectOperationException;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
-import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
-import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
-import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
-import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
-
-/**
- * @author Maxim.Medvedev
- */
-public abstract class GrThisSuperReferenceExpressionBase extends GrExpressionImpl implements GrThisSuperReferenceExpression {
-  private static final OurResolver OUR_RESOLVER = new OurResolver();
-
-  public GrThisSuperReferenceExpressionBase(ASTNode node) {
-    super(node);
-  }
-
-  @Nullable
-  public GrReferenceExpression getQualifier() {
-    return (GrReferenceExpression)findChildByType(GroovyElementTypes.REFERENCE_EXPRESSION);
-  }
-
-  @Override
-  public void setQualifier(@Nullable GrReferenceExpression newQualifier) {
-    PsiImplUtil.setQualifier(this, newQualifier);
-  }
-
-  @NotNull
-  @Override
-  public PsiElement getReferenceNameElement() {
-    return getLastChild();
-  }
-
-  @Override
-  public PsiElement getElement() {
-    return this;
-  }
-
-  @Override
-  public TextRange getRangeInElement() {
-    final PsiElement token = findNotNullChildByType(TokenSet.create(GroovyTokenTypes.kTHIS, GroovyTokenTypes.kSUPER));
-    return TextRange.from(token.getStartOffsetInParent(), token.getTextLength());
-  }
-
-  @Override
-  public PsiElement resolve() {
-    final ResolveResult[] results = TypeInferenceHelper.getCurrentContext().multiResolve(this, false, OUR_RESOLVER);
-    if (results.length == 1) return results[0].getElement();
-    return null;
-  }
-
-  @Nullable
-  protected PsiElement resolveInner() {
-    final PsiElement parent = getParent();
-    if (parent instanceof GrConstructorInvocation) {
-      return ((GrConstructorInvocation)parent).resolveMethod();
-    }
-    return null;
-  }
-
-  public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
-    return this;
-  }
-
-  public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
-    return this;
-  }
-
-  public boolean isReferenceTo(PsiElement element) {
-    return getManager().areElementsEquivalent(element, resolve());
-  }
-
-  @NotNull
-  public Object[] getVariants() {
-    return ArrayUtil.EMPTY_OBJECT_ARRAY;
-  }
-
-  public boolean isSoft() {
-    return false;
-  }
-
-  @Override
-  public PsiReference getReference() {
-    return this;
-  }
-
-  @NotNull
-  public ResolveResult[] multiResolve(boolean incompleteCode) {
-    final PsiElement parent = getParent();
-    if (parent instanceof GrConstructorInvocation) {
-      return ((GrConstructorInvocation)parent).multiResolve(incompleteCode);
-    }
-    return ResolveResult.EMPTY_ARRAY;
-  }
-
-  @NotNull
-  @Override
-  public String getCanonicalText() {
-    return getReferenceName();
-  }
-
-  static class OurResolver implements ResolveCache.PolyVariantResolver<GrThisSuperReferenceExpressionBase> {
-    @NotNull
-    @Override
-    public ResolveResult[] resolve(@NotNull GrThisSuperReferenceExpressionBase ref, boolean incompleteCode) {
-      final PsiElement resolved = ref.resolveInner();
-      if (resolved == null) return ResolveResult.EMPTY_ARRAY;
-      return new GroovyResolveResult[]{new GroovyResolveResultImpl(resolved, true)};
-    }
-  }
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrReferenceListImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrReferenceListImpl.java
index e6b26f3..0b3f95b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrReferenceListImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrReferenceListImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2010 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.
@@ -16,6 +16,7 @@
 package org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef;
 
 import com.intellij.lang.ASTNode;
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.psi.PsiClassType;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.StubBasedPsiElement;
@@ -23,6 +24,7 @@
 import com.intellij.psi.tree.IElementType;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
 import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
@@ -38,7 +40,8 @@
  * @author Maxim.Medvedev
  */
 public abstract class GrReferenceListImpl extends GrStubElementBase<GrReferenceListStub> implements StubBasedPsiElement<GrReferenceListStub>, GrReferenceList {
-
+  private static final Logger LOG = Logger.getInstance(GrReferenceListImpl.class);
+  
   private PsiClassType[] cachedTypes = null;
 
   public GrReferenceListImpl(@NotNull ASTNode node) {
@@ -46,6 +49,41 @@
   }
 
   @Override
+  public void deleteChildInternal(@NotNull ASTNode child) {
+    PsiElement psi = child.getPsi();
+
+    if (psi instanceof GrCodeReferenceElement) {
+
+      GrCodeReferenceElement[] refs = getReferenceElements();
+      if (refs.length == 1) {
+        PsiElement keyword = getKeyword();
+        LOG.assertTrue(keyword != null);
+        keyword.delete();
+      }
+      else {
+        PsiElement comma = PsiUtil.skipWhitespacesAndComments(psi, refs[0] == psi, true);
+        if (comma != null && comma.getNode().getElementType() == GroovyTokenTypes.mCOMMA) {
+          comma.delete();
+        }
+      }
+
+      super.deleteChildInternal(child);
+    }
+    else {
+      super.deleteChildInternal(child);
+    }
+  }
+
+  @Nullable
+  private PsiElement getKeyword() {
+    PsiElement firstChild = getFirstChild();
+    if (firstChild != null && firstChild.getNode().getElementType() == getKeywordType()) {
+      return firstChild;
+    }
+    return null;
+  }
+
+  @Override
   public PsiElement getParent() {
     return getParentByStub();
   }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.java
index 400be53..ea18c1b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.java
@@ -25,6 +25,7 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
+import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
 import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
 import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
@@ -94,7 +95,7 @@
   }
 
   public GrMethod[] getMethods() {
-    return getStubOrPsiChildren(GroovyElementTypes.METHOD_DEFS, GrMethod.ARRAY_FACTORY);
+    return getStubOrPsiChildren(TokenSets.METHOD_DEFS, GrMethod.ARRAY_FACTORY);
   }
 
   public GrMembersDeclaration[] getMemberDeclarations() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
index ce4e6a1..9fac306 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
@@ -144,7 +144,7 @@
       }
     }
 
-    return (GrTypeElement)findChildByType(GroovyElementTypes.TYPE_ELEMENTS);
+    return (GrTypeElement)findChildByType(TokenSets.TYPE_ELEMENTS);
   }
 
   public PsiType getInferredReturnType() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightClassReferenceElement.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightClassReferenceElement.java
index 3fa5a21..9939742 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightClassReferenceElement.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightClassReferenceElement.java
@@ -125,6 +125,11 @@
   }
 
   @Override
+  public boolean isQualified() {
+    return false;
+  }
+
+  @Override
   public void accept(GroovyElementVisitor visitor) {
     //todo ???
   }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java
index 04b1c88..a29e9d3 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 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,17 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.jetbrains.plugins.groovy.mvc;
 
 import com.intellij.ProjectTopics;
 import com.intellij.codeInsight.actions.ReformatCodeProcessor;
+import com.intellij.openapi.application.Application;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.ModalityState;
 import com.intellij.openapi.components.AbstractProjectComponent;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.module.ModuleUtilCore;
 import com.intellij.openapi.project.DumbAwareRunnable;
 import com.intellij.openapi.project.ModuleAdapter;
 import com.intellij.openapi.project.Project;
@@ -246,12 +246,18 @@
       StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {
         @Override
         public void run() {
-          ApplicationManager.getApplication().invokeLater(new Runnable() {
-            @Override
-            public void run() {
-              runActions();
-            }
-          }, ModalityState.NON_MODAL);
+          Application app = ApplicationManager.getApplication();
+          if (!app.isUnitTestMode()) {
+            app.invokeLater(new Runnable() {
+              @Override
+              public void run() {
+                runActions();
+              }
+            }, ModalityState.NON_MODAL);
+          }
+          else {
+            runActions();
+          }
         }
       });
     }
@@ -270,7 +276,7 @@
     if (o instanceof VirtualFile) {
       final VirtualFile file = (VirtualFile)o;
       if (file.isValid()) {
-        final Module module = ModuleUtil.findModuleForFile(file, myProject);
+        final Module module = ModuleUtilCore.findModuleForFile(file, myProject);
         if (module == null) {
           return Collections.emptyList();
         }
@@ -296,7 +302,7 @@
         return;
       }
 
-      Pair<Object, SyncAction>[] actions = myActions.toArray(new Pair[myActions.size()]);
+      @SuppressWarnings("unchecked") Pair<Object, SyncAction>[] actions = myActions.toArray(new Pair[myActions.size()]);
       //get module by object and kill duplicates
 
       final Set<Trinity<Module, SyncAction, MvcFramework>> rawActions = new LinkedHashSet<Trinity<Module, SyncAction, MvcFramework>>();
@@ -379,7 +385,7 @@
       @Override
       void doAction(Module module, MvcFramework framework) {
         final Project project = module.getProject();
-        final MvcModuleStructureSynchronizer mvcModuleStructureSynchronizer = MvcModuleStructureSynchronizer.getInstance(project);
+        final MvcModuleStructureSynchronizer mvcModuleStructureSynchronizer = getInstance(project);
 
         if (mvcModuleStructureSynchronizer.myOutOfModuleDirectoryCreatedActionAdded) {
           mvcModuleStructureSynchronizer.myOutOfModuleDirectoryCreatedActionAdded = false;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java
index 67d1c37..7e71010 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java
@@ -49,6 +49,11 @@
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.JpsElementFactory;
+import org.jetbrains.jps.model.JpsSimpleElement;
+import org.jetbrains.jps.model.java.JavaSourceRootProperties;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 
 import java.io.File;
 import java.io.IOException;
@@ -82,10 +87,10 @@
                                                                              final MvcProjectStructure structure) {
     ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(structure.myModule);
 
-    Map<VirtualFile, Boolean> sourceRoots = new HashMap<VirtualFile, Boolean>();
+    Map<VirtualFile, JpsModuleSourceRootType> sourceRoots = new HashMap<VirtualFile, JpsModuleSourceRootType>();
     for (ContentEntry entry : moduleRootManager.getContentEntries()) {
       for (SourceFolder folder : entry.getSourceFolders()) {
-        sourceRoots.put(folder.getFile(), folder.isTestSource());
+        sourceRoots.put(folder.getFile(), folder.getRootType());
       }
     }
 
@@ -93,12 +98,14 @@
 
     final List<Consumer<ContentEntry>> actions = ContainerUtil.newArrayList();
 
-    for (final String src : structure.getSourceFolders()) {
-      addSourceFolder(root, src, false, actions, sourceRoots);
+    for (Map.Entry<JpsModuleSourceRootType<?>, Collection<String>> entry : structure.getSourceFolders().entrySet()) {
+      JpsModuleSourceRootType rootType = entry.getKey();
+
+      for (String src : entry.getValue()) {
+        addSourceFolder(root, src, rootType, actions, sourceRoots);
+      }
     }
-    for (final String src : structure.getTestFolders()) {
-      addSourceFolder(root, src, true, actions, sourceRoots);
-    }
+
     for (final String src : structure.getInvalidSourceFolders()) {
       removeSrcFolderFromRoots(root.findFileByRelativePath(src), actions, sourceRoots);
     }
@@ -138,7 +145,7 @@
 
   public static void removeSrcFolderFromRoots(final VirtualFile file,
                                               List<Consumer<ContentEntry>> actions,
-                                              Map<VirtualFile, Boolean> sourceRoots) {
+                                              Map<VirtualFile, JpsModuleSourceRootType> sourceRoots) {
     if (sourceRoots.containsKey(file)) {
       actions.add(new Consumer<ContentEntry>() {
         public void consume(ContentEntry contentEntry) {
@@ -199,37 +206,37 @@
 
   public static void addSourceFolder(@NotNull VirtualFile root,
                                      @NotNull String relativePath,
-                                     final boolean isTest,
+                                     final JpsModuleSourceRootType rootType,
                                      List<Consumer<ContentEntry>> actions,
-                                     Map<VirtualFile, Boolean> sourceRoots) {
+                                     Map<VirtualFile, JpsModuleSourceRootType> sourceRoots) {
     final VirtualFile src = root.findFileByRelativePath(relativePath);
     if (src == null) {
       return;
     }
 
-    Boolean existingFolderIsTest = sourceRoots.get(src);
+    JpsModuleSourceRootType existingRootType = sourceRoots.get(src);
 
-    if (existingFolderIsTest != null) {
-      if (isTest && !existingFolderIsTest) { // see http://youtrack.jetbrains.net/issue/IDEA-70642
-        actions.add(new Consumer<ContentEntry>() {
-          @Override
-          public void consume(ContentEntry entry) {
-            for (SourceFolder folder : entry.getSourceFolders()) {
-              if (Comparing.equal(folder.getFile(), src)) {
-                entry.removeSourceFolder(folder);
-                entry.addSourceFolder(src, isTest, "");
-                break;
-              }
+    if (rootType == JavaSourceRootType.TEST_SOURCE && (existingRootType != null && existingRootType != JavaSourceRootType.TEST_SOURCE)) { // see http://youtrack.jetbrains.net/issue/IDEA-70642
+      actions.add(new Consumer<ContentEntry>() {
+        @Override
+        public void consume(ContentEntry entry) {
+          for (SourceFolder folder : entry.getSourceFolders()) {
+            if (Comparing.equal(folder.getFile(), src)) {
+              entry.removeSourceFolder(folder);
+              JpsSimpleElement<JavaSourceRootProperties> properties = JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(""));
+              entry.addSourceFolder(src, rootType, properties);
+              break;
             }
           }
-        });
-      }
+        }
+      });
       return;
     }
 
     actions.add(new Consumer<ContentEntry>() {
       public void consume(ContentEntry contentEntry) {
-        contentEntry.addSourceFolder(src, isTest, "");
+        JpsSimpleElement<JavaSourceRootProperties> properties = JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(""));
+        contentEntry.addSourceFolder(src, rootType, properties);
       }
     });
   }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcProjectStructure.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcProjectStructure.java
index 112f82f..e13c50e 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcProjectStructure.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcProjectStructure.java
@@ -18,7 +18,9 @@
 
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.MultiMap;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -57,8 +59,8 @@
   @NotNull
   public abstract String getUserLibraryName();
 
-  public abstract String[] getSourceFolders();
-  public abstract String[] getTestFolders();
+  public abstract MultiMap<JpsModuleSourceRootType<?>, String> getSourceFolders();
+
   public abstract String[] getInvalidSourceFolders();
 
   public abstract String[] getExcludedFolders();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java
index 422b557..0dd6b2c 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java
@@ -18,6 +18,7 @@
 
 import com.intellij.openapi.util.Key;
 import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
 import com.intellij.psi.util.PsiTreeUtil;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
@@ -114,6 +115,7 @@
                 final PsiElement qualifier = refExpr.getQualifier();
                 if (!(qualifier instanceof GrReferenceExpression)) {
                   refExpr.setQualifier(factory.createReferenceExpressionFromText(memberClass.getQualifiedName()));
+                  JavaCodeStyleManager.getInstance(manager.getProject()).shortenClassReferences(refExpr.getQualifier());
                   return;
                 }
               }
@@ -140,4 +142,13 @@
       }
     }
   }
+
+  public static void clearContextInfo(PsiElement scope) {
+    scope.putCopyableUserData(QUALIFIER_CLASS_KEY, null);
+    scope.putCopyableUserData(REF_TO_CLASS, null);
+    scope.putCopyableUserData(REF_TO_MEMBER, null);
+    for (PsiElement child = scope.getFirstChild(); child != null; child = child.getNextSibling()) {
+      clearContextInfo(child);
+    }
+  }
 }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java
index 5e2e2af..b8b2857 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java
@@ -41,6 +41,7 @@
 import org.jetbrains.plugins.groovy.refactoring.introduce.field.GrIntroduceFieldHandler;
 import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrIntroduceParameterHandler;
 import org.jetbrains.plugins.groovy.refactoring.introduce.variable.GrIntroduceVariableHandler;
+import org.jetbrains.plugins.groovy.refactoring.memberPullUp.GrPullUpHandler;
 
 /**
  * @author ilyas
@@ -129,4 +130,17 @@
   public RefactoringActionHandler getIntroduceConstantHandler() {
     return new GrIntroduceConstantHandler();
   }
+
+  @Nullable
+  @Override
+  public RefactoringActionHandler getPullUpHandler() {
+    return new GrPullUpHandler();
+  }
+
+  @Nullable
+  @Override
+  public RefactoringActionHandler getExtractInterfaceHandler() {
+    //return new ExtractInterfaceHandler();
+    return null;
+  }
 }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrClassMemberReferenceVisitor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrClassMemberReferenceVisitor.java
new file mode 100644
index 0000000..92a0735
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrClassMemberReferenceVisitor.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 org.jetbrains.plugins.groovy.refactoring.classMembers;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
+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.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
+import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
+
+/**
+ * @author Max Medvedev
+ */
+public abstract class GrClassMemberReferenceVisitor extends GroovyRecursiveElementVisitor {
+  private final PsiClass myClass;
+
+  public GrClassMemberReferenceVisitor(@NotNull PsiClass aClass) {
+    myClass = aClass;
+  }
+
+  @Override
+  public void visitReferenceExpression(GrReferenceExpression ref) {
+    GrExpression qualifier = ref.getQualifier();
+
+    if (qualifier != null && !(PsiUtil.isThisOrSuperRef(qualifier))) {
+      qualifier.accept(this);
+
+      if (!(qualifier instanceof GrReferenceExpression) || !(((GrReferenceExpression) qualifier).resolve() instanceof PsiClass)) {
+        return;
+      }
+    }
+
+    PsiElement resolved = ref.resolve();
+    if (resolved instanceof GrMember) {
+      PsiClass containingClass = ((GrMember)resolved).getContainingClass();
+      if (isPartOf(myClass, containingClass)) {
+        visitClassMemberReferenceElement((GrMember)resolved, ref);
+      }
+    }
+  }
+
+  @Override
+  public void visitCodeReferenceElement(GrCodeReferenceElement reference) {
+    PsiElement referencedElement = reference.resolve();
+    if (referencedElement instanceof GrTypeDefinition) {
+      final GrTypeDefinition referencedClass = (GrTypeDefinition)referencedElement;
+      if (PsiTreeUtil.isAncestor(myClass, referencedElement, true) ||
+          isPartOf(myClass, referencedClass.getContainingClass())) {
+        visitClassMemberReferenceElement((GrMember)referencedElement, reference);
+      }
+    }
+  }
+
+  private static boolean isPartOf(@NotNull PsiClass aClass, @Nullable PsiClass containingClass) {
+    if (containingClass == null) return false;
+    return aClass.equals(containingClass) || aClass.isInheritor(containingClass, true);
+  }
+
+  protected abstract void visitClassMemberReferenceElement(GrMember resolved, GrReferenceElement ref);
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrDependantMembersCollector.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrDependantMembersCollector.java
new file mode 100644
index 0000000..1159e2e8
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrDependantMembersCollector.java
@@ -0,0 +1,52 @@
+/*
+ * 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.refactoring.classMembers;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.PsiMethod;
+import com.intellij.refactoring.classMembers.DependentMembersCollectorBase;
+import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrDependantMembersCollector extends DependentMembersCollectorBase<GrMember, PsiClass> {
+  public GrDependantMembersCollector(PsiClass clazz, PsiClass superClass) {
+    super(clazz, superClass);
+  }
+
+  @Override
+  public void collect(GrMember member) {
+    member.accept(new GrClassMemberReferenceVisitor(getClazz()) {
+      @Override
+      protected void visitClassMemberReferenceElement(GrMember classMember, GrReferenceElement ref) {
+        if (!existsInSuperClass(classMember)) {
+          myCollection.add(classMember);
+        }
+      }
+    });
+  }
+
+  private boolean existsInSuperClass(PsiMember classMember) {
+    if (getSuperClass() == null) return false;
+    if (!(classMember instanceof PsiMethod)) return false;
+    final PsiMethod method = ((PsiMethod)classMember);
+    final PsiMethod methodBySignature = (getSuperClass()).findMethodBySignature(method, true);
+    return methodBySignature != null;
+  }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberInfo.java
new file mode 100644
index 0000000..e1caae8
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberInfo.java
@@ -0,0 +1,186 @@
+/*
+ * 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.refactoring.classMembers;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrMemberInfo extends MemberInfoBase<GrMember> {
+  public GrMemberInfo(GrMember member) {
+    this(member, false, null);
+  }
+
+  public GrMemberInfo(GrMember member, boolean isSuperClass, GrReferenceList sourceReferenceList) {
+    super(member);
+    LOG.assertTrue(member.isValid());
+    mySourceReferenceList = sourceReferenceList;
+    if (member instanceof GrMethod) {
+      GrMethod method = (GrMethod)member;
+      displayName = PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER | PsiFormatUtil.SHOW_PARAMETERS,
+                                               PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER);
+      PsiMethod[] superMethods = method.findSuperMethods();
+      if (superMethods.length > 0) {
+        overrides = !superMethods[0].hasModifierProperty(PsiModifier.ABSTRACT) ? Boolean.TRUE : Boolean.FALSE;
+      }
+      else {
+        overrides = null;
+      }
+
+      isStatic = method.hasModifierProperty(PsiModifier.STATIC);
+    }
+    else if (member instanceof GrField) {
+      GrField field = (GrField)member;
+      displayName = PsiFormatUtil
+        .formatVariable(field, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER, PsiSubstitutor.EMPTY);
+      isStatic = field.hasModifierProperty(PsiModifier.STATIC);
+      overrides = null;
+    }
+    else if (member instanceof GrTypeDefinition) {
+      GrTypeDefinition aClass = (GrTypeDefinition)member;
+
+      if (isSuperClass) {
+        if (aClass.isInterface()) {
+          displayName = RefactoringBundle.message("member.info.implements.0", aClass.getName());
+          overrides = Boolean.FALSE;
+        }
+        else {
+          displayName = RefactoringBundle.message("member.info.extends.0", aClass.getName());
+          overrides = Boolean.TRUE;
+        }
+      }
+      else {
+        displayName = aClass.getName();
+        overrides = null;
+      }
+
+      isStatic = aClass.hasModifierProperty(PsiModifier.STATIC);
+    }
+    else {
+      LOG.assertTrue(false);
+      isStatic = false;
+      displayName = "";
+      overrides = null;
+    }
+  }
+
+  public GrReferenceList getSourceReferenceList() {
+    return mySourceReferenceList;
+  }
+
+  public static List<GrMemberInfo> extractClassMembers(GrTypeDefinition subclass, Filter<GrMember> filter, boolean extractInterfacesDeep) {
+    List<GrMemberInfo> members = new ArrayList<GrMemberInfo>();
+    extractClassMembers(subclass, members, filter, extractInterfacesDeep);
+    return members;
+  }
+
+  public static void extractClassMembers(PsiClass subclass,
+                                         List<GrMemberInfo> result,
+                                         Filter<GrMember> filter,
+                                         final boolean extractInterfacesDeep) {
+
+    if (!(subclass instanceof GrTypeDefinition)) return;
+
+
+    if (extractInterfacesDeep) {
+      extractSuperInterfaces(subclass, filter, result, ContainerUtil.<PsiClass>newHashSet());
+    }
+    else {
+      PsiClass[] interfaces = subclass.getInterfaces();
+      GrReferenceList sourceRefList = subclass.isInterface()
+                                      ? ((GrTypeDefinition)subclass).getExtendsClause()
+                                      : ((GrTypeDefinition)subclass).getImplementsClause();
+      for (PsiClass anInterface : interfaces) {
+        if (anInterface instanceof GrTypeDefinition && filter.includeMember((GrMember)anInterface)) {
+          result.add(new GrMemberInfo((GrMember)anInterface, true, sourceRefList));
+        }
+      }
+    }
+
+
+    PsiClass[] innerClasses = subclass.getInnerClasses();
+    for (PsiClass innerClass : innerClasses) {
+      if (innerClass instanceof GrTypeDefinition && filter.includeMember((GrMember)innerClass)) {
+        result.add(new GrMemberInfo((GrMember)innerClass));
+      }
+    }
+
+    GrMethod[] methods = ((GrTypeDefinition)subclass).getCodeMethods();
+    for (GrMethod method : methods) {
+      if (!method.isConstructor() && filter.includeMember(method)) {
+        result.add(new GrMemberInfo(method));
+      }
+    }
+
+    GrField[] fields = ((GrTypeDefinition)subclass).getCodeFields();
+    for (final GrField field : fields) {
+      if (filter.includeMember(field)) {
+        result.add(new GrMemberInfo(field));
+      }
+    }
+  }
+
+  private static void extractSuperInterfaces(final PsiClass subclass,
+                                             final Filter<GrMember> filter,
+                                             final List<GrMemberInfo> result,
+                                             Set<PsiClass> processed) {
+    if (!processed.contains(subclass)) {
+      processed.add(subclass);
+      if (subclass instanceof GrTypeDefinition) {
+        extractSuperInterfacesFromReferenceList(((GrTypeDefinition)subclass).getExtendsClause(), filter, result, processed);
+        extractSuperInterfacesFromReferenceList(((GrTypeDefinition)subclass).getImplementsClause(), filter, result, processed);
+      }
+    }
+  }
+
+  private static void extractSuperInterfacesFromReferenceList(final GrReferenceList referenceList,
+                                                              final Filter<GrMember> filter,
+                                                              final List<GrMemberInfo> result,
+                                                              final Set<PsiClass> processed) {
+    if (referenceList != null) {
+      final PsiClassType[] extendsListTypes = referenceList.getReferenceTypes();
+      for (PsiClassType extendsListType : extendsListTypes) {
+        final PsiClass aSuper = extendsListType.resolve();
+        if (aSuper instanceof GrTypeDefinition) {
+          if (aSuper.isInterface()) {
+            if (filter.includeMember((GrMember)aSuper)) {
+              result.add(new GrMemberInfo((GrMember)aSuper, true, referenceList));
+            }
+          }
+          else {
+            extractSuperInterfaces(aSuper, filter, result, processed);
+          }
+        }
+      }
+    }
+  }
+
+  private final GrReferenceList mySourceReferenceList;
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberInfoStorage.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberInfoStorage.java
new file mode 100644
index 0000000..e2ad586
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberInfoStorage.java
@@ -0,0 +1,89 @@
+/*
+ * 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.refactoring.classMembers;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassType;
+import com.intellij.psi.util.MethodSignatureUtil;
+import com.intellij.refactoring.classMembers.AbstractMemberInfoStorage;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrExtendsClause;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrImplementsClause;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+
+import java.util.ArrayList;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrMemberInfoStorage extends AbstractMemberInfoStorage<GrMember, PsiClass, GrMemberInfo> {
+  public GrMemberInfoStorage(GrTypeDefinition aClass, MemberInfoBase.Filter<GrMember> memberInfoFilter) {
+    super(aClass, memberInfoFilter);
+  }
+
+  @Override
+  protected boolean isInheritor(PsiClass baseClass, PsiClass aClass) {
+    return aClass.isInheritor(baseClass, true);
+  }
+
+  @Override
+  protected void extractClassMembers(PsiClass aClass, ArrayList<GrMemberInfo> temp) {
+    GrMemberInfo.extractClassMembers(aClass, temp, myFilter, false);
+  }
+
+  @Override
+  protected boolean memberConflict(GrMember member1, GrMember member) {
+    if (member instanceof GrMethod && member1 instanceof GrMethod) {
+      return MethodSignatureUtil.areSignaturesEqual((GrMethod)member, (GrMethod)member1);
+    }
+    else if (member instanceof GrField && member1 instanceof GrField ||
+             member instanceof GrTypeDefinition && member1 instanceof GrTypeDefinition) {
+      return member.getName().equals(member1.getName());
+    }
+
+    return false;
+  }
+
+  @Override
+  protected void buildSubClassesMap(PsiClass aClass) {
+    if (aClass instanceof GrTypeDefinition) {
+      final GrExtendsClause extendsList = ((GrTypeDefinition)aClass).getExtendsClause();
+      if (extendsList != null) {
+        buildSubClassesMapForList(extendsList.getReferenceTypes(), (GrTypeDefinition)aClass);
+      }
+
+      final GrImplementsClause implementsList = ((GrTypeDefinition)aClass).getImplementsClause();
+      if (implementsList != null) {
+        buildSubClassesMapForList(implementsList.getReferenceTypes(), (GrTypeDefinition)aClass);
+      }
+    }
+  }
+
+  private void buildSubClassesMapForList(final PsiClassType[] classesList, GrTypeDefinition aClass) {
+    for (int i = 0; i < classesList.length; i++) {
+      PsiClassType element = classesList[i];
+      PsiClass resolved = element.resolve();
+      if (resolved instanceof GrTypeDefinition) {
+        GrTypeDefinition superClass = (GrTypeDefinition)resolved;
+        getSubclasses(superClass).add(aClass);
+        buildSubClassesMap(superClass);
+      }
+    }
+  }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberSelectionTable.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberSelectionTable.java
new file mode 100644
index 0000000..e508284
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberSelectionTable.java
@@ -0,0 +1,114 @@
+/*
+ * 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.refactoring.classMembers;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiModifier;
+import com.intellij.psi.PsiModifierList;
+import com.intellij.refactoring.classMembers.MemberInfoModel;
+import com.intellij.refactoring.ui.AbstractMemberSelectionTable;
+import com.intellij.ui.RowIcon;
+import com.intellij.util.IconUtil;
+import com.intellij.util.VisibilityIcons;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+
+import javax.swing.*;
+import java.util.List;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrMemberSelectionTable extends AbstractMemberSelectionTable<GrMember, GrMemberInfo> {
+
+  public GrMemberSelectionTable(final List<GrMemberInfo> memberInfos, String abstractColumnHeader) {
+    this(memberInfos, null, abstractColumnHeader);
+  }
+
+  public GrMemberSelectionTable(final List<GrMemberInfo> memberInfos, MemberInfoModel<GrMember, GrMemberInfo> memberInfoModel, String abstractColumnHeader) {
+    super(memberInfos, memberInfoModel, abstractColumnHeader);
+  }
+
+  @Nullable
+  @Override
+  protected Object getAbstractColumnValue(GrMemberInfo memberInfo) {
+    if (!(memberInfo.getMember() instanceof PsiMethod)) return null;
+    if (memberInfo.isStatic()) return null;
+
+    PsiMethod method = (PsiMethod)memberInfo.getMember();
+    if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
+      final Boolean fixedAbstract = myMemberInfoModel.isFixedAbstract(memberInfo);
+      if (fixedAbstract != null) return fixedAbstract;
+    }
+
+    if (!myMemberInfoModel.isAbstractEnabled(memberInfo)) {
+      return myMemberInfoModel.isAbstractWhenDisabled(memberInfo);
+    }
+    else {
+      return memberInfo.isToAbstract() ? Boolean.TRUE : Boolean.FALSE;
+    }
+  }
+
+  @Override
+  protected boolean isAbstractColumnEditable(int rowIndex) {
+    GrMemberInfo info = myMemberInfos.get(rowIndex);
+    if (!(info.getMember() instanceof PsiMethod)) return false;
+    if (info.isStatic()) return false;
+
+    PsiMethod method = (PsiMethod)info.getMember();
+    if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
+      if (myMemberInfoModel.isFixedAbstract(info) != null) {
+        return false;
+      }
+    }
+
+    return info.isChecked() && myMemberInfoModel.isAbstractEnabled(info);
+  }
+
+
+  @Override
+  protected void setVisibilityIcon(GrMemberInfo memberInfo, RowIcon icon) {
+    PsiMember member = memberInfo.getMember();
+    PsiModifierList modifiers = member != null ? member.getModifierList() : null;
+    if (modifiers != null) {
+      VisibilityIcons.setVisibilityIcon(modifiers, icon);
+    }
+    else {
+      icon.setIcon(IconUtil.getEmptyIcon(true), VISIBILITY_ICON_POSITION);
+    }
+  }
+
+  @Override
+  protected Icon getOverrideIcon(GrMemberInfo memberInfo) {
+    PsiMember member = memberInfo.getMember();
+    Icon overrideIcon = EMPTY_OVERRIDE_ICON;
+    if (member instanceof PsiMethod) {
+      if (Boolean.TRUE.equals(memberInfo.getOverrides())) {
+        overrideIcon = AllIcons.General.OverridingMethod;
+      }
+      else if (Boolean.FALSE.equals(memberInfo.getOverrides())) {
+        overrideIcon = AllIcons.General.ImplementingMethod;
+      }
+      else {
+        overrideIcon = EMPTY_OVERRIDE_ICON;
+      }
+    }
+    return overrideIcon;
+  }
+}
+
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GroovyClassMembersRefactoringSupport.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GroovyClassMembersRefactoringSupport.java
new file mode 100644
index 0000000..46d9b72
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GroovyClassMembersRefactoringSupport.java
@@ -0,0 +1,36 @@
+/*
+ * 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.refactoring.classMembers;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.refactoring.classMembers.ClassMembersRefactoringSupport;
+import com.intellij.refactoring.classMembers.DependentMembersCollectorBase;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+
+/**
+ * @author Max Medvedev
+ */
+public class GroovyClassMembersRefactoringSupport implements ClassMembersRefactoringSupport {
+  @Override
+  public DependentMembersCollectorBase createDependentMembersCollector(Object clazz, Object superClass) {
+    return new GrDependantMembersCollector((PsiClass)clazz, (PsiClass)superClass);
+  }
+
+  @Override
+  public boolean isProperMember(MemberInfoBase member) {
+    return member instanceof GrMemberInfo;
+  }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java
index bc6882b..0846039 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java
@@ -107,7 +107,7 @@
 
     String name = method.getName();
 
-    boolean isAbstract = GenerationUtil.isAbstractInJava(method);
+    boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
 
     PsiModifierList modifierList = method.getModifierList();
 
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java
index 8179b12..7b0769c 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java
@@ -269,15 +269,6 @@
     return curClass;
   }
 
-  static boolean isAbstractInJava(PsiMethod method) {
-    if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
-      return true;
-    }
-
-    final PsiClass psiClass = method.getContainingClass();
-    return psiClass != null && psiClass.isInterface();
-  }
-
   static void writeTypeParameters(StringBuilder text,
                                   PsiTypeParameterListOwner typeParameterListOwner,
                                   final ClassNameProvider classNameProvider) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java
index 3c6d2d4..1ac17ed6 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.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.
@@ -229,7 +229,7 @@
       return; //does not have a java image
     }
 
-    boolean isAbstract = GenerationUtil.isAbstractInJava(method);
+    boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
 
     PsiModifierList modifierList = method.getModifierList();
 
@@ -342,7 +342,7 @@
         if (baseClass == null) continue;
         final String qname = baseClass.getQualifiedName();
         if (DEFAULT_BASE_CLASS_NAME.equals(qname) || GROOVY_OBJECT_SUPPORT.equals(qname) ||
-            GenerationUtil.isAbstractInJava(method) && typeDefinition.isInheritor(baseClass, true)) {
+            method.hasModifierProperty(PsiModifier.ABSTRACT) && typeDefinition.isInheritor(baseClass, true)) {
           if (method.isConstructor()) continue;
           methods.add(mirrorMethod(typeDefinition, method, baseClass, signature.getSubstitutor()));
         }
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractInterface/GrExtractInterfaceHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractInterface/GrExtractInterfaceHandler.java
new file mode 100644
index 0000000..1b7a112
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractInterface/GrExtractInterfaceHandler.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.plugins.groovy.refactoring.extractInterface;
+
+import com.intellij.history.LocalHistory;
+import com.intellij.history.LocalHistoryAction;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.ScrollType;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.refactoring.HelpID;
+import com.intellij.refactoring.RefactoringActionHandler;
+import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.extractInterface.ExtractClassUtil;
+import com.intellij.refactoring.extractSuperclass.ExtractSuperClassUtil;
+import com.intellij.refactoring.lang.ElementsHandler;
+import com.intellij.refactoring.memberPullUp.PullUpHelper;
+import com.intellij.refactoring.util.CommonRefactoringUtil;
+import com.intellij.refactoring.util.DocCommentPolicy;
+import com.intellij.refactoring.util.classMembers.MemberInfo;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+
+import javax.swing.*;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrExtractInterfaceHandler implements RefactoringActionHandler, ElementsHandler {
+  public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
+    int offset = editor.getCaretModel().getOffset();
+    editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
+    PsiElement element = file.findElementAt(offset);
+    while (true) {
+      if (element == null || element instanceof PsiFile) {
+        String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("error.wrong.caret.position.class"));
+        CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.EXTRACT_INTERFACE);
+        return;
+      }
+
+      if (element instanceof GrTypeDefinition && !(element instanceof GrAnonymousClassDefinition)) {
+        invoke(project, new PsiElement[]{element}, dataContext);
+        return;
+      }
+
+      element = element.getParent();
+    }
+  }
+
+  public void invoke(@NotNull final Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
+    if (elements.length != 1) return;
+
+
+    myProject = project;
+    myClass = (PsiClass)elements[0];
+
+
+    if (!CommonRefactoringUtil.checkReadOnlyStatus(project, myClass)) return;
+
+/* todo
+    final JavaExtractSuperBaseDialog dialog = new ExtractInterfaceDialog(myProject, myClass);
+    dialog.show();
+    if (!dialog.isOK() || !dialog.isExtractSuperclass()) return;
+
+    final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
+    ExtractSuperClassUtil.checkSuperAccessible(dialog.getTargetDirectory(), conflicts, myClass);
+    if (!ExtractSuperClassUtil.showConflicts(dialog, conflicts, myProject)) return;
+
+    CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
+      public void run() {
+        ApplicationManager.getApplication().runWriteAction(new Runnable() {
+          public void run() {
+            myInterfaceName = dialog.getExtractedSuperName();
+            mySelectedMembers = ArrayUtil.toObjectArray(dialog.getSelectedMemberInfos(), MemberInfo.class);
+            myTargetDir = dialog.getTargetDirectory();
+            myJavaDocPolicy = new DocCommentPolicy(dialog.getDocCommentPolicy());
+            try {
+              doRefactoring();
+            }
+            catch (IncorrectOperationException e) {
+              LOG.error(e);
+            }
+          }
+        });
+      }
+    }, REFACTORING_NAME, null);*/
+  }
+
+  private void doRefactoring() throws IncorrectOperationException {
+    LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName());
+    final PsiClass anInterface;
+    try {
+      anInterface = extractInterface(myTargetDir, myClass, myInterfaceName, mySelectedMembers, myJavaDocPolicy);
+    }
+    finally {
+      a.finish();
+    }
+
+
+    if (anInterface != null) {
+      final SmartPsiElementPointer<PsiClass> classPointer =
+        SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(myClass);
+      final SmartPsiElementPointer<PsiClass> interfacePointer =
+        SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(anInterface);
+      final Runnable turnRefsToSuperRunnable = new Runnable() {
+        @Override
+        public void run() {
+          ExtractClassUtil.askAndTurnRefsToSuper(myProject, classPointer, interfacePointer);
+        }
+      };
+      SwingUtilities.invokeLater(turnRefsToSuperRunnable);
+    }
+  }
+
+  public static PsiClass extractInterface(PsiDirectory targetDir,
+                                          PsiClass aClass,
+                                          String interfaceName,
+                                          MemberInfo[] selectedMembers,
+                                          DocCommentPolicy javaDocPolicy) throws IncorrectOperationException {
+    PsiClass anInterface = JavaDirectoryService.getInstance().createInterface(targetDir, interfaceName);
+    PsiJavaCodeReferenceElement ref = ExtractSuperClassUtil.createExtendingReference(anInterface, aClass, selectedMembers);
+    final PsiReferenceList referenceList = aClass.isInterface() ? aClass.getExtendsList() : aClass.getImplementsList();
+    assert referenceList != null;
+    referenceList.add(ref);
+    PullUpHelper pullUpHelper = new PullUpHelper(aClass, anInterface, selectedMembers, javaDocPolicy);
+    pullUpHelper.moveMembersToBase();
+    return anInterface;
+  }
+
+  private String getCommandName() {
+    return RefactoringBundle.message("extract.interface.command.name", myInterfaceName, DescriptiveNameUtil.getDescriptiveName(myClass));
+  }
+
+  public boolean isEnabledOnElements(PsiElement[] elements) {
+    return elements.length == 1 && elements[0] instanceof PsiClass;
+  }
+
+  private static final Logger LOG = Logger.getInstance(GrExtractInterfaceHandler.class);
+  public static final String REFACTORING_NAME = RefactoringBundle.message("extract.interface.title");
+  private Project myProject;
+  private PsiClass myClass;
+  private String myInterfaceName;
+  private MemberInfo[] mySelectedMembers;
+  private PsiDirectory myTargetDir;
+  private DocCommentPolicy myJavaDocPolicy;
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java
new file mode 100644
index 0000000..5fc3aa9
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java
@@ -0,0 +1,196 @@
+/*
+ * 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.refactoring.memberPullUp;
+
+import com.intellij.openapi.help.HelpManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiDocCommentOwner;
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.statistics.StatisticsInfo;
+import com.intellij.psi.statistics.StatisticsManager;
+import com.intellij.refactoring.HelpID;
+import com.intellij.refactoring.JavaRefactoringSettings;
+import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.classMembers.AbstractUsesDependencyMemberInfoModel;
+import com.intellij.refactoring.classMembers.MemberInfoModel;
+import com.intellij.refactoring.memberPullUp.PullUpDialogBase;
+import com.intellij.refactoring.memberPullUp.PullUpHelper;
+import com.intellij.refactoring.ui.AbstractMemberSelectionTable;
+import com.intellij.refactoring.ui.ClassCellRenderer;
+import com.intellij.refactoring.ui.DocCommentPanel;
+import com.intellij.refactoring.util.DocCommentPolicy;
+import com.intellij.refactoring.util.RefactoringHierarchyUtil;
+import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfoStorage;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberSelectionTable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.List;
+
+/**
+ * @author Max Medvedev
+ */
+class GrPullUpDialog extends PullUpDialogBase<GrMemberInfoStorage, GrMemberInfo, GrMember, PsiClass> {
+  private final Callback myCallback;
+  private DocCommentPanel myJavaDocPanel;
+
+  private final InterfaceContainmentVerifier myInterfaceContainmentVerifier = new InterfaceContainmentVerifier() {
+    public boolean checkedInterfacesContain(PsiMethod psiMethod) {
+      return PullUpHelper.checkedInterfacesContain(myMemberInfos, psiMethod);
+    }
+  };
+
+  private static final String PULL_UP_STATISTICS_KEY = "pull.up##";
+
+  public interface Callback {
+    boolean checkConflicts(GrPullUpDialog dialog);
+  }
+
+  public GrPullUpDialog(Project project,
+                        PsiClass typeDefinition,
+                        List<PsiClass> superClasses,
+                        GrMemberInfoStorage storage,
+                        GrPullUpHandler handler) {
+    super(project, typeDefinition, superClasses, storage, GrPullUpHandler.REFACTORING_NAME);
+
+    myCallback = handler;
+
+    init();
+  }
+
+  public int getJavaDocPolicy() {
+    return myJavaDocPanel.getPolicy();
+  }
+
+  protected String getDimensionServiceKey() {
+    return "#com.intellij.refactoring.memberPullUp.PullUpDialog";
+  }
+
+  InterfaceContainmentVerifier getContainmentVerifier() {
+    return myInterfaceContainmentVerifier;
+  }
+
+  @Override
+  protected void initClassCombo(JComboBox classCombo) {
+    classCombo.setRenderer(new ClassCellRenderer(classCombo.getRenderer()));
+    classCombo.addItemListener(new ItemListener() {
+      public void itemStateChanged(ItemEvent e) {
+        if (e.getStateChange() == ItemEvent.SELECTED) {
+          if (myMemberSelectionPanel != null) {
+           // ((MyMemberInfoModel)myMemberInfoModel).setSuperClass(getSuperClass());
+            myMemberSelectionPanel.getTable().setMemberInfos(myMemberInfos);
+            myMemberSelectionPanel.getTable().fireExternalDataChange();
+          }
+        }
+      }
+    });
+  }
+
+  protected PsiClass getPreselection() {
+    PsiClass preselection = RefactoringHierarchyUtil.getNearestBaseClass(myClass, false);
+
+    final String statKey = PULL_UP_STATISTICS_KEY + myClass.getQualifiedName();
+    for (StatisticsInfo info : StatisticsManager.getInstance().getAllValues(statKey)) {
+      final String superClassName = info.getValue();
+      PsiClass superClass = null;
+      for (PsiClass aClass : mySuperClasses) {
+        if (Comparing.strEqual(superClassName, aClass.getQualifiedName())) {
+          superClass = aClass;
+          break;
+        }
+      }
+      if (superClass != null && StatisticsManager.getInstance().getUseCount(info) > 0) {
+        preselection = superClass;
+        break;
+      }
+    }
+    return preselection;
+  }
+
+  protected void doHelpAction() {
+    HelpManager.getInstance().invokeHelp(HelpID.MEMBERS_PULL_UP);
+  }
+
+  protected void doAction() {
+    if (!myCallback.checkConflicts(this)) return;
+    JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC = myJavaDocPanel.getPolicy();
+    final PsiClass superClass = getSuperClass();
+    String name = superClass.getQualifiedName();
+    if (name != null) {
+      StatisticsManager
+        .getInstance().incUseCount(new StatisticsInfo(PULL_UP_STATISTICS_KEY + myClass.getQualifiedName(), name));
+    }
+
+    List<GrMemberInfo> infos = getSelectedMemberInfos();
+    GrPullUpHelper processor =
+      new GrPullUpHelper(myClass, superClass, infos.toArray(new GrMemberInfo[infos.size()]), new DocCommentPolicy(getJavaDocPolicy()));
+    invokeRefactoring(processor);
+    close(OK_EXIT_CODE);
+  }
+
+  @Override
+  protected void addCustomElementsToCentralPanel(JPanel panel) {
+    myJavaDocPanel = new DocCommentPanel(RefactoringBundle.message("javadoc.for.abstracts"));
+    myJavaDocPanel.setPolicy(JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC);
+    boolean hasJavadoc = false;
+    for (GrMemberInfo info : myMemberInfos) {
+      final PsiMember member = info.getMember();
+      if (myMemberInfoModel.isAbstractEnabled(info) &&
+          member instanceof PsiDocCommentOwner &&
+          ((PsiDocCommentOwner)member).getDocComment() != null) {
+        hasJavadoc = true;
+        break;
+      }
+    }
+    UIUtil.setEnabled(myJavaDocPanel, hasJavadoc, true);
+    panel.add(myJavaDocPanel, BorderLayout.EAST);
+  }
+
+  @Override
+  protected AbstractMemberSelectionTable<GrMember, GrMemberInfo> createMemberSelectionTable(List<GrMemberInfo> infos) {
+    return new GrMemberSelectionTable(infos, RefactoringBundle.message("make.abstract"));
+  }
+
+  @Override
+  protected MemberInfoModel<GrMember, GrMemberInfo> createMemberInfoModel() {
+    //return new UsedByDependencyMemberInfoModel<PyElement, PyClass, PyMemberInfo>(myClass);
+    return new MyMemberInfoModel(myClass, getSuperClass(), false);
+  }
+
+  private static class MyMemberInfoModel extends AbstractUsesDependencyMemberInfoModel<GrMember, PsiClass, GrMemberInfo> {
+    public MyMemberInfoModel(PsiClass aClass, PsiClass superClass, boolean recursive) {
+      super(aClass, superClass, recursive);
+    }
+
+    @Override
+    protected int doCheck(@NotNull GrMemberInfo memberInfo, int problem) {
+      if (problem == ERROR && memberInfo.isStatic()) {
+        return WARNING;
+      }
+      return problem;
+    }
+  }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHandler.java
new file mode 100644
index 0000000..5336150
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHandler.java
@@ -0,0 +1,201 @@
+/*
+ * 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.refactoring.memberPullUp;
+
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.ScrollType;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.psi.*;
+import com.intellij.refactoring.HelpID;
+import com.intellij.refactoring.RefactoringActionHandler;
+import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+import com.intellij.refactoring.lang.ElementsHandler;
+import com.intellij.refactoring.memberPullUp.PullUpConflictsUtil;
+import com.intellij.refactoring.ui.ConflictsDialog;
+import com.intellij.refactoring.util.CommonRefactoringUtil;
+import com.intellij.refactoring.util.RefactoringHierarchyUtil;
+import com.intellij.util.containers.MultiMap;
+import org.codehaus.groovy.runtime.DefaultGroovyMethods;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfoStorage;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrPullUpHandler implements RefactoringActionHandler, GrPullUpDialog.Callback, ElementsHandler {
+  private static final Logger LOG = Logger.getInstance(GrPullUpHandler.class);
+  public static final String REFACTORING_NAME = RefactoringBundle.message("pull.members.up.title");
+
+  private PsiClass mySubclass;
+  private Project myProject;
+
+  public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
+    int offset = editor.getCaretModel().getOffset();
+    editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
+    PsiElement element = file.findElementAt(offset);
+
+    while (true) {
+      if (element == null || element instanceof PsiFile) {
+        String message = RefactoringBundle
+          .getCannotRefactorMessage(RefactoringBundle.message("the.caret.should.be.positioned.inside.a.class.to.pull.members.from"));
+        CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP);
+        return;
+      }
+
+
+      if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return;
+
+
+      if (element instanceof GrTypeDefinition || element instanceof GrField || element instanceof GrMethod) {
+        invoke(project, new PsiElement[]{element}, dataContext);
+        return;
+      }
+
+      element = element.getParent();
+    }
+  }
+
+  public void invoke(@NotNull final Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
+    if (elements.length != 1) return;
+
+    myProject = project;
+
+    PsiElement element = elements[0];
+    GrTypeDefinition aClass;
+    PsiElement aMember = null;
+
+    if (element instanceof GrTypeDefinition) {
+      aClass = (GrTypeDefinition)element;
+    }
+    else if (element instanceof GrMethod) {
+      aClass = DefaultGroovyMethods.asType(((GrMethod)element).getContainingClass(), GrTypeDefinition.class);
+      aMember = element;
+    }
+    else if (element instanceof GrField) {
+      aClass = DefaultGroovyMethods.asType(((GrField)element).getContainingClass(), GrTypeDefinition.class);
+      aMember = element;
+    }
+    else {
+      return;
+    }
+
+
+    invokeImpl(project, dataContext, aClass, aMember);
+  }
+
+  private void invokeImpl(Project project, DataContext dataContext, GrTypeDefinition aClass, PsiElement aMember) {
+    final Editor editor = dataContext != null ? PlatformDataKeys.EDITOR.getData(dataContext) : null;
+    if (aClass == null) {
+      String message =
+        RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("is.not.supported.in.the.current.context", REFACTORING_NAME));
+      CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP);
+      return;
+    }
+
+
+    ArrayList<PsiClass> bases = RefactoringHierarchyUtil.createBasesList(aClass, false, true);
+
+    if (bases.isEmpty()) {
+      final GrTypeDefinition containingClass = DefaultGroovyMethods.asType(aClass.getContainingClass(), GrTypeDefinition.class);
+      if (containingClass != null) {
+        invokeImpl(project, dataContext, containingClass, aClass);
+        return;
+      }
+
+      String message = RefactoringBundle.getCannotRefactorMessage(
+        RefactoringBundle.message("class.does.not.have.base.classes.interfaces.in.current.project", aClass.getQualifiedName()));
+      CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP);
+      return;
+    }
+
+
+    mySubclass = aClass;
+    GrMemberInfoStorage memberInfoStorage = new GrMemberInfoStorage((GrTypeDefinition)mySubclass, new MemberInfoBase.Filter<GrMember>() {
+      public boolean includeMember(GrMember element) {
+        return true;
+      }
+    });
+    List<GrMemberInfo> members = memberInfoStorage.getClassMemberInfos(mySubclass);
+    PsiManager manager = mySubclass.getManager();
+
+    for (GrMemberInfo member : members) {
+      if (manager.areElementsEquivalent(member.getMember(), aMember)) {
+        member.setChecked(true);
+        break;
+      }
+    }
+
+
+    final GrPullUpDialog dialog = new GrPullUpDialog(project, aClass, bases, memberInfoStorage, this);
+    dialog.show();
+  }
+
+  public boolean checkConflicts(final GrPullUpDialog dialog) {
+    /*                         todo */
+    List<GrMemberInfo> _infos = dialog.getSelectedMemberInfos();
+    final GrMemberInfo[] infos = _infos.toArray(new GrMemberInfo[_infos.size()]);
+    final PsiClass superClass = dialog.getSuperClass();
+    if (!checkWritable(superClass, infos)) return false;
+    final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
+    if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
+      public void run() {
+        final PsiDirectory targetDirectory = superClass.getContainingFile().getContainingDirectory();
+        final PsiPackage targetPackage = targetDirectory != null ? JavaDirectoryService.getInstance().getPackage(targetDirectory) : null;
+        conflicts.putAllValues(PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, targetPackage, targetDirectory,
+                                                                  dialog.getContainmentVerifier()));
+      }
+    }, RefactoringBundle.message("detecting.possible.conflicts"), true, myProject)) {
+      return false;
+    }
+    if (!conflicts.isEmpty()) {
+      ConflictsDialog conflictsDialog = new ConflictsDialog(myProject, conflicts);
+      conflictsDialog.show();
+      final boolean ok = conflictsDialog.isOK();
+      if (!ok && conflictsDialog.isShowConflicts()) dialog.close(DialogWrapper.CANCEL_EXIT_CODE);
+      return ok;
+    }
+
+    return true;
+  }
+
+  private boolean checkWritable(PsiClass superClass, GrMemberInfo[] infos) {
+    if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, superClass)) return false;
+    for (GrMemberInfo info : infos) {
+      if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue;
+      if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, info.getMember())) return false;
+    }
+
+    return true;
+  }
+
+  public boolean isEnabledOnElements(PsiElement[] elements) {
+    return elements.length == 1 && elements[0] instanceof PsiClass;
+  }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java
new file mode 100644
index 0000000..028e613
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java
@@ -0,0 +1,730 @@
+/*
+ * 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.refactoring.memberPullUp;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.search.searches.OverridingMethodsSearch;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.MethodSignatureUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.refactoring.BaseRefactoringProcessor;
+import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.listeners.JavaRefactoringListenerManager;
+import com.intellij.refactoring.listeners.impl.JavaRefactoringListenerManagerImpl;
+import com.intellij.refactoring.util.DocCommentPolicy;
+import com.intellij.refactoring.util.RefactoringHierarchyUtil;
+import com.intellij.refactoring.util.RefactoringUIUtil;
+import com.intellij.refactoring.util.RefactoringUtil;
+import com.intellij.usageView.UsageInfo;
+import com.intellij.usageView.UsageViewDescriptor;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
+import org.codehaus.groovy.runtime.DefaultGroovyMethods;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
+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.GrExtendsClause;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrImplementsClause;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
+import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
+import org.jetbrains.plugins.groovy.refactoring.GroovyChangeContextUtil;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrClassMemberReferenceVisitor;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo;
+
+import java.util.*;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrPullUpHelper extends BaseRefactoringProcessor {
+  private static final Logger LOG = Logger.getInstance(GrPullUpHelper.class);
+  private static final Key<Boolean> SUPER_REF = Key.create("SUPER_REF");
+  private static final Key<Boolean> THIS_REF = Key.create("THIS_REF");
+  private static final Key<Boolean> PRESERVE_QUALIFIER = Key.create("PRESERVE_QUALIFIER");
+
+  private PsiClass mySourceClass;
+  private GrTypeDefinition myTargetSuperClass;
+  private GrMemberInfo[] myMembersToMove;
+  private DocCommentPolicy myDocCommentPolicy;
+  private Set<PsiMember> myMembersAfterMove;
+
+
+  public GrPullUpHelper(PsiClass aClass, PsiClass superClass, GrMemberInfo[] infos, DocCommentPolicy policy) {
+    super(aClass.getProject());
+
+    mySourceClass = aClass;
+    myTargetSuperClass = (GrTypeDefinition)superClass;
+    myMembersToMove = infos;
+    myDocCommentPolicy = policy;
+  }
+
+  @NotNull
+  @Override
+  protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
+    return new UsageViewDescriptor() {
+      public String getProcessedElementsHeader() {
+        return "Pull up members from";
+      }
+
+      @NotNull
+      public PsiElement[] getElements() {
+        return new PsiClass[]{mySourceClass};
+      }
+
+      public String getCodeReferencesText(int usagesCount, int filesCount) {
+        return "Class to pull up members to \"" + RefactoringUIUtil.getDescription(myTargetSuperClass, true) + "\"";
+      }
+
+      public String getCommentReferencesText(int usagesCount, int filesCount) {
+        return null;
+      }
+    };
+  }
+
+  @NotNull
+  @Override
+  protected UsageInfo[] findUsages() {
+    final List<UsageInfo> result = new ArrayList<UsageInfo>();
+    for (GrMemberInfo info : myMembersToMove) {
+      final PsiMember member = info.getMember();
+      if (member.hasModifierProperty(PsiModifier.STATIC)) {
+        for (PsiReference reference : ReferencesSearch.search(member)) {
+          result.add(new UsageInfo(reference));
+        }
+      }
+    }
+
+    return DefaultGroovyMethods.asType(result, UsageInfo[].class);
+  }
+
+  @Override
+  protected void performRefactoring(UsageInfo[] usages) {
+    moveMembersToBase();
+    //moveFieldInitializations(); todo
+    for (UsageInfo usage : usages) {
+      PsiElement element = usage.getElement();
+      if (element instanceof GrReferenceExpression) {
+        GrExpression qualifier = ((GrReferenceExpression)element).getQualifier();
+        if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).resolve().equals(mySourceClass)) {
+          ((GrReferenceExpression)qualifier).bindToElement(myTargetSuperClass);
+        }
+      }
+    }
+
+    /*
+    todo
+    ApplicationManager.application.invokeLater(new Runnable() {
+      @Override
+      public void run() {
+        processMethodsDuplicates();
+      }
+    }, ModalityState.NON_MODAL, myProject.getDisposed());*/
+
+  }
+
+  @Override
+  protected String getCommandName() {
+    return RefactoringBundle.message("pullUp.command", DescriptiveNameUtil.getDescriptiveName(mySourceClass));
+  }
+
+  public void moveMembersToBase() throws IncorrectOperationException {
+    final HashSet<PsiMember> movedMembers = ContainerUtil.newHashSet();
+    myMembersAfterMove = ContainerUtil.newHashSet();
+
+    // build aux sets
+    for (GrMemberInfo info : myMembersToMove) {
+      movedMembers.add(info.getMember());
+    }
+
+
+    // correct private member visibility
+    for (GrMemberInfo info : myMembersToMove) {
+      if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue;
+      setCorrectVisibility(movedMembers, info);
+      GroovyChangeContextUtil.encodeContextInfo(info.getMember());
+      info.getMember().accept(new QualifiedThisSuperSearcher());
+      fixReferencesToStatic(info.getMember(), movedMembers);
+    }
+
+
+
+
+    final PsiSubstitutor substitutor = upDownSuperClassSubstitutor();
+
+    // do actual move
+    for (GrMemberInfo info : myMembersToMove) {
+      if (info.getMember() instanceof PsiMethod) {
+        doMoveMethod(movedMembers, substitutor, info);
+      }
+      else if (info.getMember() instanceof GrField) {
+        doMoveField(movedMembers, substitutor, info);
+      }
+      else if (info.getMember() instanceof PsiClass) {
+        doMoveClass(movedMembers, substitutor, info);
+      }
+    }
+
+
+    ExplicitSuperDeleter explicitSuperDeleter = new ExplicitSuperDeleter();
+    for (PsiMember member : myMembersAfterMove) {
+      ((GrMember)member).accept(explicitSuperDeleter);
+    }
+    explicitSuperDeleter.fixSupers();
+
+    final QualifiedThisSuperAdjuster qualifiedThisSuperAdjuster = new QualifiedThisSuperAdjuster();
+    for (PsiMember member : myMembersAfterMove) {
+      ((GrMember)member).accept(qualifiedThisSuperAdjuster);
+    }
+
+    for (PsiMember member : myMembersAfterMove) {
+      GroovyChangeContextUtil.decodeContextInfo(member, null, null);
+    }
+
+
+    final JavaRefactoringListenerManagerImpl listenerManager = (JavaRefactoringListenerManagerImpl)JavaRefactoringListenerManager.getInstance(myProject);
+    for (final PsiMember movedMember : myMembersAfterMove) {
+      ((GroovyPsiElement)movedMember).accept(new GroovyRecursiveElementVisitor() {
+        @Override
+        public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
+          if (processRef(referenceExpression)) return;
+          super.visitReferenceExpression(referenceExpression);
+        }
+
+        @Override
+        public void visitCodeReferenceElement(GrCodeReferenceElement refElement) {
+          if (processRef(refElement)) return;
+          super.visitCodeReferenceElement(refElement);
+        }
+
+        private boolean processRef(@NotNull GrReferenceElement<? extends GroovyPsiElement> refElement) {
+          final PsiElement qualifier = refElement.getQualifier();
+          if (qualifier != null) {
+            final Boolean preserveQualifier = qualifier.getCopyableUserData(PRESERVE_QUALIFIER);
+            if (preserveQualifier != null && !preserveQualifier) {
+              refElement.setQualifier(null);
+              return true;
+            }
+          }
+          return false;
+        }
+      });
+      listenerManager.fireMemberMoved(mySourceClass, movedMember);
+    }
+  }
+
+  private PsiSubstitutor upDownSuperClassSubstitutor() {
+    PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
+    for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(mySourceClass)) {
+      substitutor = substitutor.put(parameter, null);
+    }
+
+    final Map<PsiTypeParameter, PsiType> substitutionMap =
+      TypeConversionUtil.getSuperClassSubstitutor(myTargetSuperClass, mySourceClass, PsiSubstitutor.EMPTY).getSubstitutionMap();
+    for (PsiTypeParameter parameter : substitutionMap.keySet()) {
+      final PsiType type = substitutionMap.get(parameter);
+      final PsiClass resolvedClass = PsiUtil.resolveClassInType(type);
+      if (resolvedClass instanceof PsiTypeParameter) {
+        substitutor = substitutor.put((PsiTypeParameter)resolvedClass, JavaPsiFacade.getElementFactory(myProject).createType(parameter));
+      }
+    }
+
+    return substitutor;
+  }
+
+  public void setCorrectVisibility(final HashSet<PsiMember> movedMembers, GrMemberInfo info) {
+    PsiModifierListOwner modifierListOwner = info.getMember();
+    if (myTargetSuperClass.isInterface()) {
+      PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true);
+    }
+    else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) {
+      if (info.isToAbstract() || willBeUsedInSubclass(modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) {
+        PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true);
+      }
+
+      if (modifierListOwner instanceof GrTypeDefinition) {
+        ((GrTypeDefinition)modifierListOwner).accept(new GroovyRecursiveElementVisitor() {
+          @Override
+          public void visitMethod(GrMethod method) {
+            check(method);
+          }
+
+          @Override
+          public void visitField(GrField field) {
+            check(field);
+          }
+
+          @Override
+          public void visitTypeDefinition(GrTypeDefinition typeDefinition) {
+            check(typeDefinition);
+            super.visitTypeDefinition(typeDefinition);
+          }
+
+          private void check(PsiMember member) {
+            if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
+              if (willBeUsedInSubclass(member, movedMembers, myTargetSuperClass, mySourceClass)) {
+                PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true);
+              }
+            }
+          }
+        });
+      }
+    }
+  }
+
+  private static boolean willBeUsedInSubclass(PsiElement member, Set<PsiMember> movedMembers, PsiClass superclass, PsiClass subclass) {
+    for (PsiReference ref : ReferencesSearch.search(member, new LocalSearchScope(subclass), false)) {
+      PsiElement element = ref.getElement();
+      if (!RefactoringHierarchyUtil.willBeInTargetClass(element, movedMembers, superclass, false)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  private void doMoveMethod(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, GrMemberInfo info) {
+    GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
+    GrMethod method = (GrMethod)info.getMember();
+    PsiMethod sibling = method;
+    PsiMethod anchor = null;
+    while (sibling != null) {
+      sibling = PsiTreeUtil.getNextSiblingOfType(sibling, PsiMethod.class);
+      if (sibling != null) {
+        anchor = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(method.getContainingClass(), myTargetSuperClass,
+                                                                                sibling.getSignature(PsiSubstitutor.EMPTY), false);
+        if (anchor != null) {
+          break;
+        }
+      }
+    }
+
+    GrMethod methodCopy = (GrMethod)method.copy();
+    if (method.findSuperMethods(myTargetSuperClass).length == 0) {
+      deleteOverrideAnnotationIfFound(methodCopy);
+    }
+
+    final boolean isOriginalMethodAbstract =
+      method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.DEFAULT);
+    if (myTargetSuperClass.isInterface() || info.isToAbstract()) {
+      GroovyChangeContextUtil.clearContextInfo(method);
+      RefactoringUtil.makeMethodAbstract(myTargetSuperClass, methodCopy);
+      if (myTargetSuperClass.isInterface()) {
+        PsiUtil.setModifierProperty(methodCopy, PsiModifier.ABSTRACT, false);
+      }
+      replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+
+      myDocCommentPolicy.processCopiedJavaDoc(methodCopy.getDocComment(), method.getDocComment(), isOriginalMethodAbstract);
+
+      final PsiMember movedElement =
+        anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
+      CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject());
+      if (styleSettings.INSERT_OVERRIDE_ANNOTATION) {
+        if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myTargetSuperClass.isInterface() ||
+            PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) {
+          new AddAnnotationFix(CommonClassNames.JAVA_LANG_OVERRIDE, method)
+            .invoke(method.getProject(), null, mySourceClass.getContainingFile());
+        }
+      }
+
+      if (!PsiUtil.isLanguageLevel6OrHigher(mySourceClass) && myTargetSuperClass.isInterface()) {
+        if (isOriginalMethodAbstract) {
+          for (PsiMethod oMethod : OverridingMethodsSearch.search(method)) {
+            deleteOverrideAnnotationIfFound(oMethod);
+          }
+        }
+
+        deleteOverrideAnnotationIfFound(method);
+      }
+
+      myMembersAfterMove.add(movedElement);
+      if (isOriginalMethodAbstract) {
+        method.delete();
+      }
+    }
+    else {
+      if (isOriginalMethodAbstract) {
+        PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true);
+      }
+
+      //fixReferencesToStatic(methodCopy, movedMembers);
+      replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+      final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false);
+      if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
+        superClassMethod.replace(methodCopy);
+      }
+      else {
+        final PsiMember movedElement =
+          anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
+        myMembersAfterMove.add(movedElement);
+      }
+
+      method.delete();
+    }
+  }
+
+  private static void deleteOverrideAnnotationIfFound(PsiMethod oMethod) {
+    final PsiAnnotation annotation = AnnotationUtil.findAnnotation(oMethod, CommonClassNames.JAVA_LANG_OVERRIDE);
+    if (annotation != null) {
+      PsiElement prev = annotation.getPrevSibling();
+      PsiElement next = annotation.getNextSibling();
+      if ((prev == null || org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(prev)) &&
+          org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(next)) {
+        next.delete();
+      }
+      annotation.delete();
+    }
+  }
+
+  public static void replaceMovedMemberTypeParameters(final PsiElement member,
+                                                      final Iterable<PsiTypeParameter> parametersIterable,
+                                                      final PsiSubstitutor substitutor,
+                                                      final GroovyPsiElementFactory factory) {
+    final Map<PsiElement, PsiElement> replacement = new LinkedHashMap<PsiElement, PsiElement>();
+    for (PsiTypeParameter parameter : parametersIterable) {
+      PsiType substitutedType = substitutor.substitute(parameter);
+      if (substitutedType == null) {
+        substitutedType = TypeConversionUtil.erasure(factory.createType(parameter));
+      }
+
+      PsiElement scopeElement = member instanceof GrField ? member.getParent() : member;
+      for (PsiReference reference : ReferencesSearch.search(parameter, new LocalSearchScope(scopeElement))) {
+        final PsiElement element = reference.getElement();
+        final PsiElement parent = element.getParent();
+        if (parent instanceof PsiTypeElement) {
+          replacement.put(parent, factory.createTypeElement(substitutedType));
+        }
+        else if (element instanceof GrCodeReferenceElement && substitutedType instanceof PsiClassType) {
+          replacement.put(element, factory.createReferenceElementByType((PsiClassType)substitutedType));
+        }
+      }
+    }
+
+    for (PsiElement element : replacement.keySet()) {
+      if (element.isValid()) {
+        element.replace(replacement.get(element));
+      }
+    }
+  }
+
+  private void fixReferencesToStatic(GroovyPsiElement classMember, Set<PsiMember> movedMembers) throws IncorrectOperationException {
+    final StaticReferencesCollector collector = new StaticReferencesCollector(movedMembers);
+    classMember.accept(collector);
+    ArrayList<GrReferenceElement> refs = collector.getReferences();
+    ArrayList<PsiElement> members = collector.getReferees();
+    ArrayList<PsiClass> classes = collector.getRefereeClasses();
+    GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
+
+    for (int i = 0; i < refs.size(); i++) {
+      GrReferenceElement ref = refs.get(i);
+      PsiElement namedElement = members.get(i);
+      PsiClass aClass = classes.get(i);
+
+      if (namedElement instanceof PsiNamedElement) {
+        GrReferenceExpression newRef = (GrReferenceExpression)factory.createExpressionFromText("a." + ((PsiNamedElement)namedElement).getName(), null);
+        GrExpression qualifier = newRef.getQualifierExpression();
+        assert qualifier != null;
+        qualifier = (GrExpression)qualifier.replace(factory.createReferenceExpressionFromText(aClass.getQualifiedName()));
+        qualifier.putCopyableUserData(PRESERVE_QUALIFIER, ref.isQualified());
+        PsiElement replaced = ref.replace(newRef);
+        JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(replaced);
+      }
+    }
+  }
+
+
+  private class StaticReferencesCollector extends GrClassMemberReferenceVisitor {
+    private final ArrayList<GrReferenceElement> myReferences = new ArrayList<GrReferenceElement>();
+    private final ArrayList<PsiElement> myReferees = new ArrayList<PsiElement>();
+    private final ArrayList<PsiClass> myRefereeClasses = new ArrayList<PsiClass>();
+    private final Set<PsiMember> myMovedMembers;
+
+    private StaticReferencesCollector(Set<PsiMember> movedMembers) {
+      super(mySourceClass);
+      myMovedMembers = movedMembers;
+    }
+
+    public ArrayList<PsiElement> getReferees() {
+      return myReferees;
+    }
+
+    public ArrayList<PsiClass> getRefereeClasses() {
+      return myRefereeClasses;
+    }
+
+    public ArrayList<GrReferenceElement> getReferences() {
+      return myReferences;
+    }
+
+    @Override
+    protected void visitClassMemberReferenceElement(GrMember classMember, GrReferenceElement classMemberReference) {
+      if (classMember.hasModifierProperty(PsiModifier.STATIC) /*&& classMemberReference.isQualified()*/) {
+        if (!myMovedMembers.contains(classMember) &&
+            RefactoringHierarchyUtil.isMemberBetween(myTargetSuperClass, mySourceClass, classMember)) {
+          myReferences.add(classMemberReference);
+          myReferees.add(classMember);
+          myRefereeClasses.add(classMember.getContainingClass());
+        }
+        else if (myMovedMembers.contains(classMember) || myMembersAfterMove.contains(classMember)) {
+          myReferences.add(classMemberReference);
+          myReferees.add(classMember);
+          myRefereeClasses.add(myTargetSuperClass);
+        }
+      }
+    }
+  }
+
+  private class ExplicitSuperDeleter extends GroovyRecursiveElementVisitor {
+    private final ArrayList<GrExpression> mySupersToDelete = ContainerUtil.newArrayList();
+    private final ArrayList<GrReferenceExpression> mySupersToChangeToThis = ContainerUtil.newArrayList();
+
+    @Override
+    public void visitReferenceExpression(GrReferenceExpression expression) {
+      super.visitReferenceExpression(expression);
+      if(org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression.getQualifierExpression())) {
+        PsiElement resolved = expression.resolve();
+        if (resolved == null || resolved instanceof PsiMethod && shouldFixSuper((PsiMethod) resolved)) {
+          mySupersToDelete.add(expression.getQualifierExpression());
+        }
+      }
+      else if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression)) {
+        mySupersToChangeToThis.add(expression);
+      }
+    }
+
+    @Override
+    public void visitTypeDefinition(GrTypeDefinition typeDefinition) {
+      //do nothing
+    }
+
+    private boolean shouldFixSuper(PsiMethod method) {
+      for (PsiMember element : myMembersAfterMove) {
+        if (element instanceof PsiMethod) {
+          PsiMethod member = (PsiMethod)element;
+          // if there is such member among moved members, super qualifier
+          // should not be removed
+          final PsiManager manager = method.getManager();
+          if (manager.areElementsEquivalent(member.getContainingClass(), method.getContainingClass()) &&
+              MethodSignatureUtil.areSignaturesEqual(member, method)) {
+            return false;
+          }
+        }
+      }
+
+      final PsiMethod methodFromSuper = myTargetSuperClass.findMethodBySignature(method, false);
+      return methodFromSuper == null;
+    }
+
+    public void fixSupers() throws IncorrectOperationException {
+      final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
+      GrReferenceExpression thisExpression = (GrReferenceExpression) factory.createExpressionFromText("this", null);
+      for (GrExpression expression : mySupersToDelete) {
+        expression.delete();
+      }
+
+      for (GrReferenceExpression superExpression : mySupersToChangeToThis) {
+        superExpression.replace(thisExpression);
+      }
+    }
+  }
+
+  private class QualifiedThisSuperAdjuster extends GroovyRecursiveElementVisitor {
+    @Override
+    public void visitReferenceExpression(GrReferenceExpression expression) {
+      super.visitReferenceExpression(expression);
+      if (expression.getCopyableUserData(SUPER_REF) != null) {
+        expression.putCopyableUserData(SUPER_REF, null);
+        final GrExpression qualifier = expression.getQualifier();
+        if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(mySourceClass)) {
+          try {
+            GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
+            GrExpression newExpr = factory.createExpressionFromText(myTargetSuperClass.getName() + ".this", null);
+            expression.replace(newExpr);
+          }
+          catch (IncorrectOperationException e) {
+            LOG.error(e);
+          }
+        }
+      }
+      else if (expression.getCopyableUserData(THIS_REF) != null) {
+        expression.putCopyableUserData(THIS_REF, null);
+        final GrExpression qualifier = expression.getQualifier();
+        if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(mySourceClass)) {
+          try {
+            ((GrReferenceExpression)qualifier).bindToElement(myTargetSuperClass);
+            GroovyChangeContextUtil.clearContextInfo(qualifier);
+          }
+          catch (IncorrectOperationException e) {
+            LOG.error(e);
+          }
+        }
+      }
+    }
+  }
+
+  private void doMoveField(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, GrMemberInfo info) {
+    GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
+    GrField field = (GrField)info.getMember();
+    field.normalizeDeclaration();
+    replaceMovedMemberTypeParameters(field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+    //fixReferencesToStatic(field, movedMembers);
+    if (myTargetSuperClass.isInterface()) {
+      PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true);
+    }
+    final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(field);
+    myMembersAfterMove.add(movedElement);
+    field.delete();
+  }
+
+  private void doMoveClass(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, GrMemberInfo info) {
+    GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
+    GrTypeDefinition aClass = (GrTypeDefinition)info.getMember();
+    if (Boolean.FALSE.equals(info.getOverrides())) {
+      final GrReferenceList sourceReferenceList = info.getSourceReferenceList();
+      LOG.assertTrue(sourceReferenceList != null);
+      GrCodeReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ?
+                                   removeFromReferenceList(sourceReferenceList, aClass) :
+                                   findReferenceToClass(sourceReferenceList, aClass);
+      if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) {
+        replaceMovedMemberTypeParameters(ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+        GrReferenceList referenceList;
+        if (myTargetSuperClass.isInterface()) {
+          referenceList = myTargetSuperClass.getExtendsClause();
+          if (referenceList == null) {
+            GrExtendsClause newClause = GroovyPsiElementFactory.getInstance(myProject).createExtendsClause();
+            PsiElement anchor = myTargetSuperClass.getTypeParameterList() != null ? myTargetSuperClass.getTypeParameterList():
+                                myTargetSuperClass.getNameIdentifierGroovy();
+            referenceList = (GrReferenceList)myTargetSuperClass.addAfter(newClause, anchor);
+            addSpacesAround(referenceList);
+          }
+        }
+        else {
+          referenceList = myTargetSuperClass.getImplementsClause();
+
+          if (referenceList == null) {
+            GrImplementsClause newClause = GroovyPsiElementFactory.getInstance(myProject).createImplementsClause();
+            PsiElement anchor = myTargetSuperClass.getExtendsClause() != null ? myTargetSuperClass.getExtendsClause() :
+                                myTargetSuperClass.getTypeParameterList() != null ? myTargetSuperClass.getTypeParameterList() :
+                                myTargetSuperClass.getNameIdentifierGroovy();
+            referenceList = (GrReferenceList)myTargetSuperClass.addAfter(newClause, anchor);
+            addSpacesAround(referenceList);
+          }
+
+        }
+
+        assert referenceList != null;
+        referenceList.add(ref);
+      }
+    }
+    else {
+      replaceMovedMemberTypeParameters(aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+      //fixReferencesToStatic(aClass, movedMembers);
+      PsiMember movedElement = (PsiMember)myTargetSuperClass.addAfter(aClass, null);
+      //movedElement = (PsiMember)CodeStyleManager.getInstance(myProject).reformat(movedElement);
+      myMembersAfterMove.add(movedElement);
+      aClass.delete();
+    }
+  }
+
+  private static void addSpacesAround(@NotNull GrReferenceList list) {
+    PsiElement prev = list.getPrevSibling();
+    if (!PsiImplUtil.isWhiteSpace(prev)) {
+      list.getParent().getNode().addLeaf(TokenType.WHITE_SPACE, " ", list.getNode());
+    }
+
+    PsiElement next = list.getNextSibling();
+    if (!PsiImplUtil.isWhiteSpace(next)) {
+      list.getParent().getNode().addLeaf(TokenType.WHITE_SPACE, " ", list.getNode().getTreeNext());
+    }
+  }
+
+  public static GrCodeReferenceElement findReferenceToClass(GrReferenceList refList, PsiClass aClass) {
+    GrCodeReferenceElement[] refs = refList.getReferenceElements();
+    for (GrCodeReferenceElement ref : refs) {
+      if (ref.isReferenceTo(aClass)) {
+        return ref;
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * removes a reference to the specified class from the reference list given
+   *
+   * @return if removed  - a reference to the class or null if there were no references to this class in the reference list
+   */
+  public static GrCodeReferenceElement removeFromReferenceList(GrReferenceList refList, PsiClass aClass) throws IncorrectOperationException {
+    GrCodeReferenceElement[] refs = refList.getReferenceElements();
+    for (GrCodeReferenceElement ref : refs) {
+      if (ref.isReferenceTo(aClass)) {
+        GrCodeReferenceElement refCopy = (GrCodeReferenceElement)ref.copy();
+        ref.delete();
+        return refCopy;
+      }
+    }
+    return null;
+  }
+
+  private class QualifiedThisSuperSearcher extends GroovyRecursiveElementVisitor {
+    @Override
+    public void visitReferenceExpression(GrReferenceExpression expression) {
+      super.visitReferenceExpression(expression);
+      if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression)) {
+        final GrExpression qualifier = expression.getQualifier();
+        if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(mySourceClass)) {
+          try {
+            expression.putCopyableUserData(SUPER_REF, Boolean.TRUE);
+          }
+          catch (IncorrectOperationException e) {
+            LOG.error(e);
+          }
+        }
+      }
+      else if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isThisReference(expression)) {
+        final GrExpression qualifier = expression.getQualifier();
+        if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(mySourceClass)) {
+          try {
+            expression.putCopyableUserData(THIS_REF, Boolean.TRUE);
+          }
+          catch (IncorrectOperationException e) {
+            LOG.error(e);
+          }
+        }
+      }
+
+    }
+  }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
index acac929..5b989fa 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
@@ -105,6 +105,11 @@
     return inClass;
   }
 
+  @Override
+  public char getMnemonic() {
+    return 'G';
+  }
+
   @NotNull
   @Override
   public String getName() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/GroovyIndexPatternBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/GroovyIndexPatternBuilder.java
index 06e1513..d03fd8a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/GroovyIndexPatternBuilder.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/GroovyIndexPatternBuilder.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.
@@ -20,6 +20,7 @@
 import com.intellij.psi.impl.search.IndexPatternBuilder;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.plugins.groovy.lang.lexer.GroovyLexer;
 import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
 import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
@@ -30,14 +31,14 @@
  * Date: 16.07.2008
  */
 public class GroovyIndexPatternBuilder implements IndexPatternBuilder {
-    public Lexer getIndexingLexer(PsiFile file) {
+    public Lexer getIndexingLexer(@NotNull PsiFile file) {
         if (file instanceof GroovyFile) {
             return new GroovyLexer();
         }
         return null;
     }
 
-    public TokenSet getCommentTokenSet(PsiFile file) {
+    public TokenSet getCommentTokenSet(@NotNull PsiFile file) {
       return TokenSets.ALL_COMMENT_TOKENS;
     }
 
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy
index 06dd772..316de96 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy
@@ -1,29 +1,28 @@
 /*
- * 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.
- *  You may obtain a copy of the License at
+ * 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
+ * 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.
+ * 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.compiler
 
 import com.intellij.compiler.CompilerConfiguration
-import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.CompilerConfigurationImpl
 import com.intellij.compiler.server.BuildManager
 import com.intellij.openapi.util.io.FileUtil
 import com.intellij.openapi.vfs.VfsUtil
 import com.intellij.testFramework.PsiTestUtil
 import org.jetbrains.plugins.groovy.util.TestUtils
-
 /**
  * @author peter
  */
@@ -46,35 +45,6 @@
     super.tearDown()
   }
 
-  public void testTraitStubs() throws Throwable {
-    myFixture.addFileToProject("A.groovy", """
-@Trait
-abstract class SomeTrait {
-  abstract def some()
-  def concrete() {}
-}
-
-@Trait
-abstract class AnotherTrait extends SomeTrait {
-  abstract def another()
-}
-
-class Goo implements SomeTrait {
-  def some() {}
-}
-class Bar implements AnotherTrait {
-  def some() {}
-  def another() {}
-}
-""");
-    myFixture.addClass("""
-class Foo implements SomeTrait {
-  public Object some() { return null; }
-  public Object concrete() { return null; }
-}""")
-    assertEmpty(make());
-  }
-
   public void testRecompileDependentGroovyClasses() throws Exception {
     def a = myFixture.addFileToProject("A.gpp", """
 class A {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy
index 92331f6..e18c4ee 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy
@@ -1600,4 +1600,52 @@
 
 """)
   }
+
+  void testAnnotationAsAnnotationValue() {
+    testHighlighting('''\
+@interface A {}
+@interface B {
+  A[] foo()
+}
+@interface C {
+  A foo()
+}
+
+@B(foo = @A)
+@B(foo = [@A])
+@C(foo = @A)
+@C(foo = <error descr="Cannot assign 'Integer' to 'A'">2</error>)
+def foo
+''')
+  }
+
+  void testSameNameMethodWithDifferentAccessModifiers() {
+    testHighlighting('''
+
+class A {
+  def foo(){}
+  def foo(int x) {}
+}
+
+class B {
+  <error descr="Mixing private and public/protected methods of the same name">private def foo()</error>{}
+  <error descr="Mixing private and public/protected methods of the same name">public def foo(int x)</error> {}
+}
+
+class C {
+  private foo(){}
+  private foo(int x) {}
+}
+
+class D {
+  <error>private foo()</error>{}
+  <error>protected foo(int x)</error> {}
+}
+
+class E {
+  <error>private foo()</error>{}
+  <error>def foo(int x)</error> {}
+}
+''')
+  }
 }
\ No newline at end of file
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.groovy
index f78896c..1536309 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.groovy
@@ -239,7 +239,7 @@
       doTest(new SimpleInfo('optional', -1, null, '1', 'int'));
     }
     catch (ConflictsInTestsException e) {
-      assertEquals('Method foo(int) is already defined in the class <b><code>Test</code></b>.', e.message)
+      assertEquals('Method foo(int) is already defined in the class <b><code>Test</code></b>', e.message)
       return
     }
     assertFalse('conflicts are not detected!', true);
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy
index 4fdb080..6c7f1b5 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy
@@ -238,7 +238,7 @@
   }
 
   public void testSuperInExpression() {
-    doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
+    doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
   }
 
   public void testWeirdQualifierAndParameter() {
@@ -262,7 +262,7 @@
   }*/
 
   public void testSuperWithSideEffect() {
-    doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
+    doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
   }
 
   public void testConflictingField() {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/IntroduceParameterTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/IntroduceParameterTest.groovy
index 970eed4..fe8cfe0 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/IntroduceParameterTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/IntroduceParameterTest.groovy
@@ -1,17 +1,17 @@
 /*
- * 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.
- *  You may obtain a copy of the License at
+ * 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
+ * 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.
+ * 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.refactoring.introduceParameter
@@ -184,7 +184,7 @@
   }
 
   public void testSuperInExpression() {
-    doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
+    doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
   }
 
   public void testWeirdQualifierAndParameter() {
@@ -208,7 +208,7 @@
   }*/
 
   public void testSuperWithSideEffect() {
-    doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
+    doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
   }
 
   public void testConflictingField() {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy
new file mode 100644
index 0000000..e3d95a7
--- /dev/null
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy
@@ -0,0 +1,243 @@
+/*
+ * 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.refactoring.memberPullUp
+
+import com.intellij.psi.*
+import com.intellij.psi.util.PsiTreeUtil
+import com.intellij.refactoring.listeners.JavaRefactoringListenerManager
+import com.intellij.refactoring.listeners.MoveMemberListener
+import com.intellij.refactoring.util.DocCommentPolicy
+import com.intellij.util.ui.UIUtil
+import junit.framework.Assert
+import org.jetbrains.plugins.groovy.LightGroovyTestCase
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo
+import org.jetbrains.plugins.groovy.util.TestUtils
+/**
+ * Created by Max Medvedev on 8/17/13
+ */
+class GrPullUpTest extends LightGroovyTestCase {
+  @Override
+  protected String getBasePath() {
+    TestUtils.testDataPath + 'refactoring/pullUp'
+  }
+
+  public void testQualifiedThis() {
+    doTest(new MemberDescriptor("Inner", PsiClass));
+  }
+
+  public void testQualifiedSuper() {
+    doTest(new MemberDescriptor("Inner", PsiClass));
+  }
+
+  public void testQualifiedReference() {     // IDEADEV-25008
+    doTest(new MemberDescriptor("x", PsiField),
+           new MemberDescriptor("getX", PsiMethod),
+           new MemberDescriptor("setX", PsiMethod));
+  }
+
+  public void testPullUpInheritedStaticClasses() {
+    doTest(new MemberDescriptor("C", PsiClass),
+           new MemberDescriptor("D", PsiClass));
+  }
+
+  public void testPullUpPrivateInnerClassWithPrivateConstructor() {
+    doTest(new MemberDescriptor("C", PsiClass));
+  }
+
+  public void testPullUpAndMakeAbstract() {
+    doTest(new MemberDescriptor("a", PsiMethod),
+           new MemberDescriptor("b", PsiMethod, true));
+  }
+
+  public void _testTryCatchFieldInitializer() {
+    doTest(new MemberDescriptor("field", PsiField));
+  }
+
+  public void testIfFieldInitializationWithNonMovedField() {
+    doTest(new MemberDescriptor("f", PsiField));
+  }
+
+  public void _testIfFieldMovedInitialization() {
+    doTest(new MemberDescriptor("f", PsiField));
+  }
+
+  public void _testMultipleConstructorsFieldInitialization() {
+    doTest(new MemberDescriptor("f", PsiField));
+  }
+
+  public void _testMultipleConstructorsFieldInitializationNoGood() {
+    doTest(new MemberDescriptor("f", PsiField));
+  }
+
+  public void _testRemoveOverride() {
+    doTest(new MemberDescriptor("get", PsiMethod));
+  }
+
+  public void testTypeParamErasure() {
+    doTest(new MemberDescriptor("f", PsiField));
+  }
+
+  public void testTypeParamSubst() {
+    doTest(new MemberDescriptor("f", PsiField));
+  }
+
+  public void testTypeArgument() {
+    doTest(new MemberDescriptor("f", PsiField));
+  }
+
+  public void testGenericsInAbstractMethod() {
+    doTest(new MemberDescriptor("method", PsiMethod, true));
+  }
+
+  public void _testReplaceDuplicatesInInheritors() {
+    doTest(new MemberDescriptor("foo", PsiMethod, false));
+  }
+
+  public void testGenericsInImplements() {
+    doTest(false, new MemberDescriptor("I", PsiClass));
+  }
+
+  public void testUpdateStaticRefs() {
+    doTest(false, new MemberDescriptor("foo", PsiMethod));
+  }
+
+  public void testRemoveOverrideFromPulledMethod() {
+    doTest(false, new MemberDescriptor("foo", PsiMethod));
+  }
+
+  public void testPreserveOverrideInPulledMethod() {
+    doTest(false, new MemberDescriptor("foo", PsiMethod));
+  }
+
+  public void testMergeInterfaces() {
+    doTest(false, new MemberDescriptor("I", PsiClass));
+  }
+
+  public void testTypeParamsConflictingNames() {
+    doTest(false, new MemberDescriptor("foo", PsiMethod));
+  }
+
+  public void testEscalateVisibility() {
+    doTest(false, new MemberDescriptor("foo", PsiMethod));
+  }
+
+  public void _testExtensionMethod() {
+    doTest(false, new MemberDescriptor("foo", PsiMethod));
+  }
+
+  public void testPreserveOverride() {
+    doTest(false, new MemberDescriptor("foo", PsiMethod));
+  }
+
+  private void doTest(MemberDescriptor... membersToFind) {
+    doTest(true, membersToFind);
+  }
+
+  private void doTest(final boolean checkMembersMovedCount, MemberDescriptor... membersToFind) {
+    myFixture.configureByFile(getTestName(false) + ".groovy");
+    PsiElement elementAt = myFixture.getFile().findElementAt(myFixture.getEditor().getCaretModel().getOffset());
+    final PsiClass sourceClass = PsiTreeUtil.getParentOfType(elementAt, PsiClass);
+    assertNotNull(sourceClass);
+
+    PsiClass targetClass = sourceClass.getSuperClass();
+    assertNotNull(targetClass);
+    if (!targetClass.isWritable()) {
+      final PsiClass[] interfaces = sourceClass.getInterfaces();
+      assertEquals(2, interfaces.length);
+      assertTrue(interfaces[0].isWritable());
+      targetClass = interfaces[0];
+    }
+    GrMemberInfo[] infos = findMembers(sourceClass, membersToFind);
+
+    final int[] countMoved = [0];
+    final MoveMemberListener listener = new MoveMemberListener() {
+      @Override
+      public void memberMoved(PsiClass aClass, PsiMember member) {
+        assertEquals(sourceClass, aClass);
+        countMoved[0]++;
+      }
+    };
+    JavaRefactoringListenerManager.getInstance(getProject()).addMoveMembersListener(listener);
+    final GrPullUpHelper helper = new GrPullUpHelper(sourceClass, targetClass, infos, new DocCommentPolicy(DocCommentPolicy.ASIS));
+    helper.run();
+    UIUtil.dispatchAllInvocationEvents();
+    JavaRefactoringListenerManager.getInstance(getProject()).removeMoveMembersListener(listener);
+    if (checkMembersMovedCount) {
+      assertEquals(countMoved[0], membersToFind.length);
+    }
+    myFixture.checkResultByFile(getTestName(false) + "_after.groovy");
+  }
+
+  public static class MemberDescriptor {
+    private String myName;
+    private Class<? extends PsiMember> myClass;
+    private boolean myAbstract;
+
+    public MemberDescriptor(String name, Class<? extends PsiMember> aClass, boolean isAbstract) {
+      myName = name;
+      myClass = aClass;
+      myAbstract = isAbstract;
+    }
+
+
+    public MemberDescriptor(String name, Class<? extends PsiMember> aClass) {
+      this(name, aClass, false);
+    }
+  }
+
+  public static GrMemberInfo[] findMembers(final PsiClass sourceClass, final MemberDescriptor... membersToFind) {
+    GrMemberInfo[] infos = new GrMemberInfo[membersToFind.length]
+    for (int i = 0; i < membersToFind.length; i++) {
+      final Class<? extends PsiMember> clazz = membersToFind[i].myClass
+      final String name = membersToFind[i].myName
+      PsiMember member = null
+      boolean overrides = false
+      GrReferenceList refList = null
+      if (PsiClass.isAssignableFrom(clazz)) {
+        member = sourceClass.findInnerClassByName(name, false)
+        if (member == null) {
+          final PsiClass[] supers = sourceClass.getSupers()
+          for (PsiClass superTypeClass : supers) {
+            if (superTypeClass.getName().equals(name)) {
+              member = superTypeClass
+              overrides = true
+              refList = superTypeClass.isInterface() ?
+                        (sourceClass as GrTypeDefinition).getImplementsClause() :
+                        (sourceClass as GrTypeDefinition).getExtendsClause()
+              break
+            }
+          }
+        }
+
+      } else if (PsiMethod.class.isAssignableFrom(clazz)) {
+        final PsiMethod[] methods = sourceClass.findMethodsByName(name, false)
+        Assert.assertEquals(1, methods.length)
+        member = methods[0]
+      } else if (PsiField.class.isAssignableFrom(clazz)) {
+        member = sourceClass.findFieldByName(name, false)
+      }
+
+      assertNotNull(member)
+      assertInstanceOf(member, GrMember)
+      infos[i] = new GrMemberInfo(member as GrMember, overrides, refList)
+      infos[i].setToAbstract(membersToFind[i].myAbstract)
+    }
+    return infos
+  }
+}
diff --git a/plugins/groovy/testdata/groovy/stubGenerator/delegateAnno.test b/plugins/groovy/testdata/groovy/stubGenerator/delegateAnno.test
index 2f202cd..ee1acc0 100644
--- a/plugins/groovy/testdata/groovy/stubGenerator/delegateAnno.test
+++ b/plugins/groovy/testdata/groovy/stubGenerator/delegateAnno.test
@@ -15,7 +15,7 @@
 }
 -----
 public interface DelegateFoo {
-public java.lang.Object foo() ;
+public abstract java.lang.Object foo() ;
 
 }
 ---
diff --git a/plugins/groovy/testdata/groovy/stubGenerator/delegationGenerics.test b/plugins/groovy/testdata/groovy/stubGenerator/delegationGenerics.test
index 1d44095..342580f 100644
--- a/plugins/groovy/testdata/groovy/stubGenerator/delegationGenerics.test
+++ b/plugins/groovy/testdata/groovy/stubGenerator/delegationGenerics.test
@@ -7,7 +7,7 @@
 }
 -----
 public interface DelegationGenerics<K, V> {
-public V get(K k) ;
+public abstract V get(K k) ;
 
 }
 ---
diff --git a/plugins/groovy/testdata/groovy/stubGenerator/methodWithItsOwnTypeParams.test b/plugins/groovy/testdata/groovy/stubGenerator/methodWithItsOwnTypeParams.test
index 98b17da..4621b10 100644
--- a/plugins/groovy/testdata/groovy/stubGenerator/methodWithItsOwnTypeParams.test
+++ b/plugins/groovy/testdata/groovy/stubGenerator/methodWithItsOwnTypeParams.test
@@ -7,7 +7,7 @@
 }
 -----
 public interface I<S> {
-public <T> void foo(java.util.List<T> a) ;
+public abstract <T> void foo(java.util.List<T> a) ;
 
 }
 ---
diff --git a/plugins/groovy/testdata/groovy/stubGenerator/rawReturnTypeInImplementation.test b/plugins/groovy/testdata/groovy/stubGenerator/rawReturnTypeInImplementation.test
index 07de458..53b639f 100644
--- a/plugins/groovy/testdata/groovy/stubGenerator/rawReturnTypeInImplementation.test
+++ b/plugins/groovy/testdata/groovy/stubGenerator/rawReturnTypeInImplementation.test
@@ -8,7 +8,7 @@
 
 -----
 public interface Callable<V> {
-public V call() throws java.lang.Exception ;
+public abstract V call() throws java.lang.Exception ;
 
 }
 ---
diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno.java
index b6732ac..6dd2d67 100644
--- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno.java
+++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno.java
@@ -1,6 +1,6 @@
 public @interface Inter {
-public java.lang.String foo() ;
-public int de() default 4;
-public java.lang.String[] bar() default "1, 2, 3";
-public java.lang.String[] strings() ;
+public abstract java.lang.String foo() ;
+public abstract int de() default 4;
+public abstract java.lang.String[] bar() default "1, 2, 3";
+public abstract java.lang.String[] strings() ;
 }
diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno1.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno1.java
index a6f9da97..12dfa62 100644
--- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno1.java
+++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno1.java
@@ -2,10 +2,10 @@
 A,B;
 }
 public @interface Inter {
-public I[] bar() default {@I(2), @I(a = 5)};
-public java.lang.String[] strings() default {"a"};
-public E foo() default E.A;
+public abstract I[] bar() default {@I(2), @I(a = 5)};
+public abstract java.lang.String[] strings() default {"a"};
+public abstract E foo() default E.A;
 }
 public @interface I {
-public int a() default 4;
+public abstract int a() default 4;
 }
diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/useAnno.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/useAnno.java
index 6e32f6b..4905f4a 100644
--- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/useAnno.java
+++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/useAnno.java
@@ -1,7 +1,7 @@
 @p.I package p;
 
 public @interface I {
-public int x() ;
+public abstract int x() ;
 }
 @p.I public class A {
 @p.I public A() {}
diff --git a/plugins/groovy/testdata/refactoring/move/moveClassToInner/moveMultiple1/after/pack2/A.groovy b/plugins/groovy/testdata/refactoring/move/moveClassToInner/moveMultiple1/after/pack2/A.groovy
index 4a3031b..307452b 100644
--- a/plugins/groovy/testdata/refactoring/move/moveClassToInner/moveMultiple1/after/pack2/A.groovy
+++ b/plugins/groovy/testdata/refactoring/move/moveClassToInner/moveMultiple1/after/pack2/A.groovy
@@ -5,6 +5,7 @@
       Class2 a;
       Class2 b;
     }
+
     public static class Class2 {
     }
 }
diff --git a/plugins/groovy/testdata/refactoring/pullUp/EscalateVisibility.groovy b/plugins/groovy/testdata/refactoring/pullUp/EscalateVisibility.groovy
new file mode 100644
index 0000000..6f50634
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/EscalateVisibility.groovy
@@ -0,0 +1,10 @@
+class Foo {
+  
+}
+
+class FooImpl extends Foo {
+  private void fo<caret>o(){}
+  void bar() {
+    foo();
+  }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/EscalateVisibility_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/EscalateVisibility_after.groovy
new file mode 100644
index 0000000..725e5c5
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/EscalateVisibility_after.groovy
@@ -0,0 +1,10 @@
+class Foo {
+
+    protected void foo(){}
+}
+
+class FooImpl extends Foo {
+    void bar() {
+    foo();
+  }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/ExtensionMethod.groovy b/plugins/groovy/testdata/refactoring/pullUp/ExtensionMethod.groovy
new file mode 100644
index 0000000..4a59e1e
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/ExtensionMethod.groovy
@@ -0,0 +1,8 @@
+interface Base {
+}
+
+interface I2 extends Base {
+    default void foo<caret>() {
+        System.out.println("Hi there.");
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/ExtensionMethod_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/ExtensionMethod_after.groovy
new file mode 100644
index 0000000..469ee86
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/ExtensionMethod_after.groovy
@@ -0,0 +1,8 @@
+interface Base {
+    default void foo() {
+        System.out.println("Hi there.");
+    }
+}
+
+interface I2 extends Base {
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/GenericsInAbstractMethod.groovy b/plugins/groovy/testdata/refactoring/pullUp/GenericsInAbstractMethod.groovy
new file mode 100644
index 0000000..bd2f499
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/GenericsInAbstractMethod.groovy
@@ -0,0 +1,5 @@
+public abstract class Parent<S> {}
+
+class Child<T> extends Parent<T> {
+   void <caret>method(T t){}
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/GenericsInAbstractMethod_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/GenericsInAbstractMethod_after.groovy
new file mode 100644
index 0000000..353201f
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/GenericsInAbstractMethod_after.groovy
@@ -0,0 +1,8 @@
+public abstract class Parent<S> {
+    abstract void method(S t)
+}
+
+class Child<T> extends Parent<T> {
+   @Override
+   void method(T t){}
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/GenericsInImplements.groovy b/plugins/groovy/testdata/refactoring/pullUp/GenericsInImplements.groovy
new file mode 100644
index 0000000..07e1f89a
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/GenericsInImplements.groovy
@@ -0,0 +1,10 @@
+public class Parent<S> {}
+
+interface I<IT> {
+  void method(IT t);
+}
+
+class Child<T> extends Parent<T> implements I<T>{
+  <caret>
+  public void method(T t){}
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/GenericsInImplements_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/GenericsInImplements_after.groovy
new file mode 100644
index 0000000..3aca9f8
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/GenericsInImplements_after.groovy
@@ -0,0 +1,10 @@
+public class Parent<S> implements I<S> {}
+
+interface I<IT> {
+  void method(IT t);
+}
+
+class Child<T> extends Parent<T> {
+  
+  public void method(T t){}
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/IfFieldInitializationWithNonMovedField.groovy b/plugins/groovy/testdata/refactoring/pullUp/IfFieldInitializationWithNonMovedField.groovy
new file mode 100644
index 0000000..ba3609d
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/IfFieldInitializationWithNonMovedField.groovy
@@ -0,0 +1,18 @@
+public class A {
+}
+
+class B extends A {
+    final String <caret>f;
+    final String foo;
+
+    B(String fi, String foo) {
+        this.foo = foo;
+        if (fi == this.foo) {
+            f = foo;
+        } else {
+            f = "";
+        }
+    }
+
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/IfFieldInitializationWithNonMovedField_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/IfFieldInitializationWithNonMovedField_after.groovy
new file mode 100644
index 0000000..8d52600
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/IfFieldInitializationWithNonMovedField_after.groovy
@@ -0,0 +1,18 @@
+public class A {
+    protected final String f
+}
+
+class B extends A {
+    final String foo;
+
+    B(String fi, String foo) {
+        this.foo = foo;
+        if (fi == this.foo) {
+            f = foo;
+        } else {
+            f = "";
+        }
+    }
+
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/IfFieldMovedInitialization.groovy b/plugins/groovy/testdata/refactoring/pullUp/IfFieldMovedInitialization.groovy
new file mode 100644
index 0000000..f541f0e
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/IfFieldMovedInitialization.groovy
@@ -0,0 +1,18 @@
+public class A {
+}
+
+class B extends A {
+    final String <caret>f;
+    final String foo;
+
+    B(String fi, String foo) {
+        this.foo = foo;
+        if (fi == foo) {
+            f = foo;
+        } else {
+            f = "";
+        }
+    }
+
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/IfFieldMovedInitialization_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/IfFieldMovedInitialization_after.groovy
new file mode 100644
index 0000000..4000fdc
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/IfFieldMovedInitialization_after.groovy
@@ -0,0 +1,22 @@
+public class A {
+    final String f;
+
+    public A(String fi, String foo) {
+        if (fi == foo) {
+            f = foo;
+        } else {
+            f = "";
+        }
+    }
+}
+
+class B extends A {
+    final String foo;
+
+    B(String fi, String foo) {
+        super(fi, foo);
+        this.foo = foo;
+    }
+
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/MergeInterfaces.groovy b/plugins/groovy/testdata/refactoring/pullUp/MergeInterfaces.groovy
new file mode 100644
index 0000000..5376e86
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/MergeInterfaces.groovy
@@ -0,0 +1,3 @@
+class Base implements I<String> {}
+class Te<caret>st extends Base implements I<String> {}
+interface I<T>{}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/MergeInterfaces_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/MergeInterfaces_after.groovy
new file mode 100644
index 0000000..ea7fffc
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/MergeInterfaces_after.groovy
@@ -0,0 +1,3 @@
+class Base implements I<String> {}
+class Test extends Base {}
+interface I<T>{}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitialization.groovy b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitialization.groovy
new file mode 100644
index 0000000..f884f48
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitialization.groovy
@@ -0,0 +1,17 @@
+public class A {
+}
+
+class B extends A {
+    final String <caret>f;
+    final String foo;
+
+    B(String fi, String foo) {
+        this.foo = foo;
+        f = "";
+    }
+
+    B(String foo) {
+        this.foo = foo;
+        f = "";
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitializationNoGood.groovy b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitializationNoGood.groovy
new file mode 100644
index 0000000..25117fc
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitializationNoGood.groovy
@@ -0,0 +1,21 @@
+public class A {
+}
+
+class B extends A {
+    final String <caret>f;
+    final String foo;
+
+    B(String fi, String foo) {
+        this.foo = foo;
+        if (fi == this.foo) {
+            f = foo;
+        } else {
+            f = "";
+        }
+    }
+
+    B(String f) {
+        this.f = f;
+        foo = "";
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitializationNoGood_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitializationNoGood_after.groovy
new file mode 100644
index 0000000..b66ba0b
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitializationNoGood_after.groovy
@@ -0,0 +1,21 @@
+public class A {
+    final String f;
+}
+
+class B extends A {
+    final String foo;
+
+    B(String fi, String foo) {
+        this.foo = foo;
+        if (fi == this.foo) {
+            f = foo;
+        } else {
+            f = "";
+        }
+    }
+
+    B(String f) {
+        this.f = f;
+        foo = "";
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitialization_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitialization_after.groovy
new file mode 100644
index 0000000..7c19de1
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitialization_after.groovy
@@ -0,0 +1,21 @@
+public class A {
+    final String f;
+
+    public A() {
+        f = "";
+    }
+}
+
+class B extends A {
+    final String foo;
+
+    B(String fi, String foo) {
+        super();
+        this.foo = foo;
+    }
+
+    B(String foo) {
+        super();
+        this.foo = foo;
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PreserveOverride.groovy b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverride.groovy
new file mode 100644
index 0000000..84f2f18
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverride.groovy
@@ -0,0 +1,12 @@
+abstract class Bazz {
+    public abstract void foo();
+}
+
+abstract class Foo extends Bazz {}
+
+class Bar extends Foo {
+    @Override
+    public void f<caret>oo() {
+    }
+}
+
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PreserveOverrideInPulledMethod.groovy b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverrideInPulledMethod.groovy
new file mode 100644
index 0000000..61e9da2
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverrideInPulledMethod.groovy
@@ -0,0 +1,12 @@
+public class Test {
+    abstract class Base extends IntImpl {
+        @Override
+        public abstract String<caret> foo();
+    }
+
+    class IntImpl extends Int {}
+
+    class Int {
+        public abstract String foo();
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PreserveOverrideInPulledMethod_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverrideInPulledMethod_after.groovy
new file mode 100644
index 0000000..206a5b4
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverrideInPulledMethod_after.groovy
@@ -0,0 +1,13 @@
+public class Test {
+    abstract class Base extends IntImpl {
+    }
+
+    abstract class IntImpl extends Int {
+        @Override
+        public abstract String foo()
+    }
+
+    class Int {
+        public abstract String foo();
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PreserveOverride_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverride_after.groovy
new file mode 100644
index 0000000..ea553c1
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverride_after.groovy
@@ -0,0 +1,13 @@
+abstract class Bazz {
+    public abstract void foo();
+}
+
+abstract class Foo extends Bazz {
+    @Override
+    public void foo() {
+    }
+}
+
+class Bar extends Foo {
+}
+
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PullUpAndMakeAbstract.groovy b/plugins/groovy/testdata/refactoring/pullUp/PullUpAndMakeAbstract.groovy
new file mode 100644
index 0000000..111cfbe
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PullUpAndMakeAbstract.groovy
@@ -0,0 +1,11 @@
+public class A2 {
+}
+
+class B2 extends A2 {
+  public void <caret>a() {
+    b();
+  }
+
+  private void b() {
+  }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PullUpAndMakeAbstract_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/PullUpAndMakeAbstract_after.groovy
new file mode 100644
index 0000000..312788c
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PullUpAndMakeAbstract_after.groovy
@@ -0,0 +1,14 @@
+public abstract class A2 {
+    public void a() {
+      b();
+    }
+
+    protected abstract void b()
+}
+
+class B2 extends A2 {
+
+    @Override
+    protected void b() {
+  }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PullUpInheritedStaticClasses.groovy b/plugins/groovy/testdata/refactoring/pullUp/PullUpInheritedStaticClasses.groovy
new file mode 100644
index 0000000..e0faaba
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PullUpInheritedStaticClasses.groovy
@@ -0,0 +1,8 @@
+public class A extends AA {
+  <caret>
+  static class C extends D {}
+  static class D extends B {}
+  static class B {}
+}
+
+class AA {}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PullUpInheritedStaticClasses_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/PullUpInheritedStaticClasses_after.groovy
new file mode 100644
index 0000000..cc948e7
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PullUpInheritedStaticClasses_after.groovy
@@ -0,0 +1,10 @@
+public class A extends AA {
+
+    static class B {}
+}
+
+class AA {
+    static class C extends D {}
+
+    static class D extends A.B {}
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PullUpPrivateInnerClassWithPrivateConstructor.groovy b/plugins/groovy/testdata/refactoring/pullUp/PullUpPrivateInnerClassWithPrivateConstructor.groovy
new file mode 100644
index 0000000..a5fbc56
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PullUpPrivateInnerClassWithPrivateConstructor.groovy
@@ -0,0 +1,15 @@
+public class B extends A {
+    private void f(){
+        new C();
+    }
+      <caret>
+    private static class C{
+        private C(){
+
+        }
+    }
+}
+
+//A.java
+class A {
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PullUpPrivateInnerClassWithPrivateConstructor_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/PullUpPrivateInnerClassWithPrivateConstructor_after.groovy
new file mode 100644
index 0000000..a1cc2b8
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PullUpPrivateInnerClassWithPrivateConstructor_after.groovy
@@ -0,0 +1,15 @@
+public class B extends A {
+    private void f(){
+        new C();
+    }
+
+}
+
+//A.java
+class A {
+    protected static class C{
+        protected C(){
+
+        }
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/QualifiedReference.groovy b/plugins/groovy/testdata/refactoring/pullUp/QualifiedReference.groovy
new file mode 100644
index 0000000..cf557dd
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/QualifiedReference.groovy
@@ -0,0 +1,13 @@
+class X {}
+
+class <caret>Y extends X {
+    private static int x = 0;
+
+    public static int getX() {
+        return x;
+    }
+
+    public static void setX(int x) {
+        Y.x = x;
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/QualifiedReference_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/QualifiedReference_after.groovy
new file mode 100644
index 0000000..2ee9526
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/QualifiedReference_after.groovy
@@ -0,0 +1,16 @@
+class X {
+    private static int x = 0
+
+    public static int getX() {
+        return x;
+    }
+
+    public static void setX(int x) {
+        X.x = x;
+    }
+}
+
+class Y extends X {
+
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/QualifiedSuper.groovy b/plugins/groovy/testdata/refactoring/pullUp/QualifiedSuper.groovy
new file mode 100644
index 0000000..6c58661
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/QualifiedSuper.groovy
@@ -0,0 +1,12 @@
+class <caret>QualifiedSuper extends Base {
+    class Inner {
+        void goo() {
+            QualifiedSuper.super.toString();
+        }
+    }
+}
+
+class Base {
+
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/QualifiedSuper_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/QualifiedSuper_after.groovy
new file mode 100644
index 0000000..08e7250
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/QualifiedSuper_after.groovy
@@ -0,0 +1,12 @@
+class QualifiedSuper extends Base {
+}
+
+class Base {
+
+
+    class Inner {
+        void goo() {
+            Base.this.toString();
+        }
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/QualifiedThis.groovy b/plugins/groovy/testdata/refactoring/pullUp/QualifiedThis.groovy
new file mode 100644
index 0000000..ae04288
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/QualifiedThis.groovy
@@ -0,0 +1,15 @@
+class Base {
+    void foo() {
+    }
+}
+
+public class <caret>QualifiedThis extends Base {
+    void foo() {
+    }
+
+    class Inner {
+        void bar() {
+            QualifiedThis.this.foo();
+        }
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/QualifiedThis_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/QualifiedThis_after.groovy
new file mode 100644
index 0000000..c097c66b
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/QualifiedThis_after.groovy
@@ -0,0 +1,16 @@
+class Base {
+    void foo() {
+    }
+
+    class Inner {
+        void bar() {
+            Base.this.foo();
+        }
+    }
+}
+
+public class QualifiedThis extends Base {
+    void foo() {
+    }
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/RemoveOverride.groovy b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverride.groovy
new file mode 100644
index 0000000..8c3d05f
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverride.groovy
@@ -0,0 +1,16 @@
+public class Test {
+    class Impl extends Base {
+        @Override
+        public String get() {
+            return "239";
+        }
+    }
+
+    abstract class Base implements Int {
+        public abstract String <caret>get();
+
+    }
+
+    interface Int {
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/RemoveOverrideFromPulledMethod.groovy b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverrideFromPulledMethod.groovy
new file mode 100644
index 0000000..f298edc
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverrideFromPulledMethod.groovy
@@ -0,0 +1,9 @@
+public class Test {
+    abstract class Base extends Int {
+        @Override
+        public abstract String<caret> foo();
+    }
+
+    class Int {
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/RemoveOverrideFromPulledMethod_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverrideFromPulledMethod_after.groovy
new file mode 100644
index 0000000..79ff76e
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverrideFromPulledMethod_after.groovy
@@ -0,0 +1,8 @@
+public class Test {
+    abstract class Base extends Int {
+    }
+
+    abstract class Int {
+        public abstract String foo()
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/RemoveOverride_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverride_after.groovy
new file mode 100644
index 0000000..94aef6d
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverride_after.groovy
@@ -0,0 +1,15 @@
+public class Test {
+    class Impl extends Base {
+        public String get() {
+            return "239";
+        }
+    }
+
+    abstract class Base implements Int {
+
+    }
+
+    interface Int {
+        String get();
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/ReplaceDuplicatesInInheritors.groovy b/plugins/groovy/testdata/refactoring/pullUp/ReplaceDuplicatesInInheritors.groovy
new file mode 100644
index 0000000..0f8c6a1
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/ReplaceDuplicatesInInheritors.groovy
@@ -0,0 +1,18 @@
+class A {}
+class AImpl1 extends A{
+  void f<caret>oo() {
+    System.out.println("hello");
+    System.out.println("hello");
+    System.out.println("hello");
+    System.out.println("hello");
+  }
+}
+
+class AImpl2 extends A {
+  void bar() {
+    System.out.println("hello");
+    System.out.println("hello");
+    System.out.println("hello");
+    System.out.println("hello");
+  }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/ReplaceDuplicatesInInheritors_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/ReplaceDuplicatesInInheritors_after.groovy
new file mode 100644
index 0000000..47b655c
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/ReplaceDuplicatesInInheritors_after.groovy
@@ -0,0 +1,16 @@
+class A {
+    void foo() {
+      System.out.println("hello");
+      System.out.println("hello");
+      System.out.println("hello");
+      System.out.println("hello");
+    }
+}
+class AImpl1 extends A{
+}
+
+class AImpl2 extends A {
+  void bar() {
+      foo();
+  }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TryCatchFieldInitializer.groovy b/plugins/groovy/testdata/refactoring/pullUp/TryCatchFieldInitializer.groovy
new file mode 100644
index 0000000..64675e4
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TryCatchFieldInitializer.groovy
@@ -0,0 +1,19 @@
+public class Sup {
+
+}
+
+class ExtractSuperClass extends Sup {
+
+  private final String <caret>field;
+
+  public ExtractSuperClass() {
+
+
+    try {
+      field = (String)"text";
+    }
+    catch (RuntimeException e) {
+      throw new RuntimeException();
+    }
+  }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TryCatchFieldInitializer_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/TryCatchFieldInitializer_after.groovy
new file mode 100644
index 0000000..600247f
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TryCatchFieldInitializer_after.groovy
@@ -0,0 +1,22 @@
+public class Sup {
+
+    protected final String field
+
+    public Sup() {
+        try {
+          field = (String)"text";
+        }
+        catch (RuntimeException e) {
+          throw new RuntimeException();
+        }
+    }
+}
+
+class ExtractSuperClass extends Sup {
+
+    public ExtractSuperClass() {
+        super();
+
+
+    }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeArgument.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeArgument.groovy
new file mode 100644
index 0000000..21140c8
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeArgument.groovy
@@ -0,0 +1,5 @@
+public class Parent<S> {}
+
+class Child extends Parent<String> {
+   String <caret>f;
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeArgument_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeArgument_after.groovy
new file mode 100644
index 0000000..3eb9010
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeArgument_after.groovy
@@ -0,0 +1,6 @@
+public class Parent<S> {
+    String f
+}
+
+class Child extends Parent<String> {
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeParamErasure.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeParamErasure.groovy
new file mode 100644
index 0000000..0dbc24f
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeParamErasure.groovy
@@ -0,0 +1,5 @@
+public class Parent {}
+
+class Child<T> extends Parent {
+   T <caret>f;
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeParamErasure_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeParamErasure_after.groovy
new file mode 100644
index 0000000..ab94d54
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeParamErasure_after.groovy
@@ -0,0 +1,6 @@
+public class Parent {
+    Object f
+}
+
+class Child<T> extends Parent {
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeParamSubst.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeParamSubst.groovy
new file mode 100644
index 0000000..f2ad0c7
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeParamSubst.groovy
@@ -0,0 +1,5 @@
+public class Parent<S> {}
+
+class Child<T> extends Parent<T> {
+   T <caret>f;
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeParamSubst_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeParamSubst_after.groovy
new file mode 100644
index 0000000..7034451
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeParamSubst_after.groovy
@@ -0,0 +1,6 @@
+public class Parent<S> {
+    S f
+}
+
+class Child<T> extends Parent<T> {
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeParamsConflictingNames.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeParamsConflictingNames.groovy
new file mode 100644
index 0000000..b0d7366
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeParamsConflictingNames.groovy
@@ -0,0 +1,7 @@
+interface Bar<T> { }
+
+interface Base<T> { }
+
+class Foo<T,U> implements Base<U> {
+    void fo<caret>o(Bar<U> bar) { }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeParamsConflictingNames_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeParamsConflictingNames_after.groovy
new file mode 100644
index 0000000..97b65ab
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeParamsConflictingNames_after.groovy
@@ -0,0 +1,10 @@
+interface Bar<T> { }
+
+interface Base<T> {
+    void foo(Bar<T> bar)
+}
+
+class Foo<T,U> implements Base<U> {
+    @Override
+    void foo(Bar<U> bar) { }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/UpdateStaticRefs.groovy b/plugins/groovy/testdata/refactoring/pullUp/UpdateStaticRefs.groovy
new file mode 100644
index 0000000..7ad6fb6
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/UpdateStaticRefs.groovy
@@ -0,0 +1,10 @@
+class Foo {}
+class FooImpl extends Foo {
+  public static void foo(){}
+  <caret>
+}
+class U {
+  public static void main(String[] args) {
+    FooImpl.foo();
+  }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/UpdateStaticRefs_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/UpdateStaticRefs_after.groovy
new file mode 100644
index 0000000..dc797f7
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/UpdateStaticRefs_after.groovy
@@ -0,0 +1,11 @@
+class Foo {
+    public static void foo(){}
+}
+class FooImpl extends Foo {
+
+}
+class U {
+  public static void main(String[] args) {
+    Foo.foo();
+  }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotationProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotationProvider.java
index eaad2b9..5592151 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotationProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotationProvider.java
@@ -29,6 +29,7 @@
 import org.zmlx.hg4idea.command.HgLogCommand;
 import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand;
 import org.zmlx.hg4idea.execution.HgCommandException;
+import org.zmlx.hg4idea.util.HgUtil;
 
 import java.util.List;
 
@@ -52,10 +53,12 @@
       throw new VcsException("vcs root is null for " + file);
     }
     final HgFile hgFile = new HgFile(vcsRoot, VfsUtilCore.virtualToIoFile(file));
-    final List<HgAnnotationLine> annotationResult = (new HgAnnotateCommand(myProject)).execute(hgFile, revision);
+    HgFile fileToAnnotate = revision instanceof HgFileRevision ? HgUtil
+      .getFileNameInTargetRevision(myProject, ((HgFileRevision)revision).getRevisionNumber(), hgFile) : hgFile;
+    final List<HgAnnotationLine> annotationResult = (new HgAnnotateCommand(myProject)).execute(fileToAnnotate, revision);
     final List<HgFileRevision> logResult;
     try {
-      logResult = (new HgLogCommand(myProject)).execute(hgFile, DEFAULT_LIMIT, false);
+      logResult = (new HgLogCommand(myProject)).execute(fileToAnnotate, DEFAULT_LIMIT, false);
     }
     catch (HgCommandException e) {
       throw new VcsException("Can not annotate, " + HgVcsMessages.message("hg4idea.error.log.command.execution"), e);
@@ -69,5 +72,4 @@
   public boolean isAnnotationValid(VcsFileRevision rev) {
     return true;
   }
-
 }
diff --git a/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/JpsJavaFxApplicationArtifactType.java b/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/JpsJavaFxApplicationArtifactType.java
index 3d1df6e..fbad37a 100644
--- a/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/JpsJavaFxApplicationArtifactType.java
+++ b/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/JpsJavaFxApplicationArtifactType.java
@@ -1,11 +1,12 @@
 package org.jetbrains.plugins.javaFX;
 
 import org.jetbrains.jps.model.artifact.JpsArtifactType;
+import org.jetbrains.jps.model.ex.JpsElementTypeBase;
 
 /**
  * User: anna
  * Date: 3/13/13
  */
-public class JpsJavaFxApplicationArtifactType extends JpsArtifactType<JpsJavaFxArtifactProperties> {
+public class JpsJavaFxApplicationArtifactType extends JpsElementTypeBase<JpsJavaFxArtifactProperties> implements JpsArtifactType<JpsJavaFxArtifactProperties> {
   public static final JpsJavaFxApplicationArtifactType INSTANCE = new JpsJavaFxApplicationArtifactType();
 }
diff --git a/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/preloader/JpsJavaFxPreloaderArtifactType.java b/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/preloader/JpsJavaFxPreloaderArtifactType.java
index ab0440dc9..d05fed5 100644
--- a/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/preloader/JpsJavaFxPreloaderArtifactType.java
+++ b/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/preloader/JpsJavaFxPreloaderArtifactType.java
@@ -16,11 +16,12 @@
 package org.jetbrains.plugins.javaFX.preloader;
 
 import org.jetbrains.jps.model.artifact.JpsArtifactType;
+import org.jetbrains.jps.model.ex.JpsElementTypeBase;
 
 /**
  * User: anna
  * Date: 3/13/13
  */
-public class JpsJavaFxPreloaderArtifactType extends JpsArtifactType<JpsJavaFxPreloaderArtifactProperties> {
+public class JpsJavaFxPreloaderArtifactType extends JpsElementTypeBase<JpsJavaFxPreloaderArtifactProperties> implements JpsArtifactType<JpsJavaFxPreloaderArtifactProperties> {
   public static final JpsJavaFxPreloaderArtifactType INSTANCE = new JpsJavaFxPreloaderArtifactType();
 }
diff --git a/plugins/javaFX/javaFX.iml b/plugins/javaFX/javaFX.iml
index 3513259..3abff64 100644
--- a/plugins/javaFX/javaFX.iml
+++ b/plugins/javaFX/javaFX.iml
@@ -22,6 +22,7 @@
     <orderEntry type="module" module-name="compiler-impl" />
     <orderEntry type="module" module-name="common-javaFX-plugin" />
     <orderEntry type="module" module-name="manifest" />
+    <orderEntry type="module" module-name="idea-ui" />
   </component>
 </module>
 
diff --git a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml
index df18ddf..af48a12 100644
--- a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml
+++ b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml
@@ -50,6 +50,9 @@
     <renamePsiElementProcessor implementation="org.jetbrains.plugins.javaFX.JavaFxRenameAttributeProcessor" order="before xmlAttribute"/>
     <completion.contributor implementationClass="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxCompletionContributor" language="XML" order="before xmlNonFirst"/>
     <manifest.parser.provider implementation="org.jetbrains.plugins.javaFX.manifest.JavaFxManifestHeaderParsers"/>
+    <!--
+    <projectWizard.projectCategory implementation="org.jetbrains.plugins.javaFX.JavaFxProjectType"/>
+    -->
   </extensions>
 
   <actions>
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxProjectType.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxProjectType.java
new file mode 100644
index 0000000..653c573
--- /dev/null
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxProjectType.java
@@ -0,0 +1,19 @@
+package org.jetbrains.plugins.javaFX;
+
+import com.intellij.ide.projectWizard.TemplateBasedProjectType;
+
+/**
+ * @author Dmitry Avdeev
+ *         Date: 20.09.13
+ */
+public class JavaFxProjectType extends TemplateBasedProjectType {
+
+  public JavaFxProjectType() {
+    super("/resources/projectTemplates/Java/JavaFX Application.zip");
+  }
+
+  @Override
+  public String getId() {
+    return "JavaFX";
+  }
+}
diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java b/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java
index 21828ec..dcbff35 100644
--- a/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java
+++ b/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java
@@ -33,6 +33,11 @@
     return "JUnit3";
   }
 
+  @Override
+  public char getMnemonic() {
+    return '3';
+  }
+
   @NotNull
   @Override
   public Icon getIcon() {
diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnit4Framework.java b/plugins/junit/src/com/intellij/execution/junit/JUnit4Framework.java
index 3f724c4..bcb3678 100644
--- a/plugins/junit/src/com/intellij/execution/junit/JUnit4Framework.java
+++ b/plugins/junit/src/com/intellij/execution/junit/JUnit4Framework.java
@@ -146,6 +146,11 @@
   }
 
   @Override
+  public char getMnemonic() {
+    return '4';
+  }
+
+  @Override
   public boolean isParameterized(PsiClass clazz) {
     final PsiAnnotation annotation = AnnotationUtil.findAnnotation(clazz, JUnitUtil.RUN_WITH);
     if (annotation != null) {
diff --git a/plugins/junit/src/com/intellij/execution/junit/TestClassFilter.java b/plugins/junit/src/com/intellij/execution/junit/TestClassFilter.java
index 84b5e3b..cc58990 100644
--- a/plugins/junit/src/com/intellij/execution/junit/TestClassFilter.java
+++ b/plugins/junit/src/com/intellij/execution/junit/TestClassFilter.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.
@@ -27,7 +27,6 @@
 import com.intellij.psi.PsiClass;
 import com.intellij.psi.PsiManager;
 import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.util.PsiUtilBase;
 import com.intellij.psi.util.PsiUtilCore;
 import org.jetbrains.annotations.NotNull;
 
@@ -55,7 +54,8 @@
     return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
       @Override
       public Boolean compute() {
-        return ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS.value(aClass) &&
+        return aClass.getQualifiedName() != null &&
+               ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS.value(aClass) &&
                (aClass.isInheritor(myBase, true) || JUnitUtil.isTestClass(aClass))
                && !CompilerConfiguration.getInstance(getProject()).isExcludedFromCompilation(PsiUtilCore.getVirtualFile(aClass)); 
       }
diff --git a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenArtifactInfo.java b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenArtifactInfo.java
index 9344d31..d04fb9e 100644
--- a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenArtifactInfo.java
+++ b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenArtifactInfo.java
@@ -95,6 +95,7 @@
     MavenId.append(builder, myPackaging);
     if (!StringUtil.isEmptyOrSpaces(myClassifier)) MavenId.append(builder, myClassifier);
     MavenId.append(builder, myVersion);
+    MavenId.append(builder, myRepositoryId);
 
     return builder.toString();
   }
diff --git a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenRepositoryInfo.java b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenRepositoryInfo.java
index dd9fd21..2e3a566 100644
--- a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenRepositoryInfo.java
+++ b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenRepositoryInfo.java
@@ -39,4 +39,15 @@
   public String getUrl() {
     return myUrl;
   }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+
+    MavenId.append(builder, myId);
+    MavenId.append(builder, myName);
+    MavenId.append(builder, myUrl);
+
+    return builder.toString();
+  }
 }
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java
index 69af10c..179127d 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java
@@ -232,6 +232,7 @@
   public static <T extends MavenDomElement> T getMavenDomModel(@NotNull Project project,
                                                                @NotNull VirtualFile file,
                                                                @NotNull Class<T> clazz) {
+    if (!file.isValid()) return null;
     PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
     if (psiFile == null) return null;
     return getMavenDomModel(psiFile, clazz);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicateDependenciesInspection.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicateDependenciesInspection.java
index 134ac62..cd37e99 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicateDependenciesInspection.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicateDependenciesInspection.java
@@ -22,12 +22,12 @@
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.xml.XmlTag;
 import com.intellij.util.Processor;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.util.containers.MultiMapBasedOnSet;
 import com.intellij.util.containers.hash.HashSet;
 import com.intellij.util.xml.DomFileElement;
 import com.intellij.util.xml.highlighting.BasicDomElementsInspection;
 import com.intellij.util.xml.highlighting.DomElementAnnotationHolder;
-import gnu.trove.THashMap;
-import gnu.trove.THashSet;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.idea.maven.dom.DependencyConflictId;
 import org.jetbrains.idea.maven.dom.MavenDomBundle;
@@ -56,13 +56,13 @@
 
   private static void checkDependencies(@NotNull MavenDomProjectModel projectModel,
                                         @NotNull DomElementAnnotationHolder holder) {
-    final Map<DependencyConflictId, Set<MavenDomDependency>> allDuplicates = getDuplicateDependenciesMap(projectModel);
+    MultiMap<DependencyConflictId, MavenDomDependency> allDuplicates = getDuplicateDependenciesMap(projectModel);
 
     for (MavenDomDependency dependency : projectModel.getDependencies().getDependencies()) {
       DependencyConflictId id = DependencyConflictId.create(dependency);
       if (id != null) {
-        Set<MavenDomDependency> dependencies = allDuplicates.get(id);
-        if (dependencies != null && dependencies.size() > 1) {
+        Collection<MavenDomDependency> dependencies = allDuplicates.get(id);
+        if (dependencies.size() > 1) {
 
           List<MavenDomDependency> duplicatedDependencies = new ArrayList<MavenDomDependency>();
 
@@ -115,22 +115,12 @@
   }
 
   private static String createLinkText(@NotNull MavenDomProjectModel model, @NotNull MavenDomDependency dependency) {
-    StringBuilder sb = new StringBuilder();
-
     XmlTag tag = dependency.getXmlTag();
     if (tag == null) return getProjectName(model);
     VirtualFile file = tag.getContainingFile().getVirtualFile();
     if (file == null) return getProjectName(model);
 
-    sb.append("<a href ='#navigation/");
-    sb.append(file.getPath());
-    sb.append(":");
-    sb.append(tag.getTextRange().getStartOffset());
-    sb.append("'>");
-    sb.append(getProjectName(model));
-    sb.append("</a>");
-
-    return sb.toString();
+    return "<a href ='#navigation/" + file.getPath() + ":" + tag.getTextRange().getStartOffset() + "'>" + getProjectName(model) + "</a>";
   }
 
   @NotNull
@@ -151,8 +141,8 @@
   }
 
   @NotNull
-  private static Map<DependencyConflictId, Set<MavenDomDependency>> getDuplicateDependenciesMap(MavenDomProjectModel projectModel) {
-    final Map<DependencyConflictId, Set<MavenDomDependency>> allDependencies = new HashMap<DependencyConflictId, Set<MavenDomDependency>>();
+  private static MultiMap<DependencyConflictId, MavenDomDependency> getDuplicateDependenciesMap(MavenDomProjectModel projectModel) {
+    final MultiMap<DependencyConflictId, MavenDomDependency> allDependencies = new MultiMapBasedOnSet<DependencyConflictId, MavenDomDependency>();
 
     Processor<MavenDomProjectModel> collectProcessor = new Processor<MavenDomProjectModel>() {
       public boolean process(MavenDomProjectModel model) {
@@ -167,28 +157,22 @@
     return allDependencies;
   }
 
-  private static void collect(Map<DependencyConflictId, Set<MavenDomDependency>> duplicates, @NotNull MavenDomDependencies dependencies) {
+  private static void collect(MultiMap<DependencyConflictId, MavenDomDependency> duplicates, @NotNull MavenDomDependencies dependencies) {
     for (MavenDomDependency dependency : dependencies.getDependencies()) {
       DependencyConflictId mavenId = DependencyConflictId.create(dependency);
       if (mavenId == null) continue;
 
-      Set<MavenDomDependency> set = duplicates.get(mavenId);
-      if (set == null) {
-        set = new THashSet<MavenDomDependency>();
-        duplicates.put(mavenId, set);
-      }
-
-      set.add(dependency);
+      duplicates.putValue(mavenId, dependency);
     }
   }
 
   private static void checkManagedDependencies(@NotNull MavenDomProjectModel projectModel,
                                                @NotNull DomElementAnnotationHolder holder) {
-    final Map<DependencyConflictId, Set<MavenDomDependency>> duplicates = new THashMap<DependencyConflictId, Set<MavenDomDependency>>();
+    MultiMap<DependencyConflictId, MavenDomDependency> duplicates = new MultiMapBasedOnSet<DependencyConflictId, MavenDomDependency>();
     collect(duplicates, projectModel.getDependencyManagement().getDependencies());
 
-    for (Map.Entry<DependencyConflictId, Set<MavenDomDependency>> entry : duplicates.entrySet()) {
-      Set<MavenDomDependency> set = entry.getValue();
+    for (Map.Entry<DependencyConflictId, Collection<MavenDomDependency>> entry : duplicates.entrySet()) {
+      Collection<MavenDomDependency> set = entry.getValue();
       if (set.size() <= 1) continue;
 
       for (MavenDomDependency dependency : set) {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicatePluginInspection.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicatePluginInspection.java
new file mode 100644
index 0000000..7e7f510
--- /dev/null
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicatePluginInspection.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2000-2010 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.maven.dom.inspections;
+
+import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.util.containers.MultiMapBasedOnSet;
+import com.intellij.util.xml.DomFileElement;
+import com.intellij.util.xml.highlighting.BasicDomElementsInspection;
+import com.intellij.util.xml.highlighting.DomElementAnnotationHolder;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.maven.dom.MavenDomBundle;
+import org.jetbrains.idea.maven.dom.model.MavenDomPlugin;
+import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
+
+import java.util.Collection;
+import java.util.Map;
+
+public class MavenDuplicatePluginInspection extends BasicDomElementsInspection<MavenDomProjectModel> {
+  public MavenDuplicatePluginInspection() {
+    super(MavenDomProjectModel.class);
+  }
+
+  @Override
+  public void checkFileElement(DomFileElement<MavenDomProjectModel> domFileElement,
+                               DomElementAnnotationHolder holder) {
+    MavenDomProjectModel projectModel = domFileElement.getRootElement();
+
+    MultiMap<Pair<String,String>, MavenDomPlugin> duplicates = new MultiMapBasedOnSet<Pair<String, String>, MavenDomPlugin>();
+
+    for (MavenDomPlugin plugin : projectModel.getBuild().getPlugins().getPlugins()) {
+      String groupId = plugin.getGroupId().getStringValue();
+      String artifactId = plugin.getArtifactId().getStringValue();
+
+      if (StringUtil.isEmptyOrSpaces(artifactId)) continue;
+
+      if ("".equals(groupId) || "org.apache.maven.plugins".equals(groupId) || "org.codehaus.mojo".equals(groupId)) {
+        groupId = null;
+      }
+
+      duplicates.putValue(Pair.create(groupId, artifactId), plugin);
+    }
+
+    for (Map.Entry<Pair<String,String>, Collection<MavenDomPlugin>> entry : duplicates.entrySet()) {
+      Collection<MavenDomPlugin> set = entry.getValue();
+      if (set.size() <= 1) continue;
+
+      for (MavenDomPlugin dependency : set) {
+        holder.createProblem(dependency, HighlightSeverity.WARNING, "Duplicated plugin declaration");
+      }
+    }
+  }
+
+  @NotNull
+  public String getGroupDisplayName() {
+    return MavenDomBundle.message("inspection.group");
+  }
+
+  @NotNull
+  public String getDisplayName() {
+    return MavenDomBundle.message("inspection.duplicate.plugin.declaration");
+  }
+
+  @NotNull
+  public String getShortName() {
+    return "MavenDuplicatePluginInspection";
+  }
+
+  @NotNull
+  public HighlightDisplayLevel getDefaultLevel() {
+    return HighlightDisplayLevel.WARNING;
+  }
+}
\ No newline at end of file
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java
index 2aa3515..a8f4606 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java
@@ -69,7 +69,7 @@
   private static final Logger LOG = Logger.getInstance(MavenExternalParameters.class);
 
   public static final String MAVEN_LAUNCHER_CLASS = "org.codehaus.classworlds.Launcher";
-  @NonNls private static final String JAVA_HOME = "JAVA_HOME";
+
   @NonNls private static final String MAVEN_OPTS = "MAVEN_OPTS";
 
   @Deprecated // Use createJavaParameters(Project,MavenRunnerParameters, MavenGeneralSettings,MavenRunnerSettings,MavenRunConfiguration)
@@ -295,7 +295,7 @@
     }
 
     if (name.equals(MavenRunnerSettings.USE_JAVA_HOME)) {
-      final String javaHome = System.getenv(JAVA_HOME);
+      final String javaHome = System.getenv("JAVA_HOME");
       if (StringUtil.isEmptyOrSpaces(javaHome)) {
         throw new ExecutionException(RunnerBundle.message("maven.java.home.undefined"));
       }
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenJdkComboBox.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenJdkComboBox.java
new file mode 100644
index 0000000..f982ef9
--- /dev/null
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenJdkComboBox.java
@@ -0,0 +1,102 @@
+package org.jetbrains.idea.maven.execution;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
+import com.intellij.openapi.roots.ProjectRootManager;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.maven.utils.ComboBoxUtil;
+
+import javax.swing.*;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author Sergey Evdokimov
+ */
+public class MavenJdkComboBox extends JComboBox {
+
+  private static final int MAX_PATH_LENGTH = 50;
+
+  @Nullable
+  private final Project myProject;
+
+  public MavenJdkComboBox(@Nullable Project project) {
+    myProject = project;
+  }
+
+  @Nullable
+  public Project getProject() {
+    return myProject;
+  }
+
+  public void refreshData(@Nullable String selectedValue) {
+    Map<String, String> jdkMap = collectJdkNamesAndDescriptions();
+    if (selectedValue != null && !jdkMap.containsKey(selectedValue)) {
+      assert selectedValue.length() > 0;
+      jdkMap.put(selectedValue, selectedValue);
+    }
+
+    removeAllItems();
+
+    for (Map.Entry<String, String> entry : jdkMap.entrySet()) {
+      ComboBoxUtil.addToModel((DefaultComboBoxModel)getModel(), entry.getKey(), entry.getValue());
+    }
+
+    ComboBoxUtil.select((DefaultComboBoxModel)getModel(), selectedValue);
+  }
+
+  public String getSelectedValue() {
+    return ComboBoxUtil.getSelectedString((DefaultComboBoxModel)getModel());
+  }
+
+  private Map<String, String> collectJdkNamesAndDescriptions() {
+    Map<String, String> result = new LinkedHashMap<String, String>();
+
+    for (Sdk projectJdk : ProjectJdkTable.getInstance().getSdksOfType(JavaSdk.getInstance())) {
+      String name = projectJdk.getName();
+
+      String label;
+
+      String path = projectJdk.getHomePath();
+      if (path == null) {
+        label = name;
+      }
+      else {
+        label = String.format("<html>%s <font color=gray>(%s)</font></html>", name, truncateLongPath(path));
+      }
+
+      result.put(name, label);
+    }
+
+    String internalJdkPath = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk().getHomePath();
+    assert internalJdkPath != null;
+    result.put(MavenRunnerSettings.USE_INTERNAL_JAVA, RunnerBundle.message("maven.java.internal", truncateLongPath(internalJdkPath)));
+
+    if (myProject != null) {
+      String projectJdk = ProjectRootManager.getInstance(myProject).getProjectSdkName();
+      String projectJdkTitle = String.format("<html>Use Project JDK <font color=gray>(%s)</font></html>", projectJdk == null ? "not defined yet" : projectJdk);
+      result.put(MavenRunnerSettings.USE_PROJECT_JDK, projectJdkTitle);
+    }
+
+    String javaHomePath = System.getenv("JAVA_HOME");
+    String javaHomeLabel = RunnerBundle.message("maven.java.home.env", javaHomePath == null ? "not defined yet" : truncateLongPath(javaHomePath));
+
+    result.put(MavenRunnerSettings.USE_JAVA_HOME, javaHomeLabel);
+
+    return result;
+  }
+
+  @NotNull
+  private static String truncateLongPath(@NotNull String path) {
+    if (path.length() > MAX_PATH_LENGTH) {
+      return path.substring(0, MAX_PATH_LENGTH / 2) + "..." + path.substring(path.length() - MAX_PATH_LENGTH / 2 - 3);
+    }
+
+    return path;
+  }
+
+}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunnerPanel.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunnerPanel.java
index 61a45a4..14a0197 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunnerPanel.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunnerPanel.java
@@ -19,16 +19,11 @@
 
 import com.intellij.execution.configuration.EnvironmentVariablesComponent;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.JavaSdk;
-import com.intellij.openapi.projectRoots.ProjectJdkTable;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.ui.IdeBorderFactory;
 import com.intellij.ui.RawCommandLineEditor;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.idea.maven.project.MavenProject;
 import org.jetbrains.idea.maven.project.MavenProjectsManager;
-import org.jetbrains.idea.maven.utils.ComboBoxUtil;
 
 import javax.swing.*;
 import java.awt.*;
@@ -43,8 +38,8 @@
   private JCheckBox myRunInBackgroundCheckbox;
   private RawCommandLineEditor myVMParametersEditor;
   private EnvironmentVariablesComponent myEnvVariablesComponent;
-  private JComboBox myJdkCombo;
-  private final DefaultComboBoxModel myJdkComboModel = new DefaultComboBoxModel();
+  private MavenJdkComboBox myJdkCombo;
+
   private JCheckBox mySkipTestsCheckBox;
   private MavenPropertiesPanel myPropertiesPanel;
 
@@ -93,7 +88,7 @@
 
     JLabel jdkLabel = new JLabel("JRE:");
     jdkLabel.setDisplayedMnemonic('j');
-    jdkLabel.setLabelFor(myJdkCombo = new JComboBox());
+    jdkLabel.setLabelFor(myJdkCombo = new MavenJdkComboBox(myProject));
     c.gridx = 0;
     c.gridy++;
     c.weightx = 0;
@@ -153,17 +148,7 @@
     myVMParametersEditor.setText(data.getVmOptions());
     mySkipTestsCheckBox.setSelected(data.isSkipTests());
 
-    Map<String, String> jdkMap = collectJdkNamesAndDescriptions();
-    if (!jdkMap.containsKey(data.getJreName())) {
-      jdkMap.put(data.getJreName(), data.getJreName());
-    }
-
-    myJdkComboModel.removeAllElements();
-    for (Map.Entry<String, String> entry : jdkMap.entrySet()) {
-      ComboBoxUtil.addToModel(myJdkComboModel, entry.getKey(), entry.getValue());
-    }
-    myJdkCombo.setModel(myJdkComboModel);
-    ComboBoxUtil.select(myJdkComboModel, data.getJreName());
+    myJdkCombo.refreshData(data.getJreName());
 
     myPropertiesPanel.setDataFromMap(data.getMavenProperties());
 
@@ -171,37 +156,12 @@
     myEnvVariablesComponent.setPassParentEnvs(data.isPassParentEnv());
   }
 
-  private Map<String, String> collectJdkNamesAndDescriptions() {
-    Map<String, String> result = new LinkedHashMap<String, String>();
-
-    for (Sdk projectJdk : ProjectJdkTable.getInstance().getSdksOfType(JavaSdk.getInstance())) {
-      String name = projectJdk.getName();
-      result.put(name, name);
-    }
-
-    result.put(MavenRunnerSettings.USE_INTERNAL_JAVA, RunnerBundle.message("maven.java.internal"));
-
-    String projectJdkTitle;
-
-    String projectJdk = ProjectRootManager.getInstance(myProject).getProjectSdkName();
-    if (projectJdk == null) {
-      projectJdkTitle = "Use Project JDK (not defined yet)";
-    }
-    else {
-      projectJdkTitle = "Use Project JDK (" + projectJdk + ')';
-    }
-
-    result.put(MavenRunnerSettings.USE_PROJECT_JDK, projectJdkTitle);
-    result.put(MavenRunnerSettings.USE_JAVA_HOME, RunnerBundle.message("maven.java.home.env"));
-
-    return result;
-  }
 
   protected void setData(MavenRunnerSettings data) {
     data.setRunMavenInBackground(myRunInBackgroundCheckbox.isSelected());
     data.setVmOptions(myVMParametersEditor.getText().trim());
     data.setSkipTests(mySkipTestsCheckBox.isSelected());
-    data.setJreName(ComboBoxUtil.getSelectedString(myJdkComboModel));
+    data.setJreName(myJdkCombo.getSelectedValue());
 
     data.setMavenProperties(myPropertiesPanel.getDataAsMap());
 
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/GroovyImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/GroovyImporter.java
index 2f35f62..d4c4628 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/GroovyImporter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/GroovyImporter.java
@@ -1,12 +1,15 @@
 package org.jetbrains.idea.maven.importing;
 
 import com.intellij.openapi.module.Module;
+import com.intellij.util.PairConsumer;
 import org.jdom.Element;
 import org.jetbrains.idea.maven.project.MavenProject;
 import org.jetbrains.idea.maven.project.MavenProjectChanges;
 import org.jetbrains.idea.maven.project.MavenProjectsProcessorTask;
 import org.jetbrains.idea.maven.project.MavenProjectsTree;
 import org.jetbrains.idea.maven.utils.MavenJDOMUtil;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 
 import java.util.List;
 import java.util.Map;
@@ -33,23 +36,22 @@
   }
 
   @Override
-  public void collectSourceFolders(MavenProject mavenProject, List<String> result) {
-    collectSourceOrTestFolders(mavenProject, "compile", "src/main/groovy", result);
+  public void collectSourceRoots(MavenProject mavenProject, PairConsumer<String, JpsModuleSourceRootType<?>> result) {
+    collectSourceOrTestFolders(mavenProject, "compile", "src/main/groovy", JavaSourceRootType.SOURCE, result);
+    collectSourceOrTestFolders(mavenProject, "testCompile", "src/test/groovy", JavaSourceRootType.TEST_SOURCE, result);
   }
 
-  @Override
-  public void collectTestFolders(MavenProject mavenProject, List<String> result) {
-    collectSourceOrTestFolders(mavenProject, "testCompile", "src/test/groovy", result);
-  }
-
-  private void collectSourceOrTestFolders(MavenProject mavenProject, String goal, String defaultDir, List<String> result) {
+  private void collectSourceOrTestFolders(MavenProject mavenProject, String goal, String defaultDir, JavaSourceRootType type,
+                                          PairConsumer<String, JpsModuleSourceRootType<?>> result) {
     Element sourcesElement = getGoalConfig(mavenProject, goal);
     List<String> dirs = MavenJDOMUtil.findChildrenValuesByPath(sourcesElement, "sources", "fileset.directory");
     if (dirs.isEmpty()) {
-      result.add(mavenProject.getDirectory() + "/" + defaultDir);
+      result.consume(mavenProject.getDirectory() + "/" + defaultDir, type);
       return;
     }
-    result.addAll(dirs);
+    for (String dir : dirs) {
+      result.consume(dir, type);
+    }
   }
 
   @Override
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 0f5441e..be9ebda 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
@@ -24,16 +24,20 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ModifiableRootModel;
 import com.intellij.openapi.roots.impl.ModifiableModelCommitter;
-import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.util.ArrayUtil;
+import com.intellij.util.PairConsumer;
+import com.intellij.util.containers.LinkedMultiMap;
+import com.intellij.util.containers.MultiMap;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.idea.maven.model.MavenResource;
 import org.jetbrains.idea.maven.project.MavenImportingSettings;
 import org.jetbrains.idea.maven.project.MavenProject;
 import org.jetbrains.idea.maven.project.MavenProjectsManager;
-import org.jetbrains.idea.maven.utils.Path;
+import org.jetbrains.jps.model.java.JavaResourceRootType;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -102,70 +106,60 @@
   }
 
   private void configSourceFolders() {
-    List<String> sourceFolders = new ArrayList<String>();
-    List<String> testFolders = new ArrayList<String>();
+    final MultiMap<JpsModuleSourceRootType<?>, String> roots = new LinkedMultiMap<JpsModuleSourceRootType<?>, String>();
 
-    sourceFolders.addAll(myMavenProject.getSources());
-    testFolders.addAll(myMavenProject.getTestSources());
+    roots.putValues(JavaSourceRootType.SOURCE, myMavenProject.getSources());
+    roots.putValues(JavaSourceRootType.TEST_SOURCE, myMavenProject.getTestSources());
 
     for (MavenImporter each : MavenImporter.getSuitableImporters(myMavenProject)) {
-      each.collectSourceFolders(myMavenProject, sourceFolders);
-      each.collectTestFolders(myMavenProject, testFolders);
+      each.collectSourceRoots(myMavenProject, new PairConsumer<String, JpsModuleSourceRootType<?>>() {
+        @Override
+        public void consume(String s, JpsModuleSourceRootType<?> type) {
+          roots.putValue(type, s);
+        }
+      });
     }
 
     for (MavenResource each : myMavenProject.getResources()) {
-      sourceFolders.add(each.getDirectory());
+      roots.putValue(JavaResourceRootType.RESOURCE, each.getDirectory());
     }
     for (MavenResource each : myMavenProject.getTestResources()) {
-      testFolders.add(each.getDirectory());
+      roots.putValue(JavaResourceRootType.TEST_RESOURCE, each.getDirectory());
     }
 
-    addBuilderHelperPaths("add-source", sourceFolders);
-    addBuilderHelperPaths("add-test-source", testFolders);
+    addBuilderHelperPaths("add-source", roots.getModifiable(JavaSourceRootType.SOURCE));
+    addBuilderHelperPaths("add-test-source", roots.getModifiable(JavaSourceRootType.TEST_SOURCE));
 
-    List<Pair<Path, Boolean>> allFolders = new ArrayList<Pair<Path, Boolean>>(sourceFolders.size() + testFolders.size());
-    for (String each : sourceFolders) {
-      allFolders.add(Pair.create(myModel.toPath(each), false));
-    }
-    for (String each : testFolders) {
-      allFolders.add(Pair.create(myModel.toPath(each), true));
-    }
-
-    for (Pair<Path, Boolean> each : normalize(allFolders)) {
-      myModel.addSourceFolder(each.first.getPath(), each.second);
+    List<String> addedPaths = new ArrayList<String>();
+    for (JpsModuleSourceRootType<?> type : roots.keySet()) {
+      for (String path : roots.get(type)) {
+        addSourceFolderIfNotOverlap(path, type, addedPaths);
+      }
     }
   }
 
-  private void addBuilderHelperPaths(String goal, List<String> folders) {
+  private void addBuilderHelperPaths(String goal, Collection<String> folders) {
     final Element configurationElement = myMavenProject.getPluginGoalConfiguration("org.codehaus.mojo", "build-helper-maven-plugin", goal);
     if (configurationElement != null) {
       final Element sourcesElement = configurationElement.getChild("sources");
       if (sourcesElement != null) {
-        //noinspection unchecked
-        for (Element element : (List<Element>)sourcesElement.getChildren()) {
+        for (Element element : sourcesElement.getChildren()) {
           folders.add(element.getTextTrim());
         }
       }
     }
   }
 
-  @NotNull
-  private static List<Pair<Path, Boolean>> normalize(@NotNull List<Pair<Path, Boolean>> folders) {
-    List<Pair<Path, Boolean>> result = new ArrayList<Pair<Path, Boolean>>(folders.size());
-    for (Pair<Path, Boolean> eachToAdd : folders) {
-      addSourceFolder(eachToAdd, result);
-    }
-    return result;
-  }
-
-  private static void addSourceFolder(Pair<Path, Boolean> folder, List<Pair<Path, Boolean>> result) {
-    for (Pair<Path, Boolean> eachExisting : result) {
-      if (MavenRootModelAdapter.isEqualOrAncestor(eachExisting.first.getPath(), folder.first.getPath())
-          || MavenRootModelAdapter.isEqualOrAncestor(folder.first.getPath(), eachExisting.first.getPath())) {
+  private void addSourceFolderIfNotOverlap(String path, JpsModuleSourceRootType<?> type, List<String> addedPaths) {
+    String canonicalPath = myModel.toPath(path).getPath();
+    for (String existing : addedPaths) {
+      if (MavenRootModelAdapter.isEqualOrAncestor(existing, canonicalPath)
+          || MavenRootModelAdapter.isEqualOrAncestor(canonicalPath, existing)) {
         return;
       }
     }
-    result.add(folder);
+    addedPaths.add(canonicalPath);
+    myModel.addSourceFolder(canonicalPath, type);
   }
 
   private void configOutputFolders() {
@@ -186,8 +180,8 @@
     myModel.unregisterAll(targetDir.getPath(), true, false);
 
     if (myImportingSettings.getGeneratedSourcesFolder() != MavenImportingSettings.GeneratedSourcesFolder.IGNORE) {
-      myModel.addSourceFolder(myMavenProject.getAnnotationProcessorDirectory(true), true, true);
-      myModel.addSourceFolder(myMavenProject.getAnnotationProcessorDirectory(false), false, true);
+      myModel.addSourceFolder(myMavenProject.getAnnotationProcessorDirectory(true), JavaSourceRootType.TEST_SOURCE, true);
+      myModel.addSourceFolder(myMavenProject.getAnnotationProcessorDirectory(false), JavaSourceRootType.SOURCE, true);
     }
 
     File[] targetChildren = targetDir.listFiles();
@@ -197,10 +191,10 @@
         if (!f.isDirectory()) continue;
 
         if (FileUtil.pathsEqual(generatedDir, f.getPath())) {
-          configGeneratedSourceFolder(f, false);
+          configGeneratedSourceFolder(f, JavaSourceRootType.SOURCE);
         }
         else if (FileUtil.pathsEqual(generatedDirTest, f.getPath())) {
-          configGeneratedSourceFolder(f, true);
+          configGeneratedSourceFolder(f, JavaSourceRootType.TEST_SOURCE);
         }
         else {
           if (myImportingSettings.isExcludeTargetFolder()) {
@@ -232,29 +226,29 @@
     }
   }
 
-  private void configGeneratedSourceFolder(@NotNull File targetDir, boolean isTestSources) {
+  private void configGeneratedSourceFolder(@NotNull File targetDir, final JavaSourceRootType rootType) {
     switch (myImportingSettings.getGeneratedSourcesFolder()) {
       case GENERATED_SOURCE_FOLDER:
-        myModel.addSourceFolder(targetDir.getPath(), isTestSources, true);
+        myModel.addSourceFolder(targetDir.getPath(), rootType, true);
         break;
 
       case SUBFOLDER:
-        addAllSubDirsAsSources(targetDir, isTestSources);
+        addAllSubDirsAsSources(targetDir, rootType);
         break;
 
       case AUTODETECT:
         Collection<JavaModuleSourceRoot> sourceRoots = JavaSourceRootDetectionUtil.suggestRoots(targetDir);
 
         for (JavaModuleSourceRoot root : sourceRoots) {
-          if (targetDir.equals(root.getDirectory())) {
-            myModel.addSourceFolder(targetDir.getPath(), isTestSources);
+          if (FileUtil.filesEqual(targetDir, root.getDirectory())) {
+            myModel.addSourceFolder(targetDir.getPath(), rootType);
             return;
           }
 
-          addAsSourceFolder(root.getDirectory(), isTestSources);
+          addAsSourceFolder(root.getDirectory(), rootType);
         }
 
-        addAllSubDirsAsSources(targetDir, isTestSources);
+        addAllSubDirsAsSources(targetDir, rootType);
         break;
 
       case IGNORE:
@@ -262,16 +256,16 @@
     }
   }
 
-  private void addAsSourceFolder(@NotNull File dir, boolean isTestSources) {
+  private void addAsSourceFolder(@NotNull File dir, final JavaSourceRootType rootType) {
     if (!myModel.hasRegisteredSourceSubfolder(dir)) {
-      myModel.addSourceFolder(dir.getPath(), isTestSources, true);
+      myModel.addSourceFolder(dir.getPath(), rootType, true);
     }
   }
 
-  private void addAllSubDirsAsSources(@NotNull File dir, boolean isTestSources) {
+  private void addAllSubDirsAsSources(@NotNull File dir, final JavaSourceRootType rootType) {
     for (File f : getChildren(dir)) {
       if (f.isDirectory()) {
-        addAsSourceFolder(f, isTestSources);
+        addAsSourceFolder(f, rootType);
       }
     }
   }
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenImporter.java
index a646e8d..08117ac 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenImporter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenImporter.java
@@ -22,6 +22,7 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.Pair;
+import com.intellij.util.PairConsumer;
 import com.intellij.util.containers.ContainerUtil;
 import gnu.trove.THashSet;
 import org.jdom.Element;
@@ -33,6 +34,8 @@
 import org.jetbrains.idea.maven.server.NativeMavenProjectHolder;
 import org.jetbrains.idea.maven.utils.MavenJDOMUtil;
 import org.jetbrains.idea.maven.utils.MavenProcessCanceledException;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 
 import java.util.*;
 
@@ -139,9 +142,28 @@
     return true;
   }
 
+  public void collectSourceRoots(MavenProject mavenProject, PairConsumer<String, JpsModuleSourceRootType<?>> result) {
+    List<String> sources = new ArrayList<String>();
+    collectSourceFolders(mavenProject, sources);
+    for (String path : sources) {
+      result.consume(path, JavaSourceRootType.SOURCE);
+    }
+    List<String> testSources = new ArrayList<String>();
+    collectTestFolders(mavenProject, testSources);
+    for (String path : testSources) {
+      result.consume(path, JavaSourceRootType.TEST_SOURCE);
+    }
+  }
+
+  /**
+   * @deprecated override {@link #collectSourceRoots} instead
+   */
   public void collectSourceFolders(MavenProject mavenProject, List<String> result) {
   }
 
+  /**
+   * @deprecated override {@link #collectSourceRoots} instead
+   */
   public void collectTestFolders(MavenProject mavenProject, List<String> result) {
   }
 
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java
index 373161d..87d5f5e 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java
@@ -39,6 +39,7 @@
 import org.jetbrains.idea.maven.project.MavenProjectsManager;
 import org.jetbrains.idea.maven.utils.Path;
 import org.jetbrains.idea.maven.utils.Url;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 
 import java.io.File;
 import java.util.Set;
@@ -129,11 +130,11 @@
     }
   }
 
-  public void addSourceFolder(String path, boolean testSource) {
-    addSourceFolder(path, testSource, false);
+  public void addSourceFolder(String path, final JpsModuleSourceRootType<?> rootType) {
+    addSourceFolder(path, rootType, false);
   }
 
-  public void addSourceFolder(String path, boolean testSource, boolean ifNotEmpty) {
+  public void addSourceFolder(String path, final JpsModuleSourceRootType<?> rootType, boolean ifNotEmpty) {
     if (ifNotEmpty) {
       String[] childs = new File(toPath(path).getPath()).list();
       if (childs == null || childs.length == 0) return;
@@ -147,19 +148,7 @@
     if (e == null) return;
     unregisterAll(path, true, true);
     unregisterAll(path, false, true);
-    e.addSourceFolder(url.getUrl(), testSource);
-  }
-
-  public void addSourceFolderSoft(String path, boolean testSource) {
-    if (!exists(path)) return;
-
-    Url url = toUrl(path);
-    ContentEntry e = getContentRootFor(url);
-    if (e == null) return;
-
-    if (!hasCollision(path)) {
-      e.addSourceFolder(url.getUrl(), testSource);
-    }
+    e.addSourceFolder(url.getUrl(), rootType);
   }
 
   public boolean hasRegisteredSourceSubfolder(File f) {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingConfigurable.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingConfigurable.java
index 9dbd14f..dd757ac 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingConfigurable.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingConfigurable.java
@@ -23,6 +23,7 @@
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.maven.execution.MavenJdkComboBox;
 import org.jetbrains.idea.maven.server.MavenServerManager;
 
 import javax.swing.*;
@@ -37,6 +38,7 @@
 
   private final JCheckBox myUseMaven3CheckBox;
   private final JTextField myEmbedderVMOptions;
+  private final MavenJdkComboBox myEmbedderJdk;
 
   public MavenImportingConfigurable(Project project) {
     myImportingSettings = MavenProjectsManager.getInstance(project).getImportingSettings();
@@ -50,12 +52,16 @@
     myUseMaven3CheckBox.setToolTipText("If this option is disabled maven 2 will be used");
 
     myEmbedderVMOptions = new JTextField(30);
+    myEmbedderJdk = new MavenJdkComboBox(null); // Embedder JDK is an application setting, not a project setting, so don't pass project
+    assert myEmbedderJdk.getProject() == null;
   }
 
   public JComponent createComponent() {
     final JPanel panel = mySettingsForm.getAdditionalSettingsPanel();
     panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
 
+    panel.add(Box.createVerticalStrut(5));
+
     JPanel useMaven3Panel = new JPanel(new BorderLayout());
     useMaven3Panel.add(myUseMaven3CheckBox, BorderLayout.WEST);
 
@@ -67,9 +73,21 @@
     vmOptionLabel.setLabelFor(myEmbedderVMOptions);
 
     embedderVMOptionPanel.add(myEmbedderVMOptions);
+
+    panel.add(Box.createVerticalStrut(3));
     panel.add(embedderVMOptionPanel);
 
+    JPanel embedderJdkPanel = new JPanel(new BorderLayout());
+    JLabel embedderJdkLabel = new JLabel("JDK for importer:");
+    embedderJdkLabel.setLabelFor(myEmbedderJdk);
+    embedderJdkPanel.add(embedderJdkLabel, BorderLayout.WEST);
+    embedderJdkPanel.add(myEmbedderJdk);
+
+    panel.add(Box.createVerticalStrut(3));
+    panel.add(embedderJdkPanel);
+
     for (final UnnamedConfigurable additionalConfigurable : myAdditionalConfigurables) {
+      panel.add(Box.createVerticalStrut(3));
       panel.add(additionalConfigurable.createComponent());
     }
     return mySettingsForm.createComponent();
@@ -96,6 +114,10 @@
       return true;
     }
 
+    if (!MavenServerManager.getInstance().getEmbedderJdk().equals(myEmbedderJdk.getSelectedValue())) {
+      return true;
+    }
+
     return mySettingsForm.isModified(myImportingSettings);
   }
 
@@ -104,6 +126,7 @@
 
     MavenServerManager.getInstance().setUseMaven2(!myUseMaven3CheckBox.isSelected());
     MavenServerManager.getInstance().setMavenEmbedderVMOptions(myEmbedderVMOptions.getText());
+    MavenServerManager.getInstance().setEmbedderJdk(myEmbedderJdk.getSelectedValue());
 
     for (final UnnamedConfigurable additionalConfigurable : myAdditionalConfigurables) {
       additionalConfigurable.apply();
@@ -115,6 +138,7 @@
 
     myUseMaven3CheckBox.setSelected(!MavenServerManager.getInstance().isUseMaven2());
     myEmbedderVMOptions.setText(MavenServerManager.getInstance().getMavenEmbedderVMOptions());
+    myEmbedderJdk.refreshData(MavenServerManager.getInstance().getEmbedderJdk());
 
     for (final UnnamedConfigurable additionalConfigurable : myAdditionalConfigurables) {
       additionalConfigurable.reset();
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java
index eda90d0..46579b3 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java
@@ -15,9 +15,13 @@
  */
 package org.jetbrains.idea.maven.project.actions;
 
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationType;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.idea.maven.project.MavenProjectsManager;
+import org.jetbrains.idea.maven.utils.MavenUtil;
 import org.jetbrains.idea.maven.utils.actions.MavenAction;
 import org.jetbrains.idea.maven.utils.actions.MavenActionUtil;
 
@@ -26,16 +30,35 @@
   protected boolean isAvailable(AnActionEvent e) {
     if (!super.isAvailable(e)) return false;
 
-    final DataContext context = e.getDataContext();
-    for (VirtualFile each : MavenActionUtil.getMavenProjectsFiles(context)) {
-      if (MavenActionUtil.getProjectsManager(context).isManagedFile(each)) return true;
-    }
-    return false;
+    return !MavenActionUtil.getMavenProjectsFiles(e.getDataContext()).isEmpty();
   }
 
   @Override
   public void actionPerformed(AnActionEvent e) {
     final DataContext context = e.getDataContext();
-    MavenActionUtil.getProjectsManager(context).removeManagedFiles(MavenActionUtil.getMavenProjectsFiles(context));
+
+    boolean hasManagedFiles = false;
+
+    MavenProjectsManager projectsManager = MavenActionUtil.getProjectsManager(context);
+
+    for (VirtualFile each : MavenActionUtil.getMavenProjectsFiles(context)) {
+      if (projectsManager.isManagedFile(each)) {
+        hasManagedFiles = true;
+        break;
+      }
+    }
+
+    if (!hasManagedFiles) {
+      Notification notification = new Notification(MavenUtil.MAVEN_NOTIFICATION_GROUP, "Failed to remove project",
+                                                   "You can not remove selected project because it's " +
+                                                   "imported as module of other project. You can ignore it. Only root project can be removed.",
+                                                   NotificationType.ERROR);
+
+      notification.setImportant(true);
+      notification.notify(MavenActionUtil.getProject(context));
+      return;
+    }
+
+    projectsManager.removeManagedFiles(MavenActionUtil.getMavenProjectsFiles(context));
   }
 }
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 863594f..774bc83 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
@@ -28,16 +28,14 @@
 import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.components.*;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.JavaSdkType;
-import com.intellij.openapi.projectRoots.JdkUtil;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.projectRoots.SimpleJavaSdkType;
+import com.intellij.openapi.projectRoots.*;
+import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
 import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.openapi.util.ShutDownTracker;
 import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.Alarm;
 import com.intellij.util.PathUtil;
-import com.intellij.util.SystemProperties;
 import com.intellij.util.containers.ContainerUtil;
 import gnu.trove.THashMap;
 import org.apache.lucene.search.Query;
@@ -45,6 +43,7 @@
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.maven.execution.MavenRunnerSettings;
 import org.jetbrains.idea.maven.model.MavenId;
 import org.jetbrains.idea.maven.model.MavenModel;
 import org.jetbrains.idea.maven.project.MavenConsole;
@@ -82,6 +81,7 @@
 
   private boolean useMaven2 = true;
   private String mavenEmbedderVMOptions = DEFAULT_VM_OPTIONS;
+  private String embedderJdk = MavenRunnerSettings.USE_INTERNAL_JAVA;
 
   public static MavenServerManager getInstance() {
     return ServiceManager.getService(MavenServerManager.class);
@@ -164,12 +164,34 @@
     myShutdownAlarm.cancelAllRequests();
   }
 
+  @NotNull
+  private Sdk getJdk() {
+    if (embedderJdk.equals(MavenRunnerSettings.USE_JAVA_HOME)) {
+      final String javaHome = System.getenv("JAVA_HOME");
+      if (!StringUtil.isEmptyOrSpaces(javaHome)) {
+        Sdk jdk = JavaSdk.getInstance().createJdk("", javaHome);
+        if (jdk != null) {
+          return jdk;
+        }
+      }
+    }
+
+    for (Sdk projectJdk : ProjectJdkTable.getInstance().getAllJdks()) {
+      if (projectJdk.getName().equals(embedderJdk)) {
+        return projectJdk;
+      }
+    }
+
+    // By default use internal jdk
+    return JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
+  }
+
   private RunProfileState createRunProfileState() {
     return new CommandLineState(null) {
       private SimpleJavaParameters createJavaParameters() throws ExecutionException {
         final SimpleJavaParameters params = new SimpleJavaParameters();
 
-        params.setJdk(new SimpleJavaSdkType().createJdk("tmp", SystemProperties.getJavaHome()));
+        params.setJdk(getJdk());
 
         params.setWorkingDirectory(PathManager.getBinPath());
         final List<String> classPath = new ArrayList<String>();
@@ -461,6 +483,18 @@
     }
   }
 
+  @NotNull
+  public String getEmbedderJdk() {
+    return embedderJdk;
+  }
+
+  public void setEmbedderJdk(@NotNull String embedderJdk) {
+    if (!this.embedderJdk.equals(embedderJdk)) {
+      this.embedderJdk = embedderJdk;
+      shutdown(false);
+    }
+  }
+
   @Nullable
   @Override
   public Element getState() {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java
index 0f865a7..3ca1876 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java
@@ -90,8 +90,8 @@
     myProject = project;
     myProgressIcon.suspend();
     myCaptionLabel.setText(
-      XmlStringUtil.wrapInHtml(StringUtil.escapeXml("enter keyword, pattern or class name to search by or Maven coordinates," +
-                                                    "i.e. 'springframework', 'Logger' or 'org.hibernate:hibernate-core:3.5.0.GA':")
+      XmlStringUtil.wrapInHtml(StringUtil.escapeXml("keyword or class name to search by or exact Maven coordinates, " +
+                                                    "i.e. 'spring', 'Logger' or 'ant:ant-junit:1.6.5'")
       ));
     myInfoLabel.setPreferredSize(
       new Dimension(myInfoLabel.getFontMetrics(myInfoLabel.getFont()).stringWidth("Showing: 1000"), myInfoLabel.getPreferredSize().height));
@@ -166,6 +166,7 @@
                                              ProjectBundle.message("file.chooser.directory.for.downloaded.libraries.description"), null,
                                              descriptor);
     updateInfoLabel();
+    setOKActionEnabled(false);
     init();
   }
 
@@ -276,6 +277,9 @@
             }
           }
           updateComboboxSelection(prevSize != myCoordinates.size());
+          // tooMany != null on last call, so enable OK action to let
+          // local maven repo a chance even if all remote services failed
+          setOKActionEnabled(!myRepositories.isEmpty() || tooMany != null);
           return true;
         }
       });
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/library/RepositoryAttachHandler.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/library/RepositoryAttachHandler.java
index 2ae2f00..81e63c3 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/library/RepositoryAttachHandler.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/library/RepositoryAttachHandler.java
@@ -222,7 +222,11 @@
                   tooManyResults = true;
                 }
                 else {
-                  resultList.add(Pair.create(artifact, map.get(artifact.getRepositoryId())));
+                  MavenRepositoryInfo repository = map.get(artifact.getRepositoryId());
+                  // if the artifact is provided by an unsupported repository just skip it
+                  // because it won't be resolved anyway
+                  if (repository == null) continue;
+                  resultList.add(Pair.create(artifact, repository));
                 }
               }
             }
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenArchetypesPanel.form b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenArchetypesPanel.form
new file mode 100644
index 0000000..d7bddc1
--- /dev/null
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenArchetypesPanel.form
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.maven.wizards.MavenArchetypesPanel">
+  <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="20" y="20" width="500" height="400"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <component id="15313" class="javax.swing.JCheckBox" binding="myUseArchetypeCheckBox" default-binding="true">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="Create from &amp;archetype"/>
+        </properties>
+      </component>
+      <hspacer id="15e41">
+        <constraints>
+          <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </hspacer>
+      <component id="f63a2" class="javax.swing.JButton" binding="myAddArchetypeButton">
+        <constraints>
+          <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="A&amp;dd Archetype..."/>
+        </properties>
+      </component>
+      <grid id="d872d" binding="myArchetypesPanel" layout-manager="CardLayout" hgap="0" vgap="0">
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="3" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children/>
+      </grid>
+      <scrollpane id="88686" class="com.intellij.ui.components.JBScrollPane" binding="myArchetypeDescriptionScrollPane">
+        <constraints>
+          <grid row="2" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="fb4a8" class="javax.swing.JTextArea" binding="myArchetypeDescriptionField">
+            <constraints/>
+            <properties/>
+          </component>
+        </children>
+      </scrollpane>
+    </children>
+  </grid>
+</form>
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenArchetypesPanel.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenArchetypesPanel.java
new file mode 100644
index 0000000..2c9fcca
--- /dev/null
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenArchetypesPanel.java
@@ -0,0 +1,324 @@
+/*
+ * 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.maven.wizards;
+
+import com.intellij.ide.wizard.StepAdapter;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.*;
+import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.containers.Convertor;
+import com.intellij.util.ui.AsyncProcessIcon;
+import com.intellij.util.ui.UIUtil;
+import com.intellij.util.ui.tree.TreeUtil;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.maven.indices.MavenIndicesManager;
+import org.jetbrains.idea.maven.model.MavenArchetype;
+
+import javax.swing.*;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Dmitry Avdeev
+ *         Date: 24.09.13
+ */
+public class MavenArchetypesPanel implements Disposable {
+
+  private JCheckBox myUseArchetypeCheckBox;
+  private JButton myAddArchetypeButton;
+  private JPanel myArchetypesPanel;
+  private final Tree myArchetypesTree;
+  private JScrollPane myArchetypeDescriptionScrollPane;
+  private JPanel myMainPanel;
+  private JTextArea myArchetypeDescriptionField;
+
+  private Object myCurrentUpdaterMarker;
+  private final AsyncProcessIcon myLoadingIcon = new AsyncProcessIcon.Big(getClass() + ".loading");
+
+  private boolean skipUpdateUI;
+  private final MavenModuleBuilder myBuilder;
+  @Nullable private final StepAdapter myStep;
+
+  public MavenArchetypesPanel(MavenModuleBuilder builder, @Nullable StepAdapter step) {
+    myBuilder = builder;
+    myStep = step;
+    Disposer.register(this, myLoadingIcon);
+
+    myArchetypesTree = new Tree();
+    myArchetypesTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
+    JScrollPane archetypesScrollPane = ScrollPaneFactory.createScrollPane(myArchetypesTree);
+
+    myArchetypesPanel.add(archetypesScrollPane, "archetypes");
+
+    JPanel loadingPanel = new JPanel(new GridBagLayout());
+    JPanel bp = new JPanel(new BorderLayout(10, 10));
+    bp.add(new JLabel("Loading archetype list..."), BorderLayout.NORTH);
+    bp.add(myLoadingIcon, BorderLayout.CENTER);
+
+    loadingPanel.add(bp, new GridBagConstraints());
+
+    myArchetypesPanel.add(ScrollPaneFactory.createScrollPane(loadingPanel), "loading");
+    ((CardLayout)myArchetypesPanel.getLayout()).show(myArchetypesPanel, "archetypes");
+
+
+    myUseArchetypeCheckBox.addActionListener(new ActionListener() {
+      @Override
+      public void actionPerformed(ActionEvent e) {
+        updateComponents();
+      }
+    });
+    myUseArchetypeCheckBox.addActionListener(new ActionListener() {
+      @Override
+      public void actionPerformed(ActionEvent e) {
+        archetypeMayBeChanged();
+      }
+    });
+
+    myAddArchetypeButton.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        doAddArchetype();
+      }
+    });
+
+    myArchetypesTree.setRootVisible(false);
+    myArchetypesTree.setShowsRootHandles(true);
+    myArchetypesTree.setCellRenderer(new MyRenderer());
+    myArchetypesTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+
+    myArchetypesTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
+      public void valueChanged(TreeSelectionEvent e) {
+        updateArchetypeDescription();
+        archetypeMayBeChanged();
+      }
+    });
+
+    new TreeSpeedSearch(myArchetypesTree, new Convertor<TreePath, String>() {
+      public String convert(TreePath path) {
+        MavenArchetype info = getArchetypeInfoFromPathComponent(path.getLastPathComponent());
+        return info.groupId + ":" + info.artifactId + ":" + info.version;
+      }
+    }).setComparator(new SpeedSearchComparator(false));
+
+    myArchetypeDescriptionField.setEditable(false);
+    myArchetypeDescriptionField.setBackground(UIUtil.getPanelBackground());
+
+    updateComponents();
+    requestUpdate();
+  }
+
+  public JPanel getMainPanel() {
+    return myMainPanel;
+  }
+
+  private void updateComponents() {
+    boolean archetypesEnabled = myUseArchetypeCheckBox.isSelected();
+    myAddArchetypeButton.setEnabled(archetypesEnabled);
+    myArchetypesTree.setEnabled(archetypesEnabled);
+    myArchetypesTree.setBackground(archetypesEnabled ? UIUtil.getListBackground() : UIUtil.getPanelBackground());
+
+  }
+
+  @Nullable
+  public MavenArchetype getSelectedArchetype() {
+    if (!myUseArchetypeCheckBox.isSelected() || myArchetypesTree.isSelectionEmpty()) return null;
+    return getArchetypeInfoFromPathComponent(myArchetypesTree.getLastSelectedPathComponent());
+  }
+
+  private static MavenArchetype getArchetypeInfoFromPathComponent(Object sel) {
+    return (MavenArchetype)((DefaultMutableTreeNode)sel).getUserObject();
+  }
+
+  private void updateArchetypeDescription() {
+    MavenArchetype sel = getSelectedArchetype();
+    String desc = sel == null ? null : sel.description;
+    if (StringUtil.isEmptyOrSpaces(desc)) {
+      myArchetypeDescriptionScrollPane.setVisible(false);
+    }
+    else {
+      myArchetypeDescriptionScrollPane.setVisible(true);
+      myArchetypeDescriptionField.setText(desc);
+    }
+  }
+
+  @Nullable
+  private static TreePath findNodePath(MavenArchetype object, TreeModel model, Object parent) {
+    for (int i = 0; i < model.getChildCount(parent); i++) {
+      DefaultMutableTreeNode each = (DefaultMutableTreeNode)model.getChild(parent, i);
+      if (each.getUserObject().equals(object)) return new TreePath(each.getPath());
+
+      TreePath result = findNodePath(object, model, each);
+      if (result != null) return result;
+    }
+    return null;
+  }
+
+  private static TreeNode groupAndSortArchetypes(Set<MavenArchetype> archetypes) {
+    List<MavenArchetype> list = new ArrayList<MavenArchetype>(archetypes);
+
+    Collections.sort(list, new Comparator<MavenArchetype>() {
+      public int compare(MavenArchetype o1, MavenArchetype o2) {
+        String key1 = o1.groupId + ":" + o1.artifactId;
+        String key2 = o2.groupId + ":" + o2.artifactId;
+
+        int result = key1.compareToIgnoreCase(key2);
+        if (result != 0) return result;
+
+        return o2.version.compareToIgnoreCase(o1.version);
+      }
+    });
+
+    Map<String, List<MavenArchetype>> map = new TreeMap<String, List<MavenArchetype>>();
+
+    for (MavenArchetype each : list) {
+      String key = each.groupId + ":" + each.artifactId;
+      List<MavenArchetype> versions = map.get(key);
+      if (versions == null) {
+        versions = new ArrayList<MavenArchetype>();
+        map.put(key, versions);
+      }
+      versions.add(each);
+    }
+
+    DefaultMutableTreeNode result = new DefaultMutableTreeNode("root", true);
+    for (List<MavenArchetype> each : map.values()) {
+      MavenArchetype eachArchetype = each.get(0);
+      DefaultMutableTreeNode node = new DefaultMutableTreeNode(eachArchetype, true);
+      for (MavenArchetype eachVersion : each) {
+        DefaultMutableTreeNode versionNode = new DefaultMutableTreeNode(eachVersion, false);
+        node.add(versionNode);
+      }
+      result.add(node);
+    }
+
+    return result;
+  }
+
+  public void requestUpdate() {
+
+    MavenArchetype selectedArch = getSelectedArchetype();
+    if (selectedArch == null) {
+      selectedArch = myBuilder.getArchetype();
+    }
+    if (selectedArch != null) myUseArchetypeCheckBox.setSelected(true);
+
+    if (myArchetypesTree.getRowCount() == 0) updateArchetypesList(selectedArch);
+  }
+
+  public void updateArchetypesList(final MavenArchetype selected) {
+    ApplicationManager.getApplication().assertIsDispatchThread();
+
+    myLoadingIcon.setBackground(myArchetypesTree.getBackground());
+
+    ((CardLayout)myArchetypesPanel.getLayout()).show(myArchetypesPanel, "loading");
+
+    final Object currentUpdaterMarker = new Object();
+    myCurrentUpdaterMarker = currentUpdaterMarker;
+
+    ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+      public void run() {
+        final Set<MavenArchetype> archetypes = MavenIndicesManager.getInstance().getArchetypes();
+
+        //noinspection SSBasedInspection
+        SwingUtilities.invokeLater(new Runnable() {
+          public void run() {
+            if (currentUpdaterMarker != myCurrentUpdaterMarker) return; // Other updater has been run.
+
+            ((CardLayout)myArchetypesPanel.getLayout()).show(myArchetypesPanel, "archetypes");
+
+            TreeNode root = groupAndSortArchetypes(archetypes);
+            TreeModel model = new DefaultTreeModel(root);
+            myArchetypesTree.setModel(model);
+
+            if (selected != null) {
+              TreePath path = findNodePath(selected, model, model.getRoot());
+              if (path != null) {
+                myArchetypesTree.expandPath(path.getParentPath());
+                TreeUtil.selectPath(myArchetypesTree, path, true);
+              }
+            }
+
+            updateArchetypeDescription();
+          }
+        });
+      }
+    });
+  }
+
+  private void archetypeMayBeChanged() {
+    MavenArchetype selectedArchetype = getSelectedArchetype();
+    if (((myBuilder.getArchetype() == null) != (selectedArchetype == null))) {
+      myBuilder.setArchetype(selectedArchetype);
+      skipUpdateUI = true;
+      try {
+        if (myStep != null) {
+          myStep.fireStateChanged();
+        }
+      }
+      finally {
+        skipUpdateUI = false;
+      }
+    }
+  }
+
+
+  private void doAddArchetype() {
+    MavenAddArchetypeDialog dialog = new MavenAddArchetypeDialog(myMainPanel);
+    dialog.show();
+    if (!dialog.isOK()) return;
+
+    MavenArchetype archetype = dialog.getArchetype();
+    MavenIndicesManager.getInstance().addArchetype(archetype);
+    updateArchetypesList(archetype);
+  }
+
+  @Override
+  public void dispose() {
+  }
+
+  private static class MyRenderer extends ColoredTreeCellRenderer {
+    public void customizeCellRenderer(JTree tree,
+                                      Object value,
+                                      boolean selected,
+                                      boolean expanded,
+                                      boolean leaf,
+                                      int row,
+                                      boolean hasFocus) {
+      Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
+      if (!(userObject instanceof MavenArchetype)) return;
+
+      MavenArchetype info = (MavenArchetype)userObject;
+
+      if (leaf) {
+        append(info.artifactId, SimpleTextAttributes.GRAY_ATTRIBUTES);
+        append(":" + info.version, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+      }
+      else {
+        append(info.groupId + ":", SimpleTextAttributes.GRAY_ATTRIBUTES);
+        append(info.artifactId, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+      }
+    }
+  }
+
+}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java
index 6133b9e..2d0752a 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java
@@ -20,6 +20,7 @@
 import com.intellij.ide.util.projectWizard.ModuleWizardStep;
 import com.intellij.ide.util.projectWizard.SourcePathsBuilder;
 import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.module.JavaModuleType;
 import com.intellij.openapi.module.ModuleType;
 import com.intellij.openapi.module.StdModuleTypes;
@@ -30,12 +31,14 @@
 import com.intellij.openapi.projectRoots.SdkTypeId;
 import com.intellij.openapi.roots.ModifiableRootModel;
 import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VirtualFile;
 import icons.MavenIcons;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.maven.model.MavenArchetype;
 import org.jetbrains.idea.maven.model.MavenId;
 import org.jetbrains.idea.maven.project.MavenEnvironmentForm;
@@ -122,7 +125,15 @@
   @Override
   public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) {
     return new ModuleWizardStep[]{
-      new MavenModuleWizardStep(wizardContext.getProject(), this, wizardContext),
+      new MavenModuleWizardStep(this, wizardContext, true),
+      new SelectPropertiesStep(wizardContext.getProject(), this)
+    };
+  }
+
+  @Override
+  public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider, boolean forNewWizard) {
+    return new ModuleWizardStep[]{
+      new MavenModuleWizardStep(this, wizardContext, !forNewWizard),
       new SelectPropertiesStep(wizardContext.getProject(), this)
     };
   }
@@ -219,4 +230,16 @@
   public String getGroupName() {
     return JavaModuleType.JAVA_GROUP;
   }
+
+  private MavenArchetypesPanel myPanel;
+
+  @Nullable
+  @Override
+  public JComponent getCustomOptionsPanel(Disposable parentDisposable) {
+    if (myPanel == null) {
+      myPanel = new MavenArchetypesPanel(this, null);
+      Disposer.register(parentDisposable, myPanel);
+    }
+    return myPanel.getMainPanel();
+  }
 }
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.form b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.form
index 1c47880..d666fa0 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.form
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.form
@@ -1,16 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.maven.wizards.MavenModuleWizardStep">
-  <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="8" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-    <margin top="8" left="8" bottom="8" right="8"/>
+  <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="5" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
     <constraints>
-      <xy x="20" y="20" width="380" height="386"/>
+      <xy x="20" y="20" width="529" height="386"/>
     </constraints>
     <properties/>
-    <border type="etched"/>
+    <border type="none"/>
     <children>
       <component id="ddae6" class="javax.swing.JLabel">
         <constraints>
-          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <text value="GroupId"/>
@@ -18,7 +18,7 @@
       </component>
       <component id="bbb74" class="javax.swing.JLabel">
         <constraints>
-          <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <text value="ArtifactId"/>
@@ -26,7 +26,7 @@
       </component>
       <component id="4eb56" class="javax.swing.JLabel">
         <constraints>
-          <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+          <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <text value="Version"/>
@@ -34,7 +34,7 @@
       </component>
       <component id="d7d25" class="javax.swing.JTextField" binding="myGroupIdField">
         <constraints>
-          <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+          <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
             <preferred-size width="150" height="-1"/>
           </grid>
         </constraints>
@@ -42,7 +42,7 @@
       </component>
       <component id="efb5e" class="javax.swing.JTextField" binding="myArtifactIdField">
         <constraints>
-          <grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+          <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
             <preferred-size width="150" height="-1"/>
           </grid>
         </constraints>
@@ -50,65 +50,15 @@
       </component>
       <component id="b1344" class="javax.swing.JTextField" binding="myVersionField">
         <constraints>
-          <grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+          <grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
             <preferred-size width="150" height="-1"/>
           </grid>
         </constraints>
         <properties/>
       </component>
-      <component id="cf9eb" class="javax.swing.JLabel" binding="myAggregatorLabel">
-        <constraints>
-          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties>
-          <text value="Add as module to"/>
-        </properties>
-      </component>
-      <component id="e24ab" class="javax.swing.JButton" binding="mySelectAggregator">
-        <constraints>
-          <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties>
-          <margin top="0" left="0" bottom="0" right="0"/>
-          <text value="..."/>
-        </properties>
-      </component>
-      <component id="ebeaf" class="javax.swing.JLabel" binding="myParentLabel">
-        <constraints>
-          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties>
-          <text value="Parent"/>
-        </properties>
-      </component>
-      <component id="376fa" class="javax.swing.JButton" binding="mySelectParent">
-        <constraints>
-          <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties>
-          <margin top="0" left="0" bottom="0" right="0"/>
-          <text value="..."/>
-        </properties>
-      </component>
-      <component id="6f435" class="javax.swing.JLabel" binding="myAggregatorNameLabel">
-        <constraints>
-          <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="4" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties>
-          <text value="Label"/>
-        </properties>
-      </component>
-      <component id="5f27e" class="javax.swing.JLabel" binding="myParentNameLabel">
-        <constraints>
-          <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="4" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties>
-          <text value="Label"/>
-        </properties>
-      </component>
       <component id="d0095" class="javax.swing.JCheckBox" binding="myInheritGroupIdCheckBox">
         <constraints>
-          <grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+          <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <text value="Inherit"/>
@@ -116,62 +66,80 @@
       </component>
       <component id="897ff" class="javax.swing.JCheckBox" binding="myInheritVersionCheckBox">
         <constraints>
-          <grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+          <grid row="3" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <text value="Inherit"/>
         </properties>
       </component>
-      <grid id="320a3" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-        <margin top="0" left="0" bottom="0" right="0"/>
+      <grid id="320a3" binding="myArchetypesPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
         <constraints>
-          <grid row="5" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties/>
-        <border type="none"/>
-        <children>
-          <component id="15313" class="javax.swing.JCheckBox" binding="myUseArchetypeCheckBox" default-binding="true">
-            <constraints>
-              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties>
-              <text value="Create from archetype"/>
-            </properties>
-          </component>
-          <component id="f63a2" class="javax.swing.JButton" binding="myAddArchetypeButton">
-            <constraints>
-              <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties>
-              <text value="Add archetype..."/>
-            </properties>
-          </component>
-        </children>
-      </grid>
-      <scrollpane id="88686" class="com.intellij.ui.components.JBScrollPane" binding="myArchetypeDescriptionScrollPane">
-        <constraints>
-          <grid row="7" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties/>
-        <border type="none"/>
-        <children>
-          <component id="28942" class="javax.swing.JTextArea" binding="myArchetypeDescriptionField">
-            <constraints/>
-            <properties>
-              <background swing-color="Panel.background"/>
-              <rows value="3"/>
-            </properties>
-          </component>
-        </children>
-      </scrollpane>
-      <grid id="d872d" binding="myArchetypesPanel" layout-manager="CardLayout" hgap="0" vgap="0">
-        <constraints>
-          <grid row="6" column="0" row-span="1" col-span="3" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+          <grid row="4" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties/>
         <border type="none"/>
         <children/>
       </grid>
+      <grid id="102d8" binding="myAddToPanel" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="cf9eb" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text value="Add as module to"/>
+            </properties>
+          </component>
+          <component id="6f435" class="javax.swing.JLabel" binding="myAggregatorNameLabel">
+            <constraints>
+              <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="4" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text value="Label"/>
+            </properties>
+          </component>
+          <component id="e24ab" class="javax.swing.JButton" binding="mySelectAggregator">
+            <constraints>
+              <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <margin top="0" left="0" bottom="0" right="0"/>
+              <text value="..."/>
+            </properties>
+          </component>
+          <component id="ebeaf" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text value="Parent"/>
+            </properties>
+          </component>
+          <component id="5f27e" class="javax.swing.JLabel" binding="myParentNameLabel">
+            <constraints>
+              <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="4" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text value="Label"/>
+            </properties>
+          </component>
+          <component id="376fa" class="javax.swing.JButton" binding="mySelectParent">
+            <constraints>
+              <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <margin top="0" left="0" bottom="0" right="0"/>
+              <text value="..."/>
+            </properties>
+          </component>
+        </children>
+      </grid>
     </children>
   </grid>
 </form>
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.java
index 3f60506..ede845ae 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.java
@@ -18,19 +18,11 @@
 import com.intellij.ide.util.PropertiesComponent;
 import com.intellij.ide.util.projectWizard.ModuleWizardStep;
 import com.intellij.ide.util.projectWizard.WizardContext;
-import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.IconLoader;
 import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.ui.*;
-import com.intellij.ui.treeStructure.Tree;
-import com.intellij.util.containers.Convertor;
-import com.intellij.util.ui.AsyncProcessIcon;
-import com.intellij.util.ui.UIUtil;
-import com.intellij.util.ui.tree.TreeUtil;
 import org.jetbrains.annotations.Nullable;
-import org.jetbrains.idea.maven.indices.MavenIndicesManager;
 import org.jetbrains.idea.maven.model.MavenArchetype;
 import org.jetbrains.idea.maven.model.MavenId;
 import org.jetbrains.idea.maven.navigator.SelectMavenProjectDialog;
@@ -38,14 +30,9 @@
 import org.jetbrains.idea.maven.project.MavenProjectsManager;
 
 import javax.swing.*;
-import javax.swing.event.TreeSelectionEvent;
-import javax.swing.event.TreeSelectionListener;
-import javax.swing.tree.*;
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.util.*;
-import java.util.List;
 
 public class MavenModuleWizardStep extends ModuleWizardStep {
   private static final Icon WIZARD_ICON = IconLoader.getIcon("/addmodulewizard.png");
@@ -67,11 +54,8 @@
 
   private JPanel myMainPanel;
 
-  private JLabel myAggregatorLabel;
   private JLabel myAggregatorNameLabel;
   private JButton mySelectAggregator;
-
-  private JLabel myParentLabel;
   private JLabel myParentNameLabel;
   private JButton mySelectParent;
 
@@ -81,45 +65,28 @@
   private JTextField myVersionField;
   private JCheckBox myInheritVersionCheckBox;
 
-  private JCheckBox myUseArchetypeCheckBox;
-  private JButton myAddArchetypeButton;
-  private JScrollPane myArchetypesScrollPane;
   private JPanel myArchetypesPanel;
-  private Tree myArchetypesTree;
-  private JScrollPane myArchetypeDescriptionScrollPane;
-  private JTextArea myArchetypeDescriptionField;
+  private JPanel myAddToPanel;
 
-  private Object myCurrentUpdaterMarker;
-  private final AsyncProcessIcon myLoadingIcon = new AsyncProcessIcon.Big(getClass() + ".loading");
+  @Nullable
+  private final MavenArchetypesPanel myArchetypes;
 
-  private boolean skipUpdateUI;
-
-  public MavenModuleWizardStep(@Nullable Project project, MavenModuleBuilder builder, WizardContext context) {
-    myProjectOrNull = project;
+  public MavenModuleWizardStep(MavenModuleBuilder builder, WizardContext context, boolean includeArtifacts) {
+    myProjectOrNull = context.getProject();
     myBuilder = builder;
     myContext = context;
-
+    if (includeArtifacts) {
+      myArchetypes = new MavenArchetypesPanel(builder, this);
+      myArchetypesPanel.add(myArchetypes.getMainPanel(), BorderLayout.CENTER);
+    }
+    else {
+      myArchetypes = null;
+    }
     initComponents();
     loadSettings();
   }
 
   private void initComponents() {
-    myArchetypesTree = new Tree();
-    myArchetypesTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
-    myArchetypesScrollPane = ScrollPaneFactory.createScrollPane(myArchetypesTree);
-
-    myArchetypesPanel.add(myArchetypesScrollPane, "archetypes");
-
-    JPanel loadingPanel = new JPanel(new GridBagLayout());
-    JPanel bp = new JPanel(new BorderLayout(10, 10));
-    bp.add(new JLabel("Loading archetype list..."), BorderLayout.NORTH);
-    bp.add(myLoadingIcon, BorderLayout.CENTER);
-
-    loadingPanel.add(bp, new GridBagConstraints());
-
-    myArchetypesPanel.add(ScrollPaneFactory.createScrollPane(loadingPanel), "loading");
-    ((CardLayout)myArchetypesPanel.getLayout()).show(myArchetypesPanel, "archetypes");
-
 
     mySelectAggregator.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
@@ -142,56 +109,6 @@
     };
     myInheritGroupIdCheckBox.addActionListener(updatingListener);
     myInheritVersionCheckBox.addActionListener(updatingListener);
-
-    myUseArchetypeCheckBox.addActionListener(updatingListener);
-    myUseArchetypeCheckBox.addActionListener(new ActionListener() {
-      @Override
-      public void actionPerformed(ActionEvent e) {
-        archetypeMayBeChanged();
-      }
-    });
-
-    myAddArchetypeButton.addActionListener(new ActionListener() {
-      public void actionPerformed(ActionEvent e) {
-        doAddArchetype();
-      }
-    });
-
-    myArchetypesTree.setRootVisible(false);
-    myArchetypesTree.setShowsRootHandles(true);
-    myArchetypesTree.setCellRenderer(new MyRenderer());
-    myArchetypesTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
-
-    myArchetypesTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
-      public void valueChanged(TreeSelectionEvent e) {
-        updateArchetypeDescription();
-        archetypeMayBeChanged();
-      }
-    });
-
-    new TreeSpeedSearch(myArchetypesTree, new Convertor<TreePath, String>() {
-      public String convert(TreePath path) {
-        MavenArchetype info = getArchetypeInfoFromPathComponent(path.getLastPathComponent());
-        return info.groupId + ":" + info.artifactId + ":" + info.version;
-      }
-    }).setComparator(new SpeedSearchComparator(false));
-
-    myArchetypeDescriptionField.setEditable(false);
-    myArchetypeDescriptionField.setBackground(UIUtil.getPanelBackground());
-  }
-
-  private void archetypeMayBeChanged() {
-    MavenArchetype selectedArchetype = getSelectedArchetype();
-    if (((myBuilder.getArchetype() == null) != (selectedArchetype == null))) {
-      myBuilder.setArchetype(selectedArchetype);
-      skipUpdateUI = true;
-      try {
-        fireStateChanged();
-      }
-      finally {
-        skipUpdateUI = false;
-      }
-    }
   }
 
   @Override
@@ -208,27 +125,11 @@
     return d.getResult();
   }
 
-  private void doAddArchetype() {
-    MavenAddArchetypeDialog dialog = new MavenAddArchetypeDialog(myMainPanel);
-    dialog.show();
-    if (!dialog.isOK()) return;
-
-    MavenArchetype archetype = dialog.getArchetype();
-    MavenIndicesManager.getInstance().addArchetype(archetype);
-    updateArchetypesList(archetype);
-  }
-
   @Override
   public void onStepLeaving() {
     saveSettings();
   }
 
-  @Override
-  public void disposeUIResources() {
-    myLoadingIcon.dispose();
-    super.disposeUIResources();
-  }
-
   private void loadSettings() {
     myBuilder.setInheritedOptions(getSavedValue(INHERIT_GROUP_ID_KEY, true),
                                   getSavedValue(INHERIT_VERSION_KEY, true));
@@ -248,13 +149,15 @@
     saveValue(INHERIT_GROUP_ID_KEY, myInheritGroupIdCheckBox.isSelected());
     saveValue(INHERIT_VERSION_KEY, myInheritVersionCheckBox.isSelected());
 
-    MavenArchetype arch = getSelectedArchetype();
-    saveValue(ARCHETYPE_GROUP_ID_KEY, arch == null ? null : arch.groupId);
-    saveValue(ARCHETYPE_ARTIFACT_ID_KEY, arch == null ? null : arch.artifactId);
-    saveValue(ARCHETYPE_VERSION_KEY, arch == null ? null : arch.version);
+    if (myArchetypes != null) {
+      MavenArchetype arch = myArchetypes.getSelectedArchetype();
+      saveValue(ARCHETYPE_GROUP_ID_KEY, arch == null ? null : arch.groupId);
+      saveValue(ARCHETYPE_ARTIFACT_ID_KEY, arch == null ? null : arch.artifactId);
+      saveValue(ARCHETYPE_VERSION_KEY, arch == null ? null : arch.version);
+    }
   }
 
-  private boolean getSavedValue(String key, boolean defaultValue) {
+  private static boolean getSavedValue(String key, boolean defaultValue) {
     return getSavedValue(key, String.valueOf(defaultValue)).equals(String.valueOf(true));
   }
 
@@ -263,7 +166,7 @@
     return value == null ? defaultValue : value;
   }
 
-  private void saveValue(String key, boolean value) {
+  private static void saveValue(String key, boolean value) {
     saveValue(key, String.valueOf(value));
   }
 
@@ -296,8 +199,6 @@
   @Override
   public void updateStep() {
 
-    if (skipUpdateUI) return;
-
     if (isMavenizedProject()) {
       MavenProject parent = myBuilder.findPotentialParentProject(myProjectOrNull);
       myAggregator = parent;
@@ -320,135 +221,18 @@
     myInheritGroupIdCheckBox.setSelected(myBuilder.isInheritGroupId());
     myInheritVersionCheckBox.setSelected(myBuilder.isInheritVersion());
 
-    MavenArchetype selectedArch = getSelectedArchetype();
-    if (selectedArch == null) {
-      selectedArch = myBuilder.getArchetype();
+    if (myArchetypes != null) {
+      myArchetypes.requestUpdate();
     }
-    if (selectedArch != null) myUseArchetypeCheckBox.setSelected(true);
-
-    if (myArchetypesTree.getRowCount() == 0) updateArchetypesList(selectedArch);
     updateComponents();
   }
 
-  private void updateArchetypesList(final MavenArchetype selected) {
-    ApplicationManager.getApplication().assertIsDispatchThread();
-
-    myLoadingIcon.setBackground(myArchetypesTree.getBackground());
-
-    ((CardLayout)myArchetypesPanel.getLayout()).show(myArchetypesPanel, "loading");
-
-    final Object currentUpdaterMarker = new Object();
-    myCurrentUpdaterMarker = currentUpdaterMarker;
-
-    ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
-      public void run() {
-        final Set<MavenArchetype> archetypes = MavenIndicesManager.getInstance().getArchetypes();
-
-        SwingUtilities.invokeLater(new Runnable() {
-          public void run() {
-            if (currentUpdaterMarker != myCurrentUpdaterMarker) return; // Other updater has been run.
-
-            ((CardLayout)myArchetypesPanel.getLayout()).show(myArchetypesPanel, "archetypes");
-
-            TreeNode root = groupAndSortArchetypes(archetypes);
-            TreeModel model = new DefaultTreeModel(root);
-            myArchetypesTree.setModel(model);
-
-            if (selected != null) {
-              TreePath path = findNodePath(selected, model, model.getRoot());
-              if (path != null) {
-                myArchetypesTree.expandPath(path.getParentPath());
-                TreeUtil.selectPath(myArchetypesTree, path, true);
-              }
-            }
-
-            updateArchetypeDescription();
-          }
-        });
-      }
-    });
-  }
-
-  private void updateArchetypeDescription() {
-    MavenArchetype sel = getSelectedArchetype();
-    String desc = sel == null ? null : sel.description;
-    if (StringUtil.isEmptyOrSpaces(desc)) {
-      myArchetypeDescriptionScrollPane.setVisible(false);
-    }
-    else {
-      myArchetypeDescriptionScrollPane.setVisible(true);
-      myArchetypeDescriptionField.setText(desc);
-    }
-    myMainPanel.revalidate();
-  }
-
-  @Nullable
-  private static TreePath findNodePath(MavenArchetype object, TreeModel model, Object parent) {
-    for (int i = 0; i < model.getChildCount(parent); i++) {
-      DefaultMutableTreeNode each = (DefaultMutableTreeNode)model.getChild(parent, i);
-      if (each.getUserObject().equals(object)) return new TreePath(each.getPath());
-
-      TreePath result = findNodePath(object, model, each);
-      if (result != null) return result;
-    }
-    return null;
-  }
-
-  private static TreeNode groupAndSortArchetypes(Set<MavenArchetype> archetypes) {
-    List<MavenArchetype> list = new ArrayList<MavenArchetype>(archetypes);
-
-    Collections.sort(list, new Comparator<MavenArchetype>() {
-      public int compare(MavenArchetype o1, MavenArchetype o2) {
-        String key1 = o1.groupId + ":" + o1.artifactId;
-        String key2 = o2.groupId + ":" + o2.artifactId;
-
-        int result = key1.compareToIgnoreCase(key2);
-        if (result != 0) return result;
-
-        return o2.version.compareToIgnoreCase(o1.version);
-      }
-    });
-
-    Map<String, List<MavenArchetype>> map = new TreeMap<String, List<MavenArchetype>>();
-
-    for (MavenArchetype each : list) {
-      String key = each.groupId + ":" + each.artifactId;
-      List<MavenArchetype> versions = map.get(key);
-      if (versions == null) {
-        versions = new ArrayList<MavenArchetype>();
-        map.put(key, versions);
-      }
-      versions.add(each);
-    }
-
-    DefaultMutableTreeNode result = new DefaultMutableTreeNode("root", true);
-    for (List<MavenArchetype> each : map.values()) {
-      MavenArchetype eachArchetype = each.get(0);
-      DefaultMutableTreeNode node = new DefaultMutableTreeNode(eachArchetype, true);
-      for (MavenArchetype eachVersion : each) {
-        DefaultMutableTreeNode versionNode = new DefaultMutableTreeNode(eachVersion, false);
-        node.add(versionNode);
-      }
-      result.add(node);
-    }
-
-    return result;
-  }
-
   private boolean isMavenizedProject() {
     return myProjectOrNull != null && MavenProjectsManager.getInstance(myProjectOrNull).isMavenizedProject();
   }
 
   private void updateComponents() {
-    if (!isMavenizedProject()) {
-      myAggregatorLabel.setEnabled(false);
-      myAggregatorNameLabel.setEnabled(false);
-      mySelectAggregator.setEnabled(false);
-
-      myParentLabel.setEnabled(false);
-      myParentNameLabel.setEnabled(false);
-      mySelectParent.setEnabled(false);
-    }
+    myAddToPanel.setVisible(isMavenizedProject());
     myAggregatorNameLabel.setText(formatProjectString(myAggregator));
     myParentNameLabel.setText(formatProjectString(myParent));
 
@@ -476,11 +260,6 @@
       myInheritGroupIdCheckBox.setEnabled(true);
       myInheritVersionCheckBox.setEnabled(true);
     }
-
-    boolean archetypesEnabled = myUseArchetypeCheckBox.isSelected();
-    myAddArchetypeButton.setEnabled(archetypesEnabled);
-    myArchetypesTree.setEnabled(archetypesEnabled);
-    myArchetypesTree.setBackground(archetypesEnabled ? UIUtil.getListBackground() : UIUtil.getPanelBackground());
   }
 
   private static String formatProjectString(MavenProject project) {
@@ -500,17 +279,9 @@
     myBuilder.setInheritedOptions(myInheritGroupIdCheckBox.isSelected(),
                                   myInheritVersionCheckBox.isSelected());
 
-    myBuilder.setArchetype(getSelectedArchetype());
-  }
-
-  @Nullable
-  private MavenArchetype getSelectedArchetype() {
-    if (!myUseArchetypeCheckBox.isSelected() || myArchetypesTree.isSelectionEmpty()) return null;
-    return getArchetypeInfoFromPathComponent(myArchetypesTree.getLastSelectedPathComponent());
-  }
-
-  private static MavenArchetype getArchetypeInfoFromPathComponent(Object sel) {
-    return (MavenArchetype)((DefaultMutableTreeNode)sel).getUserObject();
+    if (myArchetypes != null) {
+      myBuilder.setArchetype(myArchetypes.getSelectedArchetype());
+    }
   }
 
   @Override
@@ -518,30 +289,6 @@
     return WIZARD_ICON;
   }
 
-  private static class MyRenderer extends ColoredTreeCellRenderer {
-    public void customizeCellRenderer(JTree tree,
-                                      Object value,
-                                      boolean selected,
-                                      boolean expanded,
-                                      boolean leaf,
-                                      int row,
-                                      boolean hasFocus) {
-      Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
-      if (!(userObject instanceof MavenArchetype)) return;
-
-      MavenArchetype info = (MavenArchetype)userObject;
-
-      if (leaf) {
-        append(info.artifactId, SimpleTextAttributes.GRAY_ATTRIBUTES);
-        append(":" + info.version, SimpleTextAttributes.REGULAR_ATTRIBUTES);
-      }
-      else {
-        append(info.groupId + ":", SimpleTextAttributes.GRAY_ATTRIBUTES);
-        append(info.artifactId, SimpleTextAttributes.REGULAR_ATTRIBUTES);
-      }
-    }
-  }
-
   @Override
   public String getHelpId() {
     return "reference.dialogs.new.project.fromScratch.maven";
diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml
index eb65fe8..491fad1 100644
--- a/plugins/maven/src/main/resources/META-INF/plugin.xml
+++ b/plugins/maven/src/main/resources/META-INF/plugin.xml
@@ -88,6 +88,9 @@
     <localInspection language="XML" shortName="MavenDuplicateDependenciesInspection" bundle="MavenDomBundle" key="inspection.duplicate.dependencies.name"
                      groupKey="inspection.group" enabledByDefault="true" level="WARNING"
                      implementationClass="org.jetbrains.idea.maven.dom.inspections.MavenDuplicateDependenciesInspection"/>
+    <localInspection language="XML" shortName="MavenDuplicatePluginInspection" bundle="MavenDomBundle" key="inspection.duplicate.plugin.declaration"
+                     groupKey="inspection.group" enabledByDefault="true" level="WARNING"
+                     implementationClass="org.jetbrains.idea.maven.dom.inspections.MavenDuplicatePluginInspection"/>
     <localInspection language="XML" shortName="MavenRedundantGroupId" bundle="MavenDomBundle" key="inspection.redundant.groupId.name"
                      groupKey="inspection.group" enabledByDefault="true" level="WARNING"
                      implementationClass="org.jetbrains.idea.maven.dom.inspections.MavenRedundantGroupIdInspection"/>
diff --git a/plugins/maven/src/main/resources/MavenDomBundle.properties b/plugins/maven/src/main/resources/MavenDomBundle.properties
index 2b10fb8..d840ea4 100644
--- a/plugins/maven/src/main/resources/MavenDomBundle.properties
+++ b/plugins/maven/src/main/resources/MavenDomBundle.properties
@@ -35,5 +35,6 @@
 refactoring.introduce.property=Introduce Property
 choose.project=Choose project
 inspection.duplicate.dependencies.name=Duplicate Dependencies
+inspection.duplicate.plugin.declaration=Duplicate plugin declaration
 MavenDuplicateDependenciesInspection.has.duplicates=<html><body>Dependency is duplicated in file(s): {0} </body></html>
 inspection.redundant.groupId.name=Redundant groupId
\ No newline at end of file
diff --git a/plugins/maven/src/main/resources/RunnerBundle.properties b/plugins/maven/src/main/resources/RunnerBundle.properties
index a12ded3..4ebc070 100644
--- a/plugins/maven/src/main/resources/RunnerBundle.properties
+++ b/plugins/maven/src/main/resources/RunnerBundle.properties
@@ -28,8 +28,8 @@
 maven.select.maven.home.directory=Select Maven home directory
 maven.running=Running
 
-maven.java.internal=Internal JRE
-maven.java.home.env=Use JAVA_HOME
+maven.java.internal=<html>Internal JRE <font color=gray>({0})</font></html>
+maven.java.home.env=<html>Use JAVA_HOME <font color=gray>({0})</font></html>
 maven.java.home.undefined=JAVA_HOME environment variable not defined
 maven.java.home.invalid=JAVA_HOME environment vairable does not point to valid JRE ({0})
 maven.java.not.found=Cannot find JRE ''{0}''
diff --git a/plugins/maven/src/main/resources/inspectionDescriptions/MavenDuplicatePluginInspection.html b/plugins/maven/src/main/resources/inspectionDescriptions/MavenDuplicatePluginInspection.html
new file mode 100644
index 0000000..0fd90db
--- /dev/null
+++ b/plugins/maven/src/main/resources/inspectionDescriptions/MavenDuplicatePluginInspection.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<span style="font-family: verdana,serif; font-size: smaller;">This inspection checks duplication of plugin declaration in pom.xml</span>
+</body>
+</html>
\ No newline at end of file
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 c75a604..94ca15b 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
@@ -48,9 +48,13 @@
 import com.intellij.util.concurrency.Semaphore;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.maven.execution.*;
 import org.jetbrains.idea.maven.model.MavenArtifact;
 import org.jetbrains.idea.maven.project.*;
+import org.jetbrains.jps.model.java.JavaResourceRootType;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 
 import javax.swing.*;
 import java.io.File;
@@ -115,36 +119,42 @@
   }
 
   protected void assertSources(String moduleName, String... expectedSources) {
-    doAssertContentFolders(moduleName, true, false, expectedSources);
+    doAssertContentFolders(moduleName, JavaSourceRootType.SOURCE, expectedSources);
+  }
+
+  protected void assertResources(String moduleName, String... expectedSources) {
+    doAssertContentFolders(moduleName, JavaResourceRootType.RESOURCE, expectedSources);
   }
 
   protected void assertTestSources(String moduleName, String... expectedSources) {
-    doAssertContentFolders(moduleName, true, true, expectedSources);
+    doAssertContentFolders(moduleName, JavaSourceRootType.TEST_SOURCE, expectedSources);
+  }
+
+  protected void assertTestResources(String moduleName, String... expectedSources) {
+    doAssertContentFolders(moduleName, JavaResourceRootType.TEST_RESOURCE, expectedSources);
   }
 
   protected void assertExcludes(String moduleName, String... expectedExcludes) {
-    doAssertContentFolders(moduleName, false, false, expectedExcludes);
+    doAssertContentFolders(moduleName, null, expectedExcludes);
   }
 
   protected void assertContentRootExcludes(String moduleName, String contentRoot, String... expectedExcudes) {
-    doAssertContentFolders(getContentRoot(moduleName, contentRoot), false, false, expectedExcudes);
+    doAssertContentFolders(getContentRoot(moduleName, contentRoot), null, expectedExcudes);
   }
 
-  private void doAssertContentFolders(String moduleName, boolean isSource, boolean isTest, String... expected) {
-    doAssertContentFolders(getContentRoot(moduleName), isSource, isTest, expected);
+  private void doAssertContentFolders(String moduleName, @Nullable JpsModuleSourceRootType<?> rootType, String... expected) {
+    doAssertContentFolders(getContentRoot(moduleName), rootType, expected);
   }
 
-  private static void doAssertContentFolders(ContentEntry e, boolean isSource, boolean isTest, String... expected) {
+  private static void doAssertContentFolders(ContentEntry e, @Nullable JpsModuleSourceRootType<?> rootType, String... expected) {
     List<String> actual = new ArrayList<String>();
-    for (ContentFolder f : isSource ? e.getSourceFolders() : e.getExcludeFolders()) {
-      if (isSource && (isTest != ((SourceFolder)f).isTestSource())) continue;
-
+    for (ContentFolder f : rootType != null ? e.getSourceFolders(rootType) : Arrays.asList(e.getExcludeFolders())) {
       String rootUrl = e.getUrl();
       String folderUrl = f.getUrl();
 
       if (folderUrl.startsWith(rootUrl)) {
-        int lenght = rootUrl.length() + 1;
-        folderUrl = folderUrl.substring(Math.min(lenght, folderUrl.length()));
+        int length = rootUrl.length() + 1;
+        folderUrl = folderUrl.substring(Math.min(length, folderUrl.length()));
       }
 
       actual.add(folderUrl);
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java
index 93cad46..7ef085a 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java
@@ -29,23 +29,12 @@
 
 import java.io.File;
 
-public abstract class ResourceCopyingTest extends MavenImportingTestCase {
-
-  public static class IdeaModeTest extends ResourceCopyingTest {
-    @Override
-    protected boolean useJps() {
-      return false;
-    }
+public class ResourceCopyingTest extends MavenImportingTestCase {
+  @Override
+  protected boolean useJps() {
+    return true;
   }
 
-  public static class JpsModeTest extends ResourceCopyingTest {
-    @Override
-    protected boolean useJps() {
-      return true;
-    }
-  }
-
-
   @Override
   protected void setUpInWriteAction() throws Exception {
     super.setUpInWriteAction();
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutionTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutionTest.java
index 9752ee7..4a0f5e2 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutionTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutionTest.java
@@ -95,8 +95,9 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources/foo");
+    assertResources("project",
+                    "src/main/resources");
 
     assertExcludes("project",
                    "target/bar",
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/FoldersImportingTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/FoldersImportingTest.java
index fa08576..fd88870 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/FoldersImportingTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/FoldersImportingTest.java
@@ -16,14 +16,13 @@
 package org.jetbrains.idea.maven.importing;
 
 import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.roots.CompilerModuleExtension;
-import com.intellij.openapi.roots.ModuleRootManager;
 import com.intellij.openapi.vfs.VirtualFile;
 import org.jetbrains.idea.maven.MavenCustomRepositoryHelper;
 import org.jetbrains.idea.maven.MavenImportingTestCase;
 import org.jetbrains.idea.maven.project.MavenImportingSettings;
 import org.jetbrains.idea.maven.project.MavenProjectsManager;
 import org.jetbrains.idea.maven.utils.Path;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
 
 import java.io.File;
 import java.io.IOException;
@@ -39,8 +38,10 @@
     assertModules("project");
     assertContentRoots("project", getProjectPath());
 
-    assertSources("project", "src/main/java", "src/main/resources");
-    assertTestSources("project", "src/test/java", "src/test/resources");
+    assertSources("project", "src/main/java");
+    assertResources("project", "src/main/resources");
+    assertTestSources("project", "src/test/java");
+    assertTestResources("project", "src/test/resources");
   }
 
   public void testInvalidProjectHasContentRoot() throws Exception {
@@ -70,8 +71,10 @@
                   "</build>");
 
     assertModules("project");
-    assertSources("project", "src/main/java", "src/main/resources");
-    assertTestSources("project", "src/test/java", "src/test/resources");
+    assertSources("project", "src/main/java");
+    assertResources("project", "src/main/resources");
+    assertTestSources("project", "src/test/java");
+    assertTestResources("project", "src/test/resources");
   }
 
   public void testDoesNotResetUserFolders() throws Exception {
@@ -87,7 +90,7 @@
         MavenRootModelAdapter adapter = new MavenRootModelAdapter(myProjectsTree.findProject(myProjectPom),
                                                                   getModule("project"),
                                                                   new MavenDefaultModifiableModelsProvider(myProject));
-        adapter.addSourceFolder(dir1.getPath(), false);
+        adapter.addSourceFolder(dir1.getPath(), JavaSourceRootType.SOURCE);
         adapter.addExcludedFolder(dir2.getPath());
         adapter.getRootModel().commit();
       }
@@ -115,7 +118,8 @@
                   "<artifactId>project</artifactId>" +
                   "<version>1</version>");
 
-    assertSources("project", "src/main/java", "src/main/resources");
+    assertSources("project", "src/main/java");
+    assertResources("project", "src/main/resources");
 
     importProject("<groupId>test</groupId>" +
                   "<artifactId>project</artifactId>" +
@@ -131,7 +135,8 @@
                   "<artifactId>project</artifactId>" +
                   "<version>1</version>");
 
-    assertSources("project", "src/main/java", "src/main/resources");
+    assertSources("project", "src/main/java");
+    assertResources("project", "src/main/resources");
   }
 
   public void testSourceFoldersOnReimport() throws Exception {
@@ -195,8 +200,10 @@
     assertModules("project");
     assertContentRoots("project", getProjectPath());
 
-    assertSources("project", "src", "res1", "res2");
-    assertTestSources("project", "test", "testRes1", "testRes2");
+    assertSources("project", "src");
+    assertResources("project", "res1", "res2");
+    assertTestSources("project", "test");
+    assertTestResources("project", "testRes1", "testRes2");
   }
 
   public void testDoNotAddCustomSourceFoldersOutsideOfContentRoot() throws Exception {
@@ -275,7 +282,8 @@
     resolveFoldersAndImport();
     assertModules("project");
 
-    assertSources("project", "src/main/java", "src/main/resources", "src1", "src2");
+    assertSources("project", "src/main/java", "src1", "src2");
+    assertResources("project", "src/main/resources");
   }
 
   public void testPluginSourceDuringGenerateResourcesPhase() throws Exception {
@@ -312,7 +320,8 @@
     resolveFoldersAndImport();
     assertModules("project");
 
-    assertSources("project", "extraResources", "src/main/java", "src/main/resources");
+    assertSources("project", "src/main/java", "extraResources");
+    assertResources("project", "src/main/resources");
   }
 
   public void testPluginTestSourcesDuringGenerateTestResourcesPhase() throws Exception {
@@ -351,7 +360,8 @@
     resolveFoldersAndImport();
     assertModules("project");
 
-    assertTestSources("project", "extraTestResources", "src/test/java", "src/test/resources");
+    assertTestSources("project", "src/test/java", "extraTestResources");
+    assertTestResources("project", "src/test/resources");
   }
 
   public void testPluginSourcesWithRelativePath() throws Exception {
@@ -388,7 +398,8 @@
     resolveFoldersAndImport();
     assertModules("project");
 
-    assertSources("project", "src/main/java", "src/main/resources", "relativePath");
+    assertSources("project", "src/main/java", "relativePath");
+    assertResources("project", "src/main/resources");
   }
 
   public void testPluginSourcesWithVariables() throws Exception {
@@ -425,7 +436,8 @@
     resolveFoldersAndImport();
     assertModules("project");
 
-    assertSources("project", "src/main/java", "src/main/resources", "target/src");
+    assertSources("project", "src/main/java", "target/src");
+    assertResources("project", "src/main/resources");
   }
 
   public void testPluginSourcesWithIntermoduleDependency() throws Exception {
@@ -487,7 +499,8 @@
     assertModules("project", "m1", "m2");
 
     resolveFoldersAndImport();
-    assertSources("m1", "src/main/java", "src/main/resources", "src/foo");
+    assertSources("m1", "src/main/java", "src/foo");
+    assertResources("m1", "src/main/resources");
   }
 
   public void testDownloadingNecessaryPlugins() throws Exception {
@@ -545,15 +558,15 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources/src1",
                   "target/generated-sources/src2");
+    assertResources("project", "src/main/resources");
 
     assertTestSources("project",
                       "src/test/java",
-                      "src/test/resources",
                       "target/generated-test-sources/test1",
                       "target/generated-test-sources/test2");
+    assertTestResources("project", "src/test/resources");
   }
 
   public void testAddingExistingGeneratedSources2() throws Exception {
@@ -567,8 +580,8 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources");
+    assertResources("project", "src/main/resources");
   }
 
   public void testAddingExistingGeneratedSources3() throws Exception {
@@ -585,8 +598,8 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources/com");
+    assertResources("project", "src/main/resources");
   }
 
   public void testOverrideAnnotationSources() throws Exception {
@@ -604,8 +617,8 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources");
+    assertResources("project", "src/main/resources");
   }
 
   public void testIgnoreGeneratedSources() throws Exception {
@@ -621,9 +634,8 @@
                   "<artifactId>project</artifactId>" +
                   "<version>1</version>");
 
-    assertSources("project",
-                  "src/main/java",
-                  "src/main/resources");
+    assertSources("project", "src/main/java");
+    assertResources("project", "src/main/resources");
   }
 
 
@@ -640,10 +652,10 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources/A1/B1",
                   "target/generated-sources/A1/B2",
                   "target/generated-sources/A2");
+    assertResources("project", "src/main/resources");
   }
 
   public void testAddingExistingGeneratedSources5() throws Exception {
@@ -658,8 +670,8 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources");
+    assertResources("project", "src/main/resources");
   }
 
 
@@ -678,13 +690,13 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "targetCustom/generated-sources/src");
+    assertResources("project", "src/main/resources");
 
     assertTestSources("project",
                       "src/test/java",
-                      "src/test/resources",
                       "targetCustom/generated-test-sources/test");
+    assertTestResources("project", "src/test/resources");
   }
 
   public void testDoesNotAddAlreadyRegisteredSourcesUnderGeneratedDir() throws Exception {
@@ -735,13 +747,13 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources/main/src");
+    assertResources("project", "src/main/resources");
 
     assertTestSources("project",
                       "src/test/java",
-                      "src/test/resources",
                       "target/generated-test-sources/test/src");
+    assertTestResources("project", "src/test/resources");
   }
 
   public void testIgnoringFilesRightUnderGeneratedSources() throws Exception {
@@ -753,8 +765,10 @@
                   "<artifactId>project</artifactId>" +
                   "<version>1</version>");
 
-    assertSources("project", "src/main/java", "src/main/resources");
-    assertTestSources("project", "src/test/java", "src/test/resources");
+    assertSources("project", "src/main/java");
+    assertResources("project", "src/main/resources");
+    assertTestSources("project", "src/test/java");
+    assertTestResources("project", "src/test/resources");
   }
 
   public void testExcludingOutputDirectories() throws Exception {
@@ -891,13 +905,13 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources/baz");
+    assertResources("project", "src/main/resources");
 
     assertTestSources("project",
                       "src/test/java",
-                      "src/test/resources",
                       "target/generated-test-sources/bazz");
+    assertTestResources("project", "src/test/resources");
   }
 
   public void testDoesNotExcludeSourcesUnderTargetDir() throws Exception {
@@ -954,9 +968,8 @@
 
     assertExcludes("project", "target/foo");
 
-    assertSources("project",
-                  "target/src/main",
-                  "src/main/resources");
+    assertSources("project", "target/src/main");
+    assertResources("project", "src/main/resources");
   }
 
   public void testUnexcludeNewSources() throws Exception {
@@ -1023,15 +1036,15 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources/foo",
                   "target/generated-sources/annotations");
+    assertResources("project", "src/main/resources");
 
     assertTestSources("project",
                       "src/test/java",
-                      "src/test/resources",
                       "target/generated-test-sources/foo",
                       "target/generated-test-sources/test-annotations");
+    assertTestResources("project", "src/test/resources");
   }
 
   public void testCustomAnnotationProcessorSources() throws Exception {
@@ -1064,20 +1077,16 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "anno",
                   "target/generated-sources/foo",
                   "target/generated-sources/annotations",
                   "target/generated-sources/test-annotations");
+    assertResources("project", "src/main/resources");
 
     assertTestSources("project",
                       "src/test/java",
-                      "src/test/resources",
                       "target/generated-test-sources/foo");
-  }
-
-  private CompilerModuleExtension getCompilerExtension(String moduleName) {
-    return ModuleRootManager.getInstance(getModule(moduleName)).getModuleExtension(CompilerModuleExtension.class);
+    assertTestResources("project", "src/test/resources");
   }
 
   private void createProjectSubDirsWithFile(String ... dirs) throws IOException {
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/GroovyImporterTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/GroovyImporterTest.java
index 9cf632dc..53941f9 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/GroovyImporterTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/GroovyImporterTest.java
@@ -93,12 +93,12 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "src/main/groovy");
+    assertResources("project", "src/main/resources");
     assertTestSources("project",
                       "src/test/java",
-                      "src/test/resources",
                       "src/test/groovy");
+    assertTestResources("project", "src/test/resources");
   }
 
   public void testAddingCustomGroovySpecificSources() throws Exception {
@@ -161,14 +161,14 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "src/foo1",
                   "src/foo2");
+    assertResources("project", "src/main/resources");
     assertTestSources("project",
                       "src/test/java",
-                      "src/test/resources",
                       "src/test-foo1",
                       "src/test-foo2");
+    assertTestResources("project", "src/test/resources");
   }
 
   public void testAddingCustomGroovySpecificSourcesByRelativePath() throws Exception {
@@ -255,11 +255,10 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources/xxx");
-    assertTestSources("project",
-                      "src/test/java",
-                      "src/test/resources");
+    assertResources("project", "src/main/resources");
+    assertTestSources("project", "src/test/java");
+    assertTestResources("project", "src/test/resources");
 
     assertExcludes("project",
                    "target/generated-sources/groovy-stubs");
@@ -308,11 +307,10 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources/xxx");
-    assertTestSources("project",
-                      "src/test/java",
-                      "src/test/resources");
+    assertResources("project", "src/main/resources");
+    assertTestSources("project", "src/test/java");
+    assertTestResources("project", "src/test/resources");
 
     assertExcludes("project",
                    "target/generated-sources/foo",
@@ -456,11 +454,10 @@
 
     assertSources("project",
                   "src/main/java",
-                  "src/main/resources",
                   "target/generated-sources/xxx");
-    assertTestSources("project",
-                      "src/test/java",
-                      "src/test/resources");
+    assertResources("project", "src/main/resources");
+    assertTestSources("project", "src/test/java");
+    assertTestResources("project", "src/test/resources");
 
     assertExcludes("project",
                    "target/generated-sources/groovy-stubs");
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedDependencyInspectionTest.groovy b/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedDependencyInspectionTest.groovy
new file mode 100644
index 0000000..62de301
--- /dev/null
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedDependencyInspectionTest.groovy
@@ -0,0 +1,255 @@
+/*
+ * 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 org.jetbrains.idea.maven.inspections
+
+import org.jetbrains.idea.maven.dom.MavenDomTestCase
+import org.jetbrains.idea.maven.dom.inspections.MavenDuplicateDependenciesInspection
+
+/**
+ * @author Sergey Evdokimov
+ */
+class MavenDuplicatedDependencyInspectionTest extends MavenDomTestCase {
+
+  public void testDuplicatedInSameFile() {
+    myFixture.enableInspections(MavenDuplicateDependenciesInspection)
+
+    createProjectPom("""
+  <groupId>mavenParent</groupId>
+  <artifactId>childA</artifactId>
+  <version>1.0</version>
+
+  <dependencies>
+    <<warning>dependency</warning>>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+      <scope>provided</scope>
+    </dependency>
+    <<warning>dependency</warning>>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+    </dependency>
+  </dependencies>
+""")
+
+    checkHighlighting()
+  }
+
+  public void testDuplicatedInSameFileDifferentVersion() {
+    myFixture.enableInspections(MavenDuplicateDependenciesInspection)
+
+    createProjectPom("""
+  <groupId>mavenParent</groupId>
+  <artifactId>childA</artifactId>
+  <version>1.0</version>
+
+  <dependencies>
+    <<warning>dependency</warning>>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+    </dependency>
+    <<warning>dependency</warning>>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+    </dependency>
+  </dependencies>
+""")
+
+    checkHighlighting()
+  }
+
+  public void testDuplicatedInParentDifferentScope() {
+    myFixture.enableInspections(MavenDuplicateDependenciesInspection)
+
+    createModulePom("child", """
+  <groupId>mavenParent</groupId>
+  <artifactId>child</artifactId>
+  <version>1.0</version>
+
+<parent>
+  <groupId>mavenParent</groupId>
+  <artifactId>parent</artifactId>
+  <version>1.0</version>
+</parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+      <scope>runtime</scope>
+    </dependency>
+  </dependencies>
+""")
+
+    createProjectPom("""
+  <groupId>mavenParent</groupId>
+  <artifactId>parent</artifactId>
+  <version>1.0</version>
+  <packaging>pom</packaging>
+
+  <modules>
+    <module>child</module>
+  </modules>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+""")
+
+    importProject()
+
+    checkHighlighting(myProjectPom, true, false, true)
+  }
+
+  public void testDuplicatedInParentSameScope() {
+    myFixture.enableInspections(MavenDuplicateDependenciesInspection)
+
+    createModulePom("child", """
+  <groupId>mavenParent</groupId>
+  <artifactId>child</artifactId>
+  <version>1.0</version>
+
+<parent>
+  <groupId>mavenParent</groupId>
+  <artifactId>parent</artifactId>
+  <version>1.0</version>
+</parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+""")
+
+    createProjectPom("""
+  <groupId>mavenParent</groupId>
+  <artifactId>parent</artifactId>
+  <version>1.0</version>
+  <packaging>pom</packaging>
+
+  <modules>
+    <module>child</module>
+  </modules>
+
+  <dependencies>
+    <<warning>dependency</warning>>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+    </dependency>
+  </dependencies>
+""")
+
+    importProject()
+
+    checkHighlighting(myProjectPom, true, false, true)
+  }
+
+  public void testDuplicatedInParentDifferentVersion() {
+    myFixture.enableInspections(MavenDuplicateDependenciesInspection)
+
+    createModulePom("child", """
+  <groupId>mavenParent</groupId>
+  <artifactId>child</artifactId>
+  <version>1.0</version>
+
+<parent>
+  <groupId>mavenParent</groupId>
+  <artifactId>parent</artifactId>
+  <version>1.0</version>
+</parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+    </dependency>
+  </dependencies>
+""")
+
+    importProject("""
+  <groupId>mavenParent</groupId>
+  <artifactId>parent</artifactId>
+  <version>1.0</version>
+  <packaging>pom</packaging>
+
+  <modules>
+    <module>child</module>
+  </modules>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+    </dependency>
+  </dependencies>
+""")
+
+    checkHighlighting(myProjectPom, true, false, true)
+  }
+
+  public void testDuplicatedInManagedDependencies() {
+    myFixture.enableInspections(MavenDuplicateDependenciesInspection)
+
+    createProjectPom("""
+  <groupId>mavenParent</groupId>
+  <artifactId>childA</artifactId>
+  <version>1.0</version>
+
+  <dependencyManagement>
+    <dependencies>
+      <<warning>dependency</warning>>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>3.8.2</version>
+        <type>jar</type>
+      </dependency>
+
+      <<warning>dependency</warning>>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.0</version>
+      </dependency>
+
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.0</version>
+        <classifier>sources</classifier>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+""")
+
+    checkHighlighting()
+  }
+
+}
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedInspectionTest.groovy b/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedInspectionTest.groovy
deleted file mode 100644
index c589168..0000000
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedInspectionTest.groovy
+++ /dev/null
@@ -1,255 +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 org.jetbrains.idea.maven.inspections
-
-import org.jetbrains.idea.maven.dom.MavenDomTestCase
-import org.jetbrains.idea.maven.dom.inspections.MavenDuplicateDependenciesInspection
-
-/**
- * @author Sergey Evdokimov
- */
-class MavenDuplicatedInspectionTest extends MavenDomTestCase {
-
-  public void testDuplicatedInSameFile() {
-    myFixture.enableInspections(MavenDuplicateDependenciesInspection)
-
-    createProjectPom("""
-  <groupId>mavenParent</groupId>
-  <artifactId>childA</artifactId>
-  <version>1.0</version>
-
-  <dependencies>
-    <<warning>dependency</warning>>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.2</version>
-      <scope>provided</scope>
-    </dependency>
-    <<warning>dependency</warning>>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.2</version>
-    </dependency>
-  </dependencies>
-""")
-
-    checkHighlighting()
-  }
-
-  public void testDuplicatedInSameFileDifferentVersion() {
-    myFixture.enableInspections(MavenDuplicateDependenciesInspection)
-
-    createProjectPom("""
-  <groupId>mavenParent</groupId>
-  <artifactId>childA</artifactId>
-  <version>1.0</version>
-
-  <dependencies>
-    <<warning>dependency</warning>>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.2</version>
-    </dependency>
-    <<warning>dependency</warning>>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.1</version>
-    </dependency>
-  </dependencies>
-""")
-
-    checkHighlighting()
-  }
-
-  public void testDuplicatedInParentDifferentScope() {
-    myFixture.enableInspections(MavenDuplicateDependenciesInspection)
-
-    createModulePom("child", """
-  <groupId>mavenParent</groupId>
-  <artifactId>child</artifactId>
-  <version>1.0</version>
-
-<parent>
-  <groupId>mavenParent</groupId>
-  <artifactId>parent</artifactId>
-  <version>1.0</version>
-</parent>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.2</version>
-      <scope>runtime</scope>
-    </dependency>
-  </dependencies>
-""")
-
-    createProjectPom("""
-  <groupId>mavenParent</groupId>
-  <artifactId>parent</artifactId>
-  <version>1.0</version>
-  <packaging>pom</packaging>
-
-  <modules>
-    <module>child</module>
-  </modules>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.2</version>
-      <scope>provided</scope>
-    </dependency>
-  </dependencies>
-""")
-
-    importProject()
-
-    checkHighlighting(myProjectPom, true, false, true)
-  }
-
-  public void testDuplicatedInParentSameScope() {
-    myFixture.enableInspections(MavenDuplicateDependenciesInspection)
-
-    createModulePom("child", """
-  <groupId>mavenParent</groupId>
-  <artifactId>child</artifactId>
-  <version>1.0</version>
-
-<parent>
-  <groupId>mavenParent</groupId>
-  <artifactId>parent</artifactId>
-  <version>1.0</version>
-</parent>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.2</version>
-      <scope>compile</scope>
-    </dependency>
-  </dependencies>
-""")
-
-    createProjectPom("""
-  <groupId>mavenParent</groupId>
-  <artifactId>parent</artifactId>
-  <version>1.0</version>
-  <packaging>pom</packaging>
-
-  <modules>
-    <module>child</module>
-  </modules>
-
-  <dependencies>
-    <<warning>dependency</warning>>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.2</version>
-    </dependency>
-  </dependencies>
-""")
-
-    importProject()
-
-    checkHighlighting(myProjectPom, true, false, true)
-  }
-
-  public void testDuplicatedInParentDifferentVersion() {
-    myFixture.enableInspections(MavenDuplicateDependenciesInspection)
-
-    createModulePom("child", """
-  <groupId>mavenParent</groupId>
-  <artifactId>child</artifactId>
-  <version>1.0</version>
-
-<parent>
-  <groupId>mavenParent</groupId>
-  <artifactId>parent</artifactId>
-  <version>1.0</version>
-</parent>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.1</version>
-    </dependency>
-  </dependencies>
-""")
-
-    importProject("""
-  <groupId>mavenParent</groupId>
-  <artifactId>parent</artifactId>
-  <version>1.0</version>
-  <packaging>pom</packaging>
-
-  <modules>
-    <module>child</module>
-  </modules>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.2</version>
-    </dependency>
-  </dependencies>
-""")
-
-    checkHighlighting(myProjectPom, true, false, true)
-  }
-
-  public void testDuplicatedInManagedDependencies() {
-    myFixture.enableInspections(MavenDuplicateDependenciesInspection)
-
-    createProjectPom("""
-  <groupId>mavenParent</groupId>
-  <artifactId>childA</artifactId>
-  <version>1.0</version>
-
-  <dependencyManagement>
-    <dependencies>
-      <<warning>dependency</warning>>
-        <groupId>junit</groupId>
-        <artifactId>junit</artifactId>
-        <version>3.8.2</version>
-        <type>jar</type>
-      </dependency>
-
-      <<warning>dependency</warning>>
-        <groupId>junit</groupId>
-        <artifactId>junit</artifactId>
-        <version>4.0</version>
-      </dependency>
-
-      <dependency>
-        <groupId>junit</groupId>
-        <artifactId>junit</artifactId>
-        <version>4.0</version>
-        <classifier>sources</classifier>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-""")
-
-    checkHighlighting()
-  }
-
-}
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedPluginInspectionTest.groovy b/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedPluginInspectionTest.groovy
new file mode 100644
index 0000000..4535f26
--- /dev/null
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedPluginInspectionTest.groovy
@@ -0,0 +1,51 @@
+/*
+ * 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 org.jetbrains.idea.maven.inspections
+
+import org.jetbrains.idea.maven.dom.MavenDomTestCase
+import org.jetbrains.idea.maven.dom.inspections.MavenDuplicatePluginInspection
+/**
+ * @author Sergey Evdokimov
+ */
+class MavenDuplicatedPluginInspectionTest extends MavenDomTestCase {
+
+  public void testDuplicatedPlugin() {
+    myFixture.enableInspections(MavenDuplicatePluginInspection)
+
+    createProjectPom("""
+  <groupId>mavenParent</groupId>
+  <artifactId>childA</artifactId>
+  <version>1.0</version>
+
+  <build>
+    <plugins>
+      <<warning>plugin</warning>>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.2</version>
+      </plugin>
+      <<warning>plugin</warning>>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.2</version>
+      </plugin>
+    </plugins>
+  </build>
+""")
+
+    checkHighlighting()
+  }
+}
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 9bd3df2..b25d8fb 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
@@ -23,6 +23,7 @@
 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.JavaSourceRootType;
 
 import java.io.File;
 
@@ -90,13 +91,17 @@
                   "<artifactId>project</artifactId>" +
                   "<version>1</version>");
 
-    assertSources("project", "src/main/java", "src/main/resources");
-    assertTestSources("project", "src/test/java", "src/test/resources");
+    assertSources("project", "src/main/java");
+    assertResources("project", "src/main/resources");
+    assertTestSources("project", "src/test/java");
+    assertTestResources("project", "src/test/resources");
 
     updateProjectFolders();
 
-    assertSources("project", "src/main/java", "src/main/resources");
-    assertTestSources("project", "src/test/java", "src/test/resources");
+    assertSources("project", "src/main/java");
+    assertResources("project", "src/main/resources");
+    assertTestSources("project", "src/test/java");
+    assertTestResources("project", "src/test/resources");
   }
 
   public void testDoesNotExcludeRegisteredSources() throws Exception {
@@ -113,7 +118,7 @@
         MavenRootModelAdapter adapter = new MavenRootModelAdapter(myProjectsTree.findProject(myProjectPom),
                                                                   getModule("project"),
                                                                   new MavenDefaultModifiableModelsProvider(myProject));
-        adapter.addSourceFolder(sourceDir.getPath(), false);
+        adapter.addSourceFolder(sourceDir.getPath(), JavaSourceRootType.SOURCE);
         adapter.getRootModel().commit();
       }
     });
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsManagerTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsManagerTest.java
index ac9b17a..6c9bc1c 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsManagerTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsManagerTest.java
@@ -920,7 +920,8 @@
                   "  </plugins>" +
                   "</build>");
 
-    assertSources("project", "src/main/java", "src/main/resources", "src1", "src2");
+    assertSources("project", "src/main/java", "src1", "src2");
+    assertResources("project", "src/main/resources");
   }
 
   public void testForceReimport() throws Exception {
diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesProjectViewTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesProjectViewTest.java
index 1b2ffb9f..b91a878 100644
--- a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesProjectViewTest.java
+++ b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesProjectViewTest.java
@@ -1,3 +1,18 @@
+/*
+ * 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.lang.properties;
 
 import com.intellij.ide.projectView.impl.AbstractProjectViewPSIPane;
@@ -13,6 +28,7 @@
 public class PropertiesProjectViewTest extends LightPlatformCodeInsightFixtureTestCase {
   private TestProjectTreeStructure myStructure;
 
+  @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
   public PropertiesProjectViewTest() {
     PlatformTestCase.initPlatformLangPrefix();
   }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
index b642114..bbb8e54 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
@@ -206,6 +206,7 @@
 radio.configure.upgrade.auto.15format=Upgrade automatically (use Subversion 1.&5)
 radio.configure.upgrade.auto.16format=Upgrade automatically (use Subversion 1.&6)
 radio.configure.upgrade.auto.17format=Upgrade automatically (use Subversion 1.&7)
+radio.configure.upgrade.auto.18format=Upgrade automatically (use Subversion 1.&8)
 
 label.configure.create.label={0} is about to create new Subversion working copy,\n\
 please, select desired working copy format:
@@ -215,10 +216,12 @@
 radio.configure.create.auto.15format=1.&5 format
 radio.configure.create.auto.16format=1.&6 format
 radio.configure.create.auto.17format=1.&7 format
+radio.configure.create.auto.18format=1.&8 format
 
 label.configure.change.label=Change working copy ''{0}'' format to:
 radio.configure.change.auto.16format=1.&6 format
 radio.configure.change.auto.17format=1.&7 format
+radio.configure.change.auto.18format=1.&8 format
 
 dialog.upgrade.wcopy.format.title=Subversion Working Copy Format
 
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java
index ecd387b..ac23963 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java
@@ -282,10 +282,6 @@
     return SvnConfiguration.UseAcceleration.nothing;
   }
 
-  private void setAcceleration(SvnConfiguration.UseAcceleration acceleration) {
-    myWithCommandLineClient.setSelected(SvnConfiguration.UseAcceleration.commandLine.equals(acceleration));
-  }
-
   public void apply() throws ConfigurationException {
     SvnConfiguration configuration = SvnConfiguration.getInstance(myProject);
     configuration.setConfigurationDirParameters(myUseDefaultCheckBox.isSelected(), myConfigurationDirectoryText.getText());
@@ -351,7 +347,7 @@
     mySSHConnectionTimeout.setValue(Long.valueOf(configuration.mySSHConnectionTimeout / 1000));
     mySSHReadTimeout.setValue(Long.valueOf(configuration.mySSHReadTimeout / 1000));
     myHttpTimeout.setValue(Long.valueOf(configuration.getHttpTimeout() / 1000));
-    setAcceleration(configuration.myUseAcceleration);
+    myWithCommandLineClient.setSelected(configuration.isCommandLine());
     final SvnApplicationSettings applicationSettings17 = SvnApplicationSettings.getInstance();
     myCommandLineClient.setText(applicationSettings17.getCommandLinePath());
 
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java
index b4f7991..1b2a8df 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java
@@ -75,11 +75,6 @@
 
   private final static String SERVERS_FILE_NAME = "servers";
   
-  public static final String UPGRADE_AUTO = "auto";
-  public static final String UPGRADE_AUTO_15 = "auto1.5";
-  public static final String UPGRADE_AUTO_16 = "auto1.6";
-  public static final String UPGRADE_AUTO_17 = "auto1.7";
-  public static final String UPGRADE_NONE = "none";
   public static final String CLEANUP_ON_START_RUN = "cleanupOnStartRun";
   private final Project myProject;
 
@@ -130,6 +125,10 @@
   private SvnInteractiveAuthenticationProvider myInteractiveProvider;
   private IdeaSVNConfigFile myConfigFile;
 
+  public boolean isCommandLine() {
+    return UseAcceleration.commandLine.equals(myUseAcceleration);
+  }
+
   @Override
   public Element getState() {
     Element element = new Element("state");
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
index 77783bad..2595631 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
@@ -136,17 +136,20 @@
     return result;
   }
 
-  public static String showUpgradeDialog(final File path, final Project project, final boolean display13format, final String mode,
-                                         @NotNull final Ref<Boolean> wasOk) {
+  public static WorkingCopyFormat showUpgradeDialog(final File path,
+                                                    final Project project,
+                                                    final boolean display13format,
+                                                    @NotNull final WorkingCopyFormat defaultSelection,
+                                                    @NotNull final Ref<Boolean> wasOk) {
     assert ! ApplicationManager.getApplication().isUnitTestMode();
-    final String[] newMode = new String[] {mode};
+    final Ref<WorkingCopyFormat> format = new Ref<WorkingCopyFormat>(defaultSelection);
     WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(new Runnable() {
       public void run() {
-        wasOk.set(displayUpgradeDialog(project, path, display13format, newMode));
+        wasOk.set(displayUpgradeDialog(project, path, display13format, format));
       }
     });
     ApplicationManager.getApplication().getMessageBus().syncPublisher(SvnVcs.WC_CONVERTED).run();
-    return newMode[0];
+    return format.get();
   }
 
   public static WorkingCopyFormat findRootAndGetFormat(final File path) {
@@ -187,12 +190,12 @@
     return WorkingCopyFormat.getInstance(format);
   }
 
-  private static boolean displayUpgradeDialog(Project project, File path, final boolean dispay13format, String[] newMode) {
+  private static boolean displayUpgradeDialog(Project project, File path, final boolean dispay13format, Ref<WorkingCopyFormat> format) {
     UpgradeFormatDialog dialog = new UpgradeFormatDialog(project, path, false);
-    dialog.setData(newMode[0]);
+    dialog.setData(format.get());
     dialog.show();
     if (dialog.isOK()) {
-      newMode[0] = dialog.getUpgradeMode();
+      format.set(dialog.getUpgradeMode());
     }
     return dialog.isOK();
   }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java
index 2de7232..1b0792a 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java
@@ -24,4 +24,5 @@
   String SVN_EXECUTABLE = "svn:executable";
   String SVN_IGNORE = "svn:ignore";
   String SVN_EXTERNALS = "svn:externals";
+  String LOG = "svn:log";
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java
deleted file mode 100644
index fcac396..0000000
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java
+++ /dev/null
@@ -1,113 +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 org.jetbrains.idea.svn;
-
-import com.intellij.vcsUtil.LearningProxy;
-import org.jetbrains.idea.svn.portable.SVNChangelistClientI;
-import org.jetbrains.idea.svn.portable.SvnUpdateClientI;
-import org.tmatesoft.svn.core.SVNException;
-
-import java.io.File;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 10/19/12
- * Time: 4:22 PM
- */
-// TODO: Likely to be removed (together with SvnAbstractWriteOperationLocks).
-public class SvnProxies {
-  private final SvnAbstractWriteOperationLocks myLocks;
-  private final AtomicReference<LearningProxy<SVNChangelistClientI, SVNException>> myChangelist;
-  private final AtomicReference<LearningProxy<SvnUpdateClientI, SVNException>> myUpdate;
-
-  public SvnProxies(SvnAbstractWriteOperationLocks locks) {
-    myLocks = locks;
-    myChangelist = new AtomicReference<LearningProxy<SVNChangelistClientI, SVNException>>();
-    myUpdate = new AtomicReference<LearningProxy<SvnUpdateClientI, SVNException>>();
-  }
-
-  public LearningProxy<SVNChangelistClientI, SVNException> getChangelistsProfessor(final File file) {
-    if (myChangelist.get() == null) {
-      final MyLearningProxy<SVNChangelistClientI> proxy = new MyLearningProxy<SVNChangelistClientI>(myLocks, file);
-      final SVNChangelistClientI learn = proxy.learn(SVNChangelistClientI.class);
-      try {
-        learn.addToChangelist(null, null, null, null);
-        learn.doAddToChangelist(null, null, null, null);
-        learn.doRemoveFromChangelist(null, null, null);
-        learn.removeFromChangelist(null, null, null);
-      } catch (SVNException e) {
-        //can not occur since methods are not really called
-        throw new RuntimeException(e);
-      }
-
-      myChangelist.set(proxy);
-    }
-    return myChangelist.get();
-  }
-
-  public LearningProxy<SvnUpdateClientI, SVNException> getUpdateProfessor(final File file) {
-    if (myUpdate.get() == null) {
-      final MyLearningProxy<SvnUpdateClientI> proxy = new MyLearningProxy<SvnUpdateClientI>(myLocks, file);
-      final SvnUpdateClientI learn = proxy.learn(SvnUpdateClientI.class);
-      try {
-        learn.doUpdate(null, null, false);
-        learn.doUpdate(null, null, false, false);
-        learn.doUpdate((File[]) null, null, null, false, false);
-        learn.doUpdate((File[]) null, null, null, false, false, false);
-        learn.doUpdate((File) null, null, null, false, false);
-
-        learn.doSwitch(null, null, null, false);
-        learn.doSwitch(null, null, null, null, false);
-        learn.doSwitch(null, null, null, null, false, false);
-        learn.doSwitch(null, null, null, null, null, false, false);
-        learn.doSwitch(null, null, null, null, null, false, false, false);
-
-        learn.doCheckout(null, null, null, null, false);
-        // todo continue
-        //learn.doCheckout();
-        //learn.doCheckout();
-      }
-      catch (SVNException e) {
-        //can not occur since methods are not really called
-        throw new RuntimeException(e);
-      }
-      myUpdate.set(proxy);
-    }
-    return myUpdate.get();
-  }
-
-  private static class MyLearningProxy<T> extends LearningProxy<T, SVNException> {
-    private final SvnAbstractWriteOperationLocks myLocks;
-    private final File myFile;
-
-    private MyLearningProxy(SvnAbstractWriteOperationLocks locks, final File file) {
-      myLocks = locks;
-      myFile = file;
-    }
-
-    @Override
-    protected void onBefore() throws SVNException {
-      myLocks.lockWrite(myFile);
-    }
-
-    @Override
-    protected void onAfter() throws SVNException {
-      myLocks.unlockWrite(myFile);
-    }
-  }
-}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
index b246ea7..690ec0e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
@@ -129,8 +129,8 @@
       myConfiguration17 = SvnConfiguration.getInstance(myProject);
       myPath = path;
       myDepth = depth;
-      mySvnClient = new SvnkitSvnStatusClient(client);
-      myCommandLineClient = new SvnCommandLineStatusClient(myProject);
+      mySvnClient = new SvnkitSvnStatusClient(myVcs, client);
+      myCommandLineClient = new SvnCommandLineStatusClient(myVcs);
       myIsInnerCopyRoot = isInnerCopyRoot;
     }
 
@@ -159,7 +159,7 @@
       if (CheckJavaHL.isPresent() && SvnConfiguration.UseAcceleration.javaHL.equals(myConfiguration17.myUseAcceleration) &&
           Svn17Detector.is17(myProject, file)) {
         return new JavaHLSvnStatusClient(myProject);
-      } else if (SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration17.myUseAcceleration)) {
+      } else if (myConfiguration17.isCommandLine()) {
         // apply command line disregarding working copy format
         return myCommandLineClient;
       }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
index 7594c2a..07301c0 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
@@ -91,7 +91,11 @@
   }
 
   public static boolean isSvnVersioned(final Project project, File parent) {
-    final SVNInfo info = SvnVcs.getInstance(project).getInfo(parent);
+    return isSvnVersioned(SvnVcs.getInstance(project), parent);
+  }
+
+  public static boolean isSvnVersioned(final @NotNull SvnVcs vcs, File parent) {
+    final SVNInfo info = vcs.getInfo(parent);
 
     return info != null;
   }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
index 02b28a9..55b79b0 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
@@ -83,6 +83,7 @@
 import org.jetbrains.idea.svn.lowLevel.PrimitivePool;
 import org.jetbrains.idea.svn.networking.SSLProtocolExceptionParser;
 import org.jetbrains.idea.svn.portable.SvnWcClientI;
+import org.jetbrains.idea.svn.properties.PropertyClient;
 import org.jetbrains.idea.svn.rollback.SvnRollbackEnvironment;
 import org.jetbrains.idea.svn.update.SvnIntegrateEnvironment;
 import org.jetbrains.idea.svn.update.SvnUpdateEnvironment;
@@ -202,8 +203,8 @@
   };
   private SvnCheckoutProvider myCheckoutProvider;
 
-  private ClientFactory cmdClientFactory;
-  private ClientFactory svnKitClientFactory;
+  private final ClientFactory cmdClientFactory;
+  private final ClientFactory svnKitClientFactory;
 
   private final boolean myLogExceptions;
 
@@ -244,6 +245,9 @@
   public SvnVcs(final Project project, MessageBus bus, SvnConfiguration svnConfiguration, final SvnLoadedBrachesStorage storage) {
     super(project, VCS_NAME);
 
+    cmdClientFactory = new CmdClientFactory(this);
+    svnKitClientFactory = new SvnKitClientFactory(this);
+
     myLoadedBranchesStorage = storage;
     myRootsToWorkingCopies = new RootsToWorkingCopies(this);
     myConfiguration = svnConfiguration;
@@ -362,7 +366,7 @@
   public boolean checkCommandLineVersion() {
     boolean isValid = true;
 
-    if (!isProject16() && (SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration.myUseAcceleration) || isProject18())) {
+    if (!isProject16() && (myConfiguration.isCommandLine() || isProject18())) {
       isValid = myChecker.checkExecutableAndNotifyIfNeeded();
     }
 
@@ -501,9 +505,6 @@
       checkCommandLineVersion();
     }
 
-    cmdClientFactory = new CmdClientFactory(this);
-    svnKitClientFactory = new SvnKitClientFactory(this);
-
     // do one time after project loaded
     StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {
       @Override
@@ -861,7 +862,7 @@
   }
 
   @Nullable
-  public SVNPropertyValue getPropertyWithCaching(final VirtualFile file, final String propName) throws SVNException {
+  public SVNPropertyValue getPropertyWithCaching(final VirtualFile file, final String propName) throws VcsException {
     Map<String, Pair<SVNPropertyValue, Trinity<Long, Long, Long>>> cachedMap = myPropertyCache.get(keyForVf(file));
     final Pair<SVNPropertyValue, Trinity<Long, Long, Long>> cachedValue = cachedMap == null ? null : cachedMap.get(propName);
 
@@ -875,7 +876,8 @@
       }
     }
 
-    final SVNPropertyData value = createWCClient().doGetProperty(ioFile, propName, SVNRevision.WORKING, SVNRevision.WORKING);
+    PropertyClient client = getFactory(ioFile).createPropertyClient();
+    final SVNPropertyData value = client.getProperty(SvnTarget.fromFile(ioFile, SVNRevision.WORKING), propName, false, SVNRevision.WORKING);
     final SVNPropertyValue propValue = value == null ? null : value.getValue();
 
     if (cachedMap == null) {
@@ -1349,7 +1351,7 @@
   }
 
   private WorkingCopyFormat getProjectRootFormat() {
-    return getWorkingCopyFormat(new File(getProject().getBaseDir().getPath()));
+    return !getProject().isDefault() ? getWorkingCopyFormat(new File(getProject().getBaseDir().getPath())) : WorkingCopyFormat.UNKNOWN;
   }
 
   /**
@@ -1395,6 +1397,11 @@
 
   @NotNull
   public ClientFactory getFactoryFromSettings() {
-    return myConfiguration.myUseAcceleration.equals(SvnConfiguration.UseAcceleration.commandLine) ? cmdClientFactory : svnKitClientFactory;
+    return myConfiguration.isCommandLine() ? cmdClientFactory : svnKitClientFactory;
+  }
+
+  @NotNull
+  public ClientFactory getCommandLineFactory() {
+    return cmdClientFactory;
   }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java
index 909d904..041ee28 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java
@@ -97,33 +97,7 @@
     return UNKNOWN;
   }
 
-  public static WorkingCopyFormat getInstance(final String updateOption) {
-    if (SvnConfiguration.UPGRADE_AUTO_17.equals(updateOption)) {
-      return ONE_DOT_SEVEN;
-    } else if (SvnConfiguration.UPGRADE_AUTO_16.equals(updateOption)) {
-      return ONE_DOT_SIX;
-    } else if (SvnConfiguration.UPGRADE_AUTO_15.equals(updateOption)) {
-      return ONE_DOT_FIVE;
-    } else if (SvnConfiguration.UPGRADE_AUTO.equals(updateOption)) {
-      return ONE_DOT_FOUR;
-    }
-    return ONE_DOT_THREE;
-  }
-
   public int getFormat() {
     return myFormat;
   }
-
-  public String getOption() {
-    if (ONE_DOT_SEVEN.equals(this)) {
-      return SvnConfiguration.UPGRADE_AUTO_17;
-    } else if (ONE_DOT_SIX.equals(this)) {
-      return SvnConfiguration.UPGRADE_AUTO_16;
-    } else if (ONE_DOT_FIVE.equals(this)) {
-      return SvnConfiguration.UPGRADE_AUTO_15;
-    } else if (ONE_DOT_FOUR.equals(this)) {
-      return SvnConfiguration.UPGRADE_AUTO;
-    }
-    return SvnConfiguration.UPGRADE_NONE;
-  }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java
index 1af0550..337a045 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java
@@ -36,13 +36,17 @@
 import org.jetbrains.idea.svn.SvnBundle;
 import org.jetbrains.idea.svn.SvnPropertyKeys;
 import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.api.ClientFactory;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
 import org.jetbrains.idea.svn.dialogs.SelectCreateExternalTargetDialog;
+import org.jetbrains.idea.svn.update.UpdateClient;
 import org.tmatesoft.svn.core.SVNCancelException;
 import org.tmatesoft.svn.core.SVNDepth;
 import org.tmatesoft.svn.core.SVNException;
 import org.tmatesoft.svn.core.SVNPropertyValue;
 import org.tmatesoft.svn.core.internal.wc.SVNExternal;
 import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
 
 import java.io.File;
 
@@ -94,7 +98,7 @@
       dirtyScopeManager.fileDirty(filePath);
       if (checkout) {
         // +-
-        final SVNUpdateClient client = vcs.createUpdateClient();
+        final UpdateClient client = vcs.getFactory(ioFile).createUpdateClient();
         client.setEventHandler(new ISVNEventHandler() {
           @Override
           public void handleEvent(SVNEvent event, double progress) throws SVNException {
@@ -118,12 +122,16 @@
     catch (SVNException e1) {
       AbstractVcsHelper.getInstance(project).showError(new VcsException(e1), "Create External");
     }
+    catch (VcsException e1) {
+      AbstractVcsHelper.getInstance(project).showError(e1, "Create External");
+    }
   }
 
-  public static boolean addToExternalProperty(SvnVcs vcs, File ioFile, String target, String url) throws SVNException {
-    final SVNWCClient wcClient = vcs.createWCClient();
-    final SVNPropertyData propertyData =
-      wcClient.doGetProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNRevision.UNDEFINED, SVNRevision.UNDEFINED);
+  public static boolean addToExternalProperty(@NotNull SvnVcs vcs, @NotNull File ioFile, String target, String url)
+    throws SVNException, VcsException {
+    ClientFactory factory = vcs.getFactory(ioFile);
+    SVNPropertyData propertyData = factory.createPropertyClient().getProperty(SvnTarget.fromFile(ioFile), SvnPropertyKeys.SVN_EXTERNALS,
+                                                                              false, SVNRevision.UNDEFINED);
     String newValue;
     if (propertyData != null && propertyData.getValue() != null && ! StringUtil.isEmptyOrSpaces(propertyData.getValue().getString())) {
       final SVNExternal[] externals = SVNExternal.parseExternals("Create External", propertyData.getValue().getString());
@@ -135,16 +143,17 @@
         }
       }
       final String string = createExternalDefinitionString(url, target);
-      newValue = propertyData.getValue().getString() + "\n" + string;
+      newValue = propertyData.getValue().getString().trim() + "\n" + string;
     } else {
       newValue = createExternalDefinitionString(url, target);
     }
-    wcClient.doSetProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNPropertyValue.create(newValue), false, SVNDepth.EMPTY, null, null);
+    factory.createPropertyClient().setProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNPropertyValue.create(newValue), SVNDepth.EMPTY,
+                                               false);
     return false;
   }
 
   public static String createExternalDefinitionString(String url, String target) {
-    return url + " " + target;
+    return CommandUtil.escape(url) + " " + target;
   }
 
   @Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java
index c2fe2c3..f7674b6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java
@@ -37,9 +37,6 @@
                        boolean includeMergedRevisions,
                        @Nullable SVNDiffOptions diffOptions,
                        @Nullable final ISVNAnnotateHandler handler) throws VcsException {
-    // TODO: after merge remove setting includeMergedRevisions to false and update parsing
-    includeMergedRevisions = false;
-
     List<String> parameters = new ArrayList<String>();
     CommandUtil.put(parameters, target.getPathOrUrlString(), pegRevision);
     parameters.add("--revision");
@@ -55,9 +52,7 @@
 
   public void parseOutput(@NotNull String output, @Nullable ISVNAnnotateHandler handler) throws VcsException {
     try {
-      JAXBContext context = JAXBContext.newInstance(BlameInfo.class);
-      Unmarshaller unmarshaller = context.createUnmarshaller();
-      BlameInfo info = (BlameInfo)unmarshaller.unmarshal(new StringReader(output));
+      BlameInfo info = CommandUtil.parse(output, BlameInfo.class);
 
       if (handler != null && info != null && info.target != null && info.target.lineEntries != null) {
         for (LineEntry entry : info.target.lineEntries) {
@@ -75,7 +70,10 @@
 
   private static void invokeHandler(ISVNAnnotateHandler handler, LineEntry entry) throws SVNException {
     // line numbers in our api start from 0 - not from 1 like in svn output
-    handler.handleLine(entry.date(), entry.revision(), entry.author(), null, null, 0, null, null, entry.lineNumber - 1);
+    // "line" value is not used in handlers - so null is passed
+    handler
+      .handleLine(entry.date(), entry.revision(), entry.author(), null, entry.mergedDate(), entry.mergedRevision(), entry.mergedAuthor(),
+                  entry.mergedPath(), entry.lineNumber - 1);
   }
 
   @XmlRootElement(name = "blame")
@@ -99,15 +97,53 @@
     @XmlElement(name = "commit")
     public CommitEntry commit;
 
+    @XmlElement(name = "merged")
+    public MergedEntry merged;
+
     public long revision() {
+      return revision(commit);
+    }
+
+    @Nullable
+    public String author() {
+      return author(commit);
+    }
+
+    @Nullable
+    public Date date() {
+      return date(commit);
+    }
+
+    @Nullable
+    public String mergedPath() {
+      return merged != null ? merged.path : null;
+    }
+
+    public long mergedRevision() {
+      return merged != null ? revision(merged.commit) : 0;
+    }
+
+    @Nullable
+    public String mergedAuthor() {
+      return merged != null ? author(merged.commit) : null;
+    }
+
+    @Nullable
+    public Date mergedDate() {
+      return merged != null ? date(merged.commit) : null;
+    }
+
+    private static long revision(@Nullable CommitEntry commit) {
       return commit != null ? commit.revision : 0;
     }
 
-    public String author() {
+    @Nullable
+    private static String author(@Nullable CommitEntry commit) {
       return commit != null ? commit.author : null;
     }
 
-    public Date date() {
+    @Nullable
+    private static Date date(@Nullable CommitEntry commit) {
       return commit != null ? commit.date : null;
     }
   }
@@ -123,4 +159,13 @@
     @XmlElement(name = "date")
     public Date date;
   }
+
+  public static class MergedEntry {
+
+    @XmlAttribute(name = "path")
+    public String path;
+
+    @XmlElement(name = "commit")
+    public CommitEntry commit;
+  }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
index 739e2ad..27c0d1e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
@@ -5,7 +5,9 @@
 import org.jetbrains.idea.svn.add.AddClient;
 import org.jetbrains.idea.svn.annotate.AnnotateClient;
 import org.jetbrains.idea.svn.change.ChangeListClient;
+import org.jetbrains.idea.svn.checkin.ImportClient;
 import org.jetbrains.idea.svn.checkout.CheckoutClient;
+import org.jetbrains.idea.svn.checkout.ExportClient;
 import org.jetbrains.idea.svn.cleanup.CleanupClient;
 import org.jetbrains.idea.svn.conflict.ConflictClient;
 import org.jetbrains.idea.svn.content.ContentClient;
@@ -15,7 +17,7 @@
 import org.jetbrains.idea.svn.integrate.MergeClient;
 import org.jetbrains.idea.svn.lock.LockClient;
 import org.jetbrains.idea.svn.portable.SvnStatusClientI;
-import org.jetbrains.idea.svn.portable.SvnUpdateClientI;
+import org.jetbrains.idea.svn.update.UpdateClient;
 import org.jetbrains.idea.svn.portable.SvnWcClientI;
 import org.jetbrains.idea.svn.properties.PropertyClient;
 import org.jetbrains.idea.svn.revert.RevertClient;
@@ -46,6 +48,9 @@
   protected LockClient myLockClient;
   protected CleanupClient myCleanupClient;
   protected RelocateClient myRelocateClient;
+  protected VersionClient myVersionClient;
+  protected ImportClient myImportClient;
+  protected ExportClient myExportClient;
 
   protected ClientFactory(@NotNull SvnVcs vcs) {
     myVcs = vcs;
@@ -94,7 +99,7 @@
   // TODO: Update this in same like other clients - move to corresponding package, rename clients
   // New instances should be always created by this method, as setXxx() methods are currently used in update logic
   @NotNull
-  public abstract SvnUpdateClientI createUpdateClient();
+  public abstract UpdateClient createUpdateClient();
 
   @NotNull
   public DeleteClient createDeleteClient() {
@@ -147,6 +152,21 @@
   }
 
   @NotNull
+  public VersionClient createVersionClient() {
+    return prepare(myVersionClient);
+  }
+
+  @NotNull
+  public ImportClient createImportClient() {
+    return prepare(myImportClient);
+  }
+
+  @NotNull
+  public ExportClient createExportClient() {
+    return prepare(myExportClient);
+  }
+
+  @NotNull
   protected <T extends SvnClient> T prepare(@NotNull T client) {
     client.setVcs(myVcs);
     client.setFactory(this);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
index e0849d9..8b73377 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
@@ -5,11 +5,13 @@
 import org.jetbrains.idea.svn.add.CmdAddClient;
 import org.jetbrains.idea.svn.annotate.CmdAnnotateClient;
 import org.jetbrains.idea.svn.change.CmdChangeListClient;
+import org.jetbrains.idea.svn.checkin.CmdImportClient;
 import org.jetbrains.idea.svn.checkout.CmdCheckoutClient;
+import org.jetbrains.idea.svn.checkout.CmdExportClient;
 import org.jetbrains.idea.svn.cleanup.CmdCleanupClient;
+import org.jetbrains.idea.svn.update.CmdUpdateClient;
 import org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient;
 import org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient;
-import org.jetbrains.idea.svn.commandLine.SvnCommandLineUpdateClient;
 import org.jetbrains.idea.svn.conflict.CmdConflictClient;
 import org.jetbrains.idea.svn.content.CmdContentClient;
 import org.jetbrains.idea.svn.copy.CmdCopyMoveClient;
@@ -17,7 +19,7 @@
 import org.jetbrains.idea.svn.history.CmdHistoryClient;
 import org.jetbrains.idea.svn.integrate.CmdMergeClient;
 import org.jetbrains.idea.svn.lock.CmdLockClient;
-import org.jetbrains.idea.svn.portable.SvnUpdateClientI;
+import org.jetbrains.idea.svn.update.UpdateClient;
 import org.jetbrains.idea.svn.properties.CmdPropertyClient;
 import org.jetbrains.idea.svn.revert.CmdRevertClient;
 import org.jetbrains.idea.svn.update.CmdRelocateClient;
@@ -48,13 +50,16 @@
     myLockClient = new CmdLockClient();
     myCleanupClient = new CmdCleanupClient();
     myRelocateClient = new CmdRelocateClient();
-    statusClient = new SvnCommandLineStatusClient(myVcs.getProject());
-    infoClient = new SvnCommandLineInfoClient(myVcs.getProject());
+    myVersionClient = new CmdVersionClient();
+    myImportClient = new CmdImportClient();
+    myExportClient = new CmdExportClient();
+    statusClient = new SvnCommandLineStatusClient(myVcs);
+    infoClient = new SvnCommandLineInfoClient(myVcs);
   }
 
   @NotNull
   @Override
-  public SvnUpdateClientI createUpdateClient() {
-    return new SvnCommandLineUpdateClient(myVcs, null);
+  public UpdateClient createUpdateClient() {
+    return prepare(new CmdUpdateClient());
   }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java
new file mode 100644
index 0000000..bc40a9f
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java
@@ -0,0 +1,80 @@
+package org.jetbrains.idea.svn.api;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.execution.process.CapturingProcessHandler;
+import com.intellij.execution.process.ProcessOutput;
+import com.intellij.openapi.util.Version;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnApplicationSettings;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdVersionClient extends BaseSvnClient implements VersionClient {
+
+  @NotNull
+  @Override
+  public Version getVersion() throws VcsException {
+    // TODO: Do not use common command running mechanism for now - to preserve timeout behavior.
+    ProcessOutput output;
+
+    try {
+      output = runCommand();
+    }
+    catch (ExecutionException e) {
+      throw new VcsException(e);
+    }
+
+    return parseVersion(output);
+  }
+
+  private static ProcessOutput runCommand() throws ExecutionException {
+    GeneralCommandLine commandLine = new GeneralCommandLine();
+    commandLine.setExePath(SvnApplicationSettings.getInstance().getCommandLinePath());
+    commandLine.addParameter(SvnCommandName.version.getName());
+    commandLine.addParameter("--quiet");
+
+    CapturingProcessHandler handler = new CapturingProcessHandler(commandLine.createProcess(), CharsetToolkit.getDefaultSystemCharset());
+    return handler.runProcess(30 * 1000);
+  }
+
+  @NotNull
+  private static Version parseVersion(@NotNull ProcessOutput output) throws VcsException {
+    if (output.isTimeout() || (output.getExitCode() != 0) || !output.getStderr().isEmpty()) {
+      throw new VcsException(
+        String.format("Exit code: %d, Error: %s, Timeout: %b", output.getExitCode(), output.getStderr(), output.isTimeout()));
+    }
+
+    return parseVersion(output.getStdout());
+  }
+
+  @NotNull
+  private static Version parseVersion(@NotNull String versionText) throws VcsException {
+    Version result = null;
+    Exception cause = null;
+    String[] parts = versionText.trim().split("\\.");
+
+    if (parts.length == 3) {
+      try {
+        result = new Version(getInt(parts[0]), getInt(parts[1]), getInt(parts[2]));
+      }
+      catch (NumberFormatException e) {
+        cause = e;
+      }
+    }
+
+    if (cause != null || result == null) {
+      throw new VcsException(String.format("Could not parse svn version: %s", versionText), cause);
+    }
+
+    return result;
+  }
+
+  private static int getInt(@NotNull String value) {
+    return Integer.parseInt(value);
+  }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
index c11226a..002820d 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
@@ -5,7 +5,9 @@
 import org.jetbrains.idea.svn.add.SvnKitAddClient;
 import org.jetbrains.idea.svn.annotate.SvnKitAnnotateClient;
 import org.jetbrains.idea.svn.change.SvnKitChangeListClient;
+import org.jetbrains.idea.svn.checkin.SvnKitImportClient;
 import org.jetbrains.idea.svn.checkout.SvnKitCheckoutClient;
+import org.jetbrains.idea.svn.checkout.SvnKitExportClient;
 import org.jetbrains.idea.svn.cleanup.SvnKitCleanupClient;
 import org.jetbrains.idea.svn.conflict.SvnKitConflictClient;
 import org.jetbrains.idea.svn.content.SvnKitContentClient;
@@ -14,8 +16,8 @@
 import org.jetbrains.idea.svn.history.SvnKitHistoryClient;
 import org.jetbrains.idea.svn.integrate.SvnKitMergeClient;
 import org.jetbrains.idea.svn.lock.SvnKitLockClient;
-import org.jetbrains.idea.svn.portable.SvnSvnkitUpdateClient;
-import org.jetbrains.idea.svn.portable.SvnUpdateClientI;
+import org.jetbrains.idea.svn.update.SvnKitUpdateClient;
+import org.jetbrains.idea.svn.update.UpdateClient;
 import org.jetbrains.idea.svn.portable.SvnkitSvnStatusClient;
 import org.jetbrains.idea.svn.portable.SvnkitSvnWcClient;
 import org.jetbrains.idea.svn.properties.SvnKitPropertyClient;
@@ -48,13 +50,16 @@
     myLockClient = new SvnKitLockClient();
     myCleanupClient = new SvnKitCleanupClient();
     myRelocateClient = new SvnKitRelocateClient();
-    statusClient = new SvnkitSvnStatusClient(myVcs.createStatusClient());
+    myVersionClient = new SvnKitVersionClient();
+    myImportClient = new SvnKitImportClient();
+    myExportClient = new SvnKitExportClient();
+    statusClient = new SvnkitSvnStatusClient(myVcs, null);
     infoClient = new SvnkitSvnWcClient(myVcs);
   }
 
   @NotNull
   @Override
-  public SvnUpdateClientI createUpdateClient() {
-    return new SvnSvnkitUpdateClient(myVcs.createUpdateClient());
+  public UpdateClient createUpdateClient() {
+    return prepare(new SvnKitUpdateClient());
   }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java
new file mode 100644
index 0000000..084f7f7
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java
@@ -0,0 +1,18 @@
+package org.jetbrains.idea.svn.api;
+
+import com.intellij.openapi.util.Version;
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.WorkingCopyFormat;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitVersionClient extends BaseSvnClient implements VersionClient {
+
+  @NotNull
+  @Override
+  public Version getVersion() throws VcsException {
+    return WorkingCopyFormat.ONE_DOT_SEVEN.getVersion();
+  }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java
new file mode 100644
index 0000000..bbd7092
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java
@@ -0,0 +1,14 @@
+package org.jetbrains.idea.svn.api;
+
+import com.intellij.openapi.util.Version;
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface VersionClient extends SvnClient {
+
+  @NotNull
+  Version getVersion() throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdImportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdImportClient.java
new file mode 100644
index 0000000..d6cb894
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdImportClient.java
@@ -0,0 +1,51 @@
+package org.jetbrains.idea.svn.checkin;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.CommitEventHandler;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.jetbrains.idea.svn.commandLine.SvnCommitRunner;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.ISVNCommitHandler;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdImportClient extends BaseSvnClient implements ImportClient {
+
+  @Override
+  public long doImport(@NotNull File path,
+                       @NotNull SVNURL url,
+                       @Nullable SVNDepth depth,
+                       @NotNull String message,
+                       boolean noIgnore,
+                       @Nullable CommitEventHandler handler,
+                       @Nullable ISVNCommitHandler commitHandler) throws VcsException {
+    // TODO: ISVNFileFilter from ISVNCommitHandler is not currently implemented
+
+    List<String> parameters = new ArrayList<String>();
+
+    CommandUtil.put(parameters, path, false);
+    CommandUtil.put(parameters, SvnTarget.fromURL(url), false);
+    CommandUtil.put(parameters, depth);
+    CommandUtil.put(parameters, noIgnore, "--no-ignore");
+    parameters.add("--message");
+    parameters.add(message);
+
+    SvnCommitRunner.CommandListener listener = new SvnCommitRunner.CommandListener(handler);
+    listener.setBaseDirectory(path);
+
+    CommandUtil.execute(myVcs, SvnTarget.fromURL(url), SvnCommandName.importFolder, parameters, listener);
+
+    return listener.getCommittedRevision();
+  }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
index 7c68e86..8a4b203 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
@@ -94,6 +94,8 @@
       result = CommitEventType.replacing;
     } else if (SVNEventAction.COMMIT_DELTA_SENT.equals(action)) {
       result = CommitEventType.transmittingDeltas;
+    } else if (SVNEventAction.SKIP.equals(action)) {
+      result = CommitEventType.skipped;
     }
 
     if (result == null) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/ImportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/ImportClient.java
new file mode 100644
index 0000000..2a8a549
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/ImportClient.java
@@ -0,0 +1,26 @@
+package org.jetbrains.idea.svn.checkin;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.jetbrains.idea.svn.commandLine.CommitEventHandler;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.ISVNCommitHandler;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface ImportClient extends SvnClient {
+
+  long doImport(@NotNull File path,
+                @NotNull SVNURL url,
+                @Nullable SVNDepth depth,
+                @NotNull String message,
+                boolean noIgnore,
+                @Nullable CommitEventHandler handler,
+                @Nullable ISVNCommitHandler commitHandler) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
index 8e2e10d8..c1f3ede 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
@@ -178,7 +178,7 @@
       return;
     }
     if (WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) || WorkingCopyFormat.ONE_DOT_SEVEN.equals(format) &&
-        SvnConfiguration.UseAcceleration.commandLine.equals(SvnConfiguration.getInstance(mySvnVcs.getProject()).myUseAcceleration) &&
+        SvnConfiguration.getInstance(mySvnVcs.getProject()).isCommandLine() &&
         (SvnAuthenticationManager.HTTP.equals(url.getProtocol()) || SvnAuthenticationManager.HTTPS.equals(url.getProtocol()))) {
       doWithCommandLine(committables, comment, exception, feedback);
       return;
@@ -282,7 +282,7 @@
     if (! childrenOfSomebody.isEmpty()) {
       final HashSet<File> result = new HashSet<File>(committables);
       result.removeAll(childrenOfSomebody);
-      final SvnCommandLineStatusClient statusClient = new SvnCommandLineStatusClient(mySvnVcs.getProject());
+      final SvnCommandLineStatusClient statusClient = new SvnCommandLineStatusClient(mySvnVcs);
       for (File file : childrenOfSomebody) {
         try {
           final SVNStatus status = statusClient.doStatus(file, false);
@@ -385,7 +385,7 @@
   }
 
   private SVNStatus getStatusCommandLine(File file) throws SVNException {
-    return new SvnCommandLineStatusClient(mySvnVcs.getProject()).doStatus(file, false);
+    return new SvnCommandLineStatusClient(mySvnVcs).doStatus(file, false);
   }
 
   private static List<File> collectPaths(final List<Change> changes) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnKitImportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnKitImportClient.java
new file mode 100644
index 0000000..838e764
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnKitImportClient.java
@@ -0,0 +1,44 @@
+package org.jetbrains.idea.svn.checkin;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommitEventHandler;
+import org.jetbrains.idea.svn.commandLine.SvnBindException;
+import org.tmatesoft.svn.core.SVNCommitInfo;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.ISVNCommitHandler;
+import org.tmatesoft.svn.core.wc.SVNCommitClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitImportClient extends BaseSvnClient implements ImportClient {
+
+  @Override
+  public long doImport(@NotNull File path,
+                       @NotNull SVNURL url,
+                       @Nullable SVNDepth depth,
+                       @NotNull String message,
+                       boolean noIgnore,
+                       @Nullable CommitEventHandler handler,
+                       @Nullable ISVNCommitHandler commitHandler) throws VcsException {
+    SVNCommitClient client = myVcs.createCommitClient();
+
+    client.setEventHandler(handler);
+    client.setCommitHandler(commitHandler);
+
+    try {
+      SVNCommitInfo info = client.doImport(path, url, message, null, !noIgnore, false, depth);
+      return info.getNewRevision();
+    }
+    catch (SVNException e) {
+      throw new SvnBindException(e);
+    }
+  }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutEventHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutEventHandler.java
index 3650696..88f2a69 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutEventHandler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutEventHandler.java
@@ -19,6 +19,8 @@
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.wm.StatusBar;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.SvnBundle;
 import org.jetbrains.idea.svn.SvnUtil;
 import org.jetbrains.idea.svn.SvnVcs;
@@ -30,13 +32,13 @@
 import org.tmatesoft.svn.core.wc.SVNEventAction;
 
 public class CheckoutEventHandler implements ISVNEventHandler {
-  private final ProgressIndicator myIndicator;
+  @Nullable private final ProgressIndicator myIndicator;
   private int myExternalsCount;
-  private final SvnVcs myVCS;
+  @NotNull private final SvnVcs myVCS;
   private final boolean myIsExport;
   private int myCnt;
 
-  public CheckoutEventHandler(SvnVcs vcs, boolean isExport, ProgressIndicator indicator) {
+  public CheckoutEventHandler(@NotNull SvnVcs vcs, boolean isExport, @Nullable ProgressIndicator indicator) {
     myIndicator = indicator;
     myVCS = vcs;
     myExternalsCount = 1;
@@ -51,16 +53,17 @@
     }
     if (event.getAction() == SVNEventAction.UPDATE_EXTERNAL) {
       myExternalsCount++;
-      ProgressManager.progress(SvnBundle.message("progress.text2.fetching.external.location", event.getFile().getAbsolutePath()), "");
+      progress(SvnBundle.message("progress.text2.fetching.external.location", event.getFile().getAbsolutePath()));
     }
     else if (event.getAction() == SVNEventAction.UPDATE_ADD) {
-      ProgressManager.progress2(SvnBundle.message(myIsExport ? "progress.text2.exported" : "progress.text2.checked.out", event.getFile().getName(), myCnt));
+      progress2(SvnBundle.message(myIsExport ? "progress.text2.exported" : "progress.text2.checked.out", event.getFile().getName(), myCnt));
       ++ myCnt;
     }
     else if (event.getAction() == SVNEventAction.UPDATE_COMPLETED) {
       myExternalsCount--;
-      ProgressManager.progress2((SvnBundle.message(myIsExport ? "progress.text2.exported.revision" : "progress.text2.checked.out.revision", event.getRevision())));
-      if (myExternalsCount == 0 && event.getRevision() >= 0 && myVCS != null) {
+      progress2(
+        (SvnBundle.message(myIsExport ? "progress.text2.exported.revision" : "progress.text2.checked.out.revision", event.getRevision())));
+      if (myExternalsCount == 0 && event.getRevision() >= 0) {
         myExternalsCount = 1;
         Project project = myVCS.getProject();
         if (project != null) {
@@ -68,9 +71,9 @@
         }
       }
     } else if (event.getAction() == SVNEventAction.COMMIT_ADDED) {
-      ProgressManager.progress2((SvnBundle.message("progress.text2.adding", path)));
+      progress2((SvnBundle.message("progress.text2.adding", path)));
     } else if (event.getAction() == SVNEventAction.COMMIT_DELTA_SENT) {
-      ProgressManager.progress2((SvnBundle.message("progress.text2.transmitting.delta", path)));
+      progress2((SvnBundle.message("progress.text2.transmitting.delta", path)));
     }
   }
 
@@ -79,4 +82,23 @@
       throw new SVNCancelException(SVNErrorMessage.create(SVNErrorCode.CANCELLED, "Operation cancelled"));
     }
   }
+
+  private void progress(@NotNull String text) {
+    if (myIndicator != null) {
+      myIndicator.checkCanceled();
+      myIndicator.setText(text);
+      myIndicator.setText2("");
+    } else {
+      ProgressManager.progress(text);
+    }
+  }
+
+  private void progress2(@NotNull String text) {
+    if (myIndicator != null) {
+      myIndicator.checkCanceled();
+      myIndicator.setText2(text);
+    } else {
+      ProgressManager.progress2(text);
+    }
+  }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdExportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdExportClient.java
new file mode 100644
index 0000000..6bff70f
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdExportClient.java
@@ -0,0 +1,53 @@
+package org.jetbrains.idea.svn.checkout;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.BaseUpdateCommandListener;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdExportClient extends BaseSvnClient implements ExportClient {
+
+  @Override
+  public void export(@NotNull SvnTarget from,
+                     @NotNull File to,
+                     @Nullable SVNRevision revision,
+                     @Nullable SVNDepth depth,
+                     @Nullable String nativeLineEnd,
+                     boolean force,
+                     boolean ignoreExternals,
+                     @Nullable ISVNEventHandler handler) throws VcsException {
+    List<String> parameters = new ArrayList<String>();
+
+    CommandUtil.put(parameters, from);
+    CommandUtil.put(parameters, to);
+    CommandUtil.put(parameters, revision);
+    CommandUtil.put(parameters, depth);
+    CommandUtil.put(parameters, force, "--force");
+    CommandUtil.put(parameters, ignoreExternals, "--ignore-externals");
+    if (!StringUtil.isEmpty(nativeLineEnd)) {
+      parameters.add("--native-eol");
+      parameters.add(nativeLineEnd);
+    }
+
+    BaseUpdateCommandListener listener = new BaseUpdateCommandListener(to, handler);
+
+    CommandUtil.execute(myVcs, from, to, SvnCommandName.export, parameters, listener);
+
+    listener.throwWrappedIfException();
+  }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/ExportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/ExportClient.java
new file mode 100644
index 0000000..6ddd6de
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/ExportClient.java
@@ -0,0 +1,27 @@
+package org.jetbrains.idea.svn.checkout;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface ExportClient extends SvnClient {
+
+  void export(@NotNull SvnTarget from,
+              @NotNull File to,
+              @Nullable SVNRevision revision,
+              @Nullable SVNDepth depth,
+              @Nullable String nativeLineEnd,
+              boolean force,
+              boolean ignoreExternals,
+              @Nullable ISVNEventHandler handler) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java
index 7b0ed8c..ff415a0 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java
@@ -33,11 +33,14 @@
 import com.intellij.openapi.vcs.update.RefreshVFsSynchronously;
 import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.StatusBar;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.*;
 import org.jetbrains.idea.svn.actions.ExclusiveBackgroundVcsAction;
 import org.jetbrains.idea.svn.actions.SvnExcludingIgnoredOperation;
+import org.jetbrains.idea.svn.checkin.IdeaCommitHandler;
+import org.jetbrains.idea.svn.commandLine.CommitEventHandler;
 import org.jetbrains.idea.svn.dialogs.CheckoutDialog;
 import org.tmatesoft.svn.core.SVNCancelException;
 import org.tmatesoft.svn.core.SVNDepth;
@@ -62,13 +65,11 @@
       target.mkdirs();
     }
 
-    final String selectedFormat = promptForWCopyFormat(target, project);
-    if (selectedFormat == null) {
-      // cancelled
-      return;
+    final WorkingCopyFormat selectedFormat = promptForWCopyFormat(target, project);
+    // UNKNOWN here means operation was cancelled
+    if (selectedFormat != WorkingCopyFormat.UNKNOWN) {
+      checkout(project, target, url, revision, depth, ignoreExternals, listener, selectedFormat);
     }
-
-    checkout(project, target, url, revision, depth, ignoreExternals, listener, WorkingCopyFormat.getInstance(selectedFormat));
   }
 
   public static void checkout(final Project project,
@@ -168,52 +169,50 @@
   }
 
   public static boolean promptForWCFormatAndSelect(final File target, final Project project) {
-    final String result = promptForWCopyFormat(target, project);
-    if (result != null) {
-      SvnWorkingCopyFormatHolder.setPresetFormat(WorkingCopyFormat.getInstance(result));
+    final WorkingCopyFormat result = promptForWCopyFormat(target, project);
+    if (result != WorkingCopyFormat.UNKNOWN) {
+      SvnWorkingCopyFormatHolder.setPresetFormat(result);
     }
-    return result != null;
+    return result != WorkingCopyFormat.UNKNOWN;
   }
 
-  @Nullable
-  private static String promptForWCopyFormat(final File target, final Project project) {
-    String formatMode = null;
+  @NotNull
+  private static WorkingCopyFormat promptForWCopyFormat(final File target, final Project project) {
+    WorkingCopyFormat format = WorkingCopyFormat.UNKNOWN;
     final Ref<Boolean> wasOk = new Ref<Boolean>();
-    while ((formatMode == null) && (! Boolean.FALSE.equals(wasOk.get()))) {
-      formatMode = SvnFormatSelector.showUpgradeDialog(target, project, true, SvnConfiguration.UPGRADE_AUTO_17, wasOk);
+    while ((format == WorkingCopyFormat.UNKNOWN) && (! Boolean.FALSE.equals(wasOk.get()))) {
+      format = SvnFormatSelector.showUpgradeDialog(target, project, true, WorkingCopyFormat.ONE_DOT_SEVEN, wasOk);
     }
-    return Boolean.TRUE.equals(wasOk.get()) ? formatMode : null;
+    return Boolean.TRUE.equals(wasOk.get()) ? format : WorkingCopyFormat.UNKNOWN;
   }
 
-  public static void doExport(final Project project, final File target, final String url, final SVNDepth depth,
+  public static void doExport(final Project project, final File target, final SVNURL url, final SVNDepth depth,
                               final boolean ignoreExternals, final boolean force, final String eolStyle) {
     try {
-      final SVNException[] exception = new SVNException[1];
-      final SVNUpdateClient client = SvnVcs.getInstance(project).createUpdateClient();
+      final VcsException[] exception = new VcsException[1];
+      final SvnVcs vcs = SvnVcs.getInstance(project);
 
       ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
         public void run() {
           ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
-          client.setEventHandler(new CheckoutEventHandler(SvnVcs.getInstance(project), true, progressIndicator));
-          client.setIgnoreExternals(ignoreExternals);
+          ISVNEventHandler handler = new CheckoutEventHandler(vcs, true, progressIndicator);
           try {
             progressIndicator.setText(SvnBundle.message("progress.text.export", target.getAbsolutePath()));
-            client.doExport(SVNURL.parseURIEncoded(url), target, SVNRevision.UNDEFINED, SVNRevision.HEAD, eolStyle, force, depth);
+
+            SvnTarget from = SvnTarget.fromURL(url);
+            ExportClient client = vcs.getFactoryFromSettings().createExportClient();
+            client.export(from, target, SVNRevision.HEAD, depth, eolStyle, force, ignoreExternals, handler);
           }
-          catch (SVNException e) {
+          catch (VcsException e) {
             exception[0] = e;
           }
-          finally {
-            client.setIgnoreExternals(false);
-            client.setEventHandler(null);
-          }
         }
       }, SvnBundle.message("message.title.export"), true, project);
       if (exception[0] != null) {
         throw exception[0];
       }
     }
-    catch (SVNException e1) {
+    catch (VcsException e1) {
       Messages.showErrorDialog(SvnBundle.message("message.text.cannot.export", e1.getMessage()), SvnBundle.message("message.title.export"));
     }
   }
@@ -221,7 +220,7 @@
   public static void doImport(final Project project, final File target, final SVNURL url, final SVNDepth depth,
                               final boolean includeIgnored, final String message) {
     final Ref<String> errorMessage = new Ref<String>();
-    final SVNCommitClient client = SvnVcs.getInstance(project).createCommitClient();
+    final SvnVcs vcs = SvnVcs.getInstance(project);
     final String targetPath = FileUtil.toSystemIndependentName(target.getAbsolutePath());
 
     ExclusiveBackgroundVcsAction.run(project, new Runnable() {
@@ -230,7 +229,6 @@
           public void run() {
             final FileIndexFacade facade = PeriodicalTasksCloser.getInstance().safeGetService(project, FileIndexFacade.class);
             ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
-            client.setEventHandler(new CheckoutEventHandler(SvnVcs.getInstance(project), true, progressIndicator));
             try {
               progressIndicator.setText(SvnBundle.message("progress.text.import", target.getAbsolutePath()));
 
@@ -244,22 +242,21 @@
                     return facade.isInContent(targetVf);
                   }
                 });
-                if (project.isDefault() || !isInContent) {
-                  // do not pay attention to ignored/excluded settings
-                  client.doImport(target, url, message, null, !includeIgnored, false, depth);
-                } else {
-                  client.setCommitHandler(new MyFilter(LocalFileSystem.getInstance(), new SvnExcludingIgnoredOperation.Filter(project)));
-                  client.doImport(target, url, message, null, !includeIgnored, false, depth);
+                CommitEventHandler handler = new IdeaCommitHandler(progressIndicator);
+                boolean useFileFilter = !project.isDefault() && isInContent;
+                ISVNCommitHandler commitHandler =
+                  useFileFilter ? new MyFilter(LocalFileSystem.getInstance(), new SvnExcludingIgnoredOperation.Filter(project)) : null;
+                long revision = vcs.getFactoryFromSettings().createImportClient()
+                  .doImport(target, url, depth, message, includeIgnored, handler, commitHandler);
+
+                if (revision > 0) {
+                  StatusBar.Info.set(SvnBundle.message("status.text.comitted.revision", revision), project);
                 }
               }
             }
-            catch (SVNException e) {
+            catch (VcsException e) {
               errorMessage.set(e.getMessage());
             }
-            finally {
-              client.setIgnoreExternals(false);
-              client.setEventHandler(null);
-            }
           }
         }, SvnBundle.message("message.title.import"), true, project);
       }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitExportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitExportClient.java
new file mode 100644
index 0000000..f04c749
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitExportClient.java
@@ -0,0 +1,48 @@
+package org.jetbrains.idea.svn.checkout;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.SvnBindException;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc.SVNUpdateClient;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitExportClient extends BaseSvnClient implements ExportClient {
+
+  @Override
+  public void export(@NotNull SvnTarget from,
+                     @NotNull File to,
+                     @Nullable SVNRevision revision,
+                     @Nullable SVNDepth depth,
+                     @Nullable String nativeLineEnd,
+                     boolean force,
+                     boolean ignoreExternals,
+                     @Nullable ISVNEventHandler handler) throws VcsException {
+    SVNUpdateClient client = myVcs.createUpdateClient();
+
+    client.setEventHandler(handler);
+    client.setIgnoreExternals(ignoreExternals);
+
+    try {
+      if (from.isFile()) {
+        client.doExport(from.getFile(), to, from.getPegRevision(), revision, nativeLineEnd, force, depth);
+      }
+      else {
+        client.doExport(from.getURL(), to, from.getPegRevision(), revision, nativeLineEnd, force, depth);
+      }
+    }
+    catch (SVNException e) {
+      throw new SvnBindException(e);
+    }
+  }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
index 393cccc..0279eba 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
@@ -103,9 +103,18 @@
   }
 
   public static void put(@NotNull List<String> parameters, @Nullable SVNDepth depth) {
+    put(parameters, depth, false);
+  }
+
+  public static void put(@NotNull List<String> parameters, @Nullable SVNDepth depth, boolean sticky) {
     if (depth != null && !SVNDepth.UNKNOWN.equals(depth)) {
       parameters.add("--depth");
       parameters.add(depth.getName());
+
+      if (sticky) {
+        parameters.add("--set-depth");
+        parameters.add(depth.getName());
+      }
     }
   }
 
@@ -148,6 +157,16 @@
     }
   }
 
+  public static String escape(@NotNull String path) {
+    String result = path;
+
+    if (path.contains("@")) {
+      result += "@";
+    }
+
+    return result;
+  }
+
   public static <T> T parse(@NotNull String data, @NotNull Class<T> type) throws JAXBException {
     JAXBContext context = JAXBContext.newInstance(type);
     Unmarshaller unmarshaller = context.createUnmarshaller();
@@ -171,8 +190,18 @@
                                    @NotNull SvnCommandName name,
                                    @NotNull List<String> parameters,
                                    @Nullable LineCommandListener listener) throws VcsException {
-    SVNURL repositoryUrl = resolveRepositoryUrl(vcs, name, target);
     File workingDirectory = resolveWorkingDirectory(vcs, target);
+
+    return execute(vcs, target, workingDirectory, name, parameters, listener);
+  }
+
+  public static SvnCommand execute(@NotNull SvnVcs vcs,
+                                   @NotNull SvnTarget target,
+                                   @NotNull File workingDirectory,
+                                   @NotNull SvnCommandName name,
+                                   @NotNull List<String> parameters,
+                                   @Nullable LineCommandListener listener) throws VcsException {
+    SVNURL repositoryUrl = resolveRepositoryUrl(vcs, name, target);
     IdeaSvnkitBasedAuthenticationCallback callback = new IdeaSvnkitBasedAuthenticationCallback(vcs);
 
     return SvnLineCommand.runWithAuthenticationAttempt(workingDirectory, repositoryUrl, name,
@@ -180,6 +209,11 @@
                                                        ArrayUtil.toStringArray(parameters));
   }
 
+  @NotNull
+  public static File getHomeDirectory() {
+    return new File(PathManager.getHomePath());
+  }
+
   private static SVNURL resolveRepositoryUrl(@NotNull SvnVcs vcs, @NotNull SvnCommandName name, @NotNull SvnTarget target) {
     RootUrlInfo rootInfo = target.isFile()
                            ? vcs.getSvnFileUrlMapping().getWcRootForFilePath(target.getFile())
@@ -204,7 +238,7 @@
 
     if (workingDirectory == null) {
       workingDirectory =
-        !vcs.getProject().isDefault() ? VfsUtilCore.virtualToIoFile(vcs.getProject().getBaseDir()) : new File(PathManager.getHomePath());
+        !vcs.getProject().isDefault() ? VfsUtilCore.virtualToIoFile(vcs.getProject().getBaseDir()) : getHomeDirectory();
     }
 
     return workingDirectory;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java
index 87dc212..f0c6df7 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java
@@ -27,7 +27,8 @@
   sending("Sending"),
   replacing("Replacing"),
   transmittingDeltas("Transmitting file data"),
-  committedRevision("Committed revision");
+  committedRevision("Committed revision"),
+  skipped("Skipped");
 
   private final String myText;
 
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
index 766d95a..0e93b54 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
@@ -56,12 +56,11 @@
 
   private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient");
 
-  @NotNull
-  private final Project myProject;
+  @NotNull private final SvnVcs myVcs;
 
-  public SvnCommandLineInfoClient(@NotNull final Project project) {
-    super(SvnVcs.getInstance(project));
-    myProject = project;
+  public SvnCommandLineInfoClient(@NotNull final SvnVcs vcs) {
+    super(vcs);
+    myVcs = vcs;
   }
 
   @Override
@@ -118,8 +117,7 @@
     };
 
     try {
-      SvnCommand command =
-        CommandUtil.execute(SvnVcs.getInstance(myProject), SvnTarget.fromFile(path), SvnCommandName.info, parameters, listener);
+      SvnCommand command = CommandUtil.execute(myVcs, SvnTarget.fromFile(path), SvnCommandName.info, parameters, listener);
 
       return command.getOutput();
     }
@@ -217,7 +215,7 @@
     fillParameters(path, pegRevision, revision, depth, parameters);
     SvnCommand command;
     try {
-      command = CommandUtil.execute(SvnVcs.getInstance(myProject), SvnTarget.fromURL(url), SvnCommandName.info, parameters, null);
+      command = CommandUtil.execute(myVcs, SvnTarget.fromURL(url), SvnCommandName.info, parameters, null);
     }
     catch (VcsException e) {
       throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
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 1cdf15f..14c701b 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
@@ -16,7 +16,6 @@
 package org.jetbrains.idea.svn.commandLine;
 
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Getter;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
@@ -53,12 +52,12 @@
 public class SvnCommandLineStatusClient implements SvnStatusClientI {
   private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient");
 
-  private final Project myProject;
   private final SvnCommandLineInfoClient myInfoClient;
+  @NotNull private final SvnVcs myVcs;
 
-  public SvnCommandLineStatusClient(Project project) {
-    myProject = project;
-    myInfoClient = new SvnCommandLineInfoClient(project);
+  public SvnCommandLineStatusClient(@NotNull SvnVcs vcs) {
+    myVcs = vcs;
+    myInfoClient = new SvnCommandLineInfoClient(vcs);
   }
 
   @Override
@@ -111,7 +110,7 @@
 
     SvnCommand command;
     try {
-      command = CommandUtil.execute(SvnVcs.getInstance(myProject), SvnTarget.fromFile(path), SvnCommandName.st, parameters, null);
+      command = CommandUtil.execute(myVcs, SvnTarget.fromFile(path), SvnCommandName.st, parameters, null);
     }
     catch (VcsException e) {
       throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
@@ -139,7 +138,7 @@
       SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
       parser.parse(new ByteArrayInputStream(result.getBytes(CharsetToolkit.UTF8_CHARSET)), svnHandl[0]);
       if (!svnHandl[0].isAnythingReported()) {
-        if (!SvnUtil.isSvnVersioned(myProject, path)) {
+        if (!SvnUtil.isSvnVersioned(myVcs, path)) {
           throw new SVNException(
             SVNErrorMessage.create(SVNErrorCode.WC_NOT_DIRECTORY, "Command - " + command.getCommandText() + ". Result - " + result));
         } else {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
deleted file mode 100644
index 06901ea..0000000
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
+++ /dev/null
@@ -1,233 +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 org.jetbrains.idea.svn.commandLine;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vcs.VcsException;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.idea.svn.SvnVcs;
-import org.jetbrains.idea.svn.portable.SvnSvnkitUpdateClient;
-import org.tmatesoft.svn.core.*;
-import org.tmatesoft.svn.core.wc.*;
-import org.tmatesoft.svn.core.wc2.SvnTarget;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/1/12
- * Time: 12:13 PM
- */
-public class SvnCommandLineUpdateClient extends SvnSvnkitUpdateClient {
-  private static final Pattern ourExceptionPattern = Pattern.compile("svn: E(\\d{6}): .+");
-  private static final String ourAuthenticationRealm = "Authentication realm:";
-  private final Project myProject;
-  private final VirtualFile myCommonAncestor;
-  private boolean myIgnoreExternals;
-  private SvnVcs myVcs;
-
-  public SvnCommandLineUpdateClient(final SvnVcs vcs, VirtualFile commonAncestor) {
-    super(vcs.createUpdateClient());
-    myVcs = vcs;
-    myProject = vcs.getProject();
-    myCommonAncestor = commonAncestor;
-  }
-
-  @Override
-  public long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException {
-    final long[] longs = doUpdate(new File[]{file}, revision, SVNDepth.fromRecurse(recursive), false, false, false);
-    return longs[0];
-  }
-
-  @Override
-  public long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException {
-    final long[] longs = doUpdate(new File[]{file}, revision, SVNDepth.fromRecurse(recursive), force, false, false);
-    return longs[0];
-  }
-
-  @Override
-  public long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
-    throws SVNException {
-    return doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, false);
-  }
-
-  @Override
-  public long[] doUpdate(final File[] paths, final SVNRevision revision, final SVNDepth depth, final boolean allowUnversionedObstructions,
-                         final boolean depthIsSticky, final boolean makeParents) throws SVNException {
-    // since one revision is passed -> I assume same repository here
-    final SvnCommandLineInfoClient infoClient = new SvnCommandLineInfoClient(myProject);
-    final SVNInfo info = infoClient.doInfo(paths[0], SVNRevision.UNDEFINED);
-    if (info == null || info.getURL() == null) {
-      throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY, paths[0].getPath()));
-    }
-    final AtomicReference<long[]> updatedToRevision = new AtomicReference<long[]>();
-    updatedToRevision.set(new long[0]);
-
-    File base = myCommonAncestor == null ? paths[0] : new File(myCommonAncestor.getPath());
-    base = base.isDirectory() ? base : base.getParentFile();
-
-    final List<String> parameters = prepareParameters(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents);
-    final BaseUpdateCommandListener listener = createCommandListener(paths, updatedToRevision, base);
-    try {
-      CommandUtil.execute(myVcs, SvnTarget.fromFile(base), SvnCommandName.up, parameters, listener);
-    }
-    catch (VcsException e) {
-      throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e));
-    }
-
-    listener.throwIfException();
-
-    return updatedToRevision.get();
-  }
-
-  private BaseUpdateCommandListener createCommandListener(final File[] paths,
-                                                          final AtomicReference<long[]> updatedToRevision,
-                                                          final File base) {
-    return new BaseUpdateCommandListener(base, getEventHandler()) {
-      final long[] myRevisions = new long[paths.length];
-
-      @Override
-      protected void beforeHandler(@NotNull SVNEvent event) {
-        if (SVNEventAction.UPDATE_COMPLETED.equals(event.getAction())) {
-          final long eventRevision = event.getRevision();
-          for (int i = 0; i < paths.length; i++) {
-            final File path = paths[i];
-            if (FileUtil.filesEqual(path, event.getFile())) {
-              myRevisions[i] = eventRevision;
-              break;
-            }
-          }
-        }
-      }
-
-      @Override
-      public void processTerminated(int exitCode) {
-        super.processTerminated(exitCode);
-        updatedToRevision.set(myRevisions);
-      }
-    };
-  }
-
-  private List<String> prepareParameters(File[] paths,
-                                         SVNRevision revision,
-                                         SVNDepth depth,
-                                         boolean allowUnversionedObstructions,
-                                         boolean depthIsSticky, boolean makeParents) {
-    List<String> parameters = new ArrayList<String>();
-
-    CommandUtil.put(parameters, revision);
-    CommandUtil.put(parameters, depth);
-    CommandUtil.put(parameters, allowUnversionedObstructions, "--force");
-    if (depthIsSticky && depth != null) {// !!! not sure, but not used
-      parameters.add("--set-depth");
-      parameters.add(depth.toString());
-    }
-    CommandUtil.put(parameters, makeParents, "--parents");
-    CommandUtil.put(parameters, myIgnoreExternals, "--ignore-externals");
-    parameters.add("--accept");
-    parameters.add("postpone");
-    CommandUtil.put(parameters, paths);
-
-    return parameters;
-  }
-
-
-  private void checkForException(final StringBuffer sbError) throws SVNException {
-    if (sbError.length() == 0) return;
-    final String message = sbError.toString();
-    final Matcher matcher = ourExceptionPattern.matcher(message);
-    if (matcher.matches()) {
-      final String group = matcher.group(1);
-      if (group != null) {
-        try {
-          final int code = Integer.parseInt(group);
-          throw new SVNException(SVNErrorMessage.create(SVNErrorCode.getErrorCode(code), message));
-        } catch (NumberFormatException e) {
-          //
-        }
-      }
-    }
-    if (message.contains(ourAuthenticationRealm)) {
-      throw new SVNException(SVNErrorMessage.create(SVNErrorCode.AUTHN_CREDS_UNAVAILABLE, message));
-    }
-    throw new SVNException(SVNErrorMessage.create(SVNErrorCode.UNKNOWN, message));
- }
-
-  @Override
-  public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
-    throws SVNException {
-    final long[] longs = doUpdate(new File[]{path}, revision, depth, allowUnversionedObstructions, depthIsSticky, false);
-    return longs[0];
-  }
-
-  @Override
-  public long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException {
-    throw new UnsupportedOperationException();
-    //return super.doSwitch(file, url, revision, recursive);
-  }
-
-  @Override
-  public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException {
-    throw new UnsupportedOperationException();
-    //return super.doSwitch(file, url, pegRevision, revision, recursive);
-  }
-
-  @Override
-  public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force)
-    throws SVNException {
-    throw new UnsupportedOperationException();
-    //return super.doSwitch(file, url, pegRevision, revision, recursive, force);
-  }
-
-  @Override
-  public long doSwitch(File path,
-                       SVNURL url,
-                       SVNRevision pegRevision,
-                       SVNRevision revision,
-                       SVNDepth depth,
-                       boolean allowUnversionedObstructions,
-                       boolean depthIsSticky) throws SVNException {
-    throw new UnsupportedOperationException();
-    //return super.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky);
-  }
-
-  @Override
-  public long doSwitch(File path,
-                       SVNURL url,
-                       SVNRevision pegRevision,
-                       SVNRevision revision,
-                       SVNDepth depth,
-                       boolean allowUnversionedObstructions,
-                       boolean depthIsSticky,
-                       boolean ignoreAncestry) throws SVNException {
-    throw new UnsupportedOperationException();
-    // todo MAIN
-    //return super.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky, ignoreAncestry);
-  }
-
-  @Override
-  public void setIgnoreExternals(boolean ignoreExternals) {
-    myIgnoreExternals = ignoreExternals;
-  }
-}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
index 72fd465..9182d937 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
@@ -26,6 +26,7 @@
   info("info", false),
   st("st", false),
   up("up", true),
+  switchCopy("switch", true),
   relocate("relocate", true),
   ci("commit", true),
   checkout("checkout", true),
@@ -46,7 +47,9 @@
   merge("merge", true),
   changelist("changelist", true),
   lock("lock", true),
-  unlock("unlock", true);
+  unlock("unlock", true),
+  importFolder("import", false),
+  export("export", false);
 
   private final String myName;
   private final boolean myWriteable;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java
index 1f93976..cf13f126 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java
@@ -29,6 +29,8 @@
 
 import java.io.File;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Created with IntelliJ IDEA.
@@ -94,6 +96,14 @@
   }
 
   public static class CommandListener extends LineCommandListener {
+
+    // Status could contain spaces, like "Adding copy of   <path>". But at the end we are not interested in "copy of" part and want to have
+    // only "Adding" in match group.
+    private static final String STATUS = "\\s*(\\w+)(.*?)\\s\\s+";
+    private static final String OPTIONAL_FILE_TYPE = "(\\(.*\\))?";
+    private static final String PATH = "\\s*(.*?)\\s*";
+    private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + OPTIONAL_FILE_TYPE + PATH);
+
     @Nullable private final CommitEventHandler myHandler;
     private SvnBindException myException;
     private long myCommittedRevision = Revision.SVN_INVALID_REVNUM;
@@ -138,6 +148,24 @@
         }
         return;
       }
+      if (line.startsWith(CommitEventType.skipped.getText())) {
+        File target = null;
+        if (myHandler != null) {
+          int pathStart = line.indexOf('\'');
+          if (pathStart > -1) {
+            int pathEnd = line.indexOf('\'', pathStart + 1);
+            if (pathEnd > -1) {
+              target = toFile(line.substring(pathStart + 1, pathEnd));
+            }
+          }
+          if (target != null) {
+            myHandler.commitEvent(CommitEventType.skipped, myBase);
+          } else {
+            LOG.info("Can not parse 'Skipped' path " + line);
+          }
+        }
+        return;
+      }
       if (line.startsWith(CommitEventType.committedRevision.getText())) {
         final String substring = line.substring(CommitEventType.committedRevision.getText().length());
         int cnt = 0;
@@ -167,26 +195,34 @@
         }
       } else {
         if (myHandler == null) return;
-        // status and path are separated by several spaces
-        final int idxSpace = line.indexOf("  ");
-        if (idxSpace == -1) {
-          LOG.info("Can not parse event type: " + line);
-          return;
+
+        Matcher matcher = CHANGED_PATH.matcher(line);
+        if (matcher.matches()) {
+          final CommitEventType type = CommitEventType.create(matcher.group(1));
+          if (type == null) {
+            LOG.info("Can not parse event type: " + line);
+            return;
+          }
+          myHandler.commitEvent(type, toFile(matcher.group(4)));
+        } else {
+          LOG.info("Can not parse output: " + line);
         }
-        final CommitEventType type = CommitEventType.create(line.substring(0, idxSpace));
-        if (type == null) {
-          LOG.info("Can not parse event type: " + line);
-          return;
-        }
-        File target = new File(new String(line.substring(idxSpace + 1).trim()));
-        if (!target.isAbsolute()) {
-          target = new File(myBase, target.getPath());
-        }
-        myHandler.commitEvent(type, target);
       }
     }
+
+    @NotNull
+    private File toFile(@NotNull String path) {
+      File result = new File(path);
+
+      if (!result.isAbsolute()) {
+        result = new File(myBase, result.getPath());
+      }
+
+      return result;
+    }
   }
 
+
 /*C:\TestProjects\sortedProjects\Subversion\local2\preRelease\mod2\src\com\test>sv
   n st
   D       gggG
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java
index 9294f0b..34525c6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java
@@ -16,14 +16,11 @@
 package org.jetbrains.idea.svn.commandLine;
 
 import com.intellij.execution.ExecutableValidator;
-import com.intellij.execution.configurations.GeneralCommandLine;
-import com.intellij.execution.process.CapturingProcessHandler;
-import com.intellij.execution.process.ProcessOutput;
 import com.intellij.notification.Notification;
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.options.Configurable;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Version;
-import com.intellij.openapi.vfs.CharsetToolkit;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.SvnApplicationSettings;
@@ -41,6 +38,8 @@
  */
 public class SvnExecutableChecker extends ExecutableValidator {
 
+  private static final Logger LOG = Logger.getInstance(SvnExecutableChecker.class);
+
   public SvnExecutableChecker(Project project) {
     super(project, getNotificationTitle(), getWrongPathMessage());
   }
@@ -74,12 +73,13 @@
   protected boolean isExecutableValid(@NotNull String executable) {
     setNotificationErrorDescription(getWrongPathMessage());
 
-    final Version version = getVersion(executable);
+    // Necessary executable path will be taken from settings while command execution
+    final Version version = getConfiguredClientVersion();
     try {
       return version != null && validateVersion(version);
     }
     catch (Throwable e) {
-      // do nothing
+      LOG.info(e);
       return false;
     }
   }
@@ -101,38 +101,19 @@
   }
 
   @Nullable
-  public Version getVersion(@NotNull String executable) {
+  private Version getConfiguredClientVersion() {
     Version result = null;
 
     try {
-      GeneralCommandLine commandLine = new GeneralCommandLine();
-      commandLine.setExePath(executable);
-      commandLine.addParameter("--version");
-      commandLine.addParameter("--quiet");
-
-      CapturingProcessHandler handler = new CapturingProcessHandler(commandLine.createProcess(), CharsetToolkit.getDefaultSystemCharset());
-      ProcessOutput output = handler.runProcess(30 * 1000);
-
-      if (!output.isTimeout() && (output.getExitCode() == 0) && output.getStderr().isEmpty()) {
-        String versionText = output.getStdout().trim();
-        final String[] parts = versionText.split("\\.");
-
-        if (parts.length >= 3) {
-          result = new Version(getInt(parts[0]), getInt(parts[1]), getInt(parts[2]));
-        }
-      }
+      result = getVcs().getCommandLineFactory().createVersionClient().getVersion();
     }
     catch (Throwable e) {
-      // do nothing
+      LOG.info(e);
     }
 
     return result;
   }
 
-  private static int getInt(@NotNull String value) {
-    return Integer.parseInt(value);
-  }
-
   private static String getWrongPathMessage() {
     return SvnBundle.message("subversion.executable.notification.description");
   }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
index cfd6db9..6520c62 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
@@ -26,7 +26,9 @@
 import org.tmatesoft.svn.core.wc.SVNStatusType;
 
 import java.io.File;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -55,12 +57,18 @@
   private final static Pattern ourUpdatedToRevision = Pattern.compile(UPDATED_TO_REVISION);
   private final static Pattern ourCheckedOutRevision = Pattern.compile("Checked out revision (\\d+)\\.");
 
+  // export from repository
+  private final static Pattern ourExportedRevision = Pattern.compile("Exported revision (\\d+)\\.");
+  // export from working copy
+  private final static Pattern ourExportComplete = Pattern.compile("Export complete\\.");
+
   private final static Pattern ourExternal = Pattern.compile(EXTERNAL);
   private final static Pattern ourUpdatedExternal = Pattern.compile(UPDATED_EXTERNAL);
   private final static Pattern ourCheckedOutExternal = Pattern.compile("Checked out external at revision (\\d+)\\.");
 
   private final static Pattern[] ourCompletePatterns =
-    new Pattern[]{ourAtRevision, ourUpdatedToRevision, ourCheckedOutRevision, ourExternal, ourUpdatedExternal, ourCheckedOutExternal};
+    new Pattern[]{ourAtRevision, ourUpdatedToRevision, ourCheckedOutRevision, ourExportedRevision, ourExternal, ourUpdatedExternal,
+      ourCheckedOutExternal, ourExportComplete};
 
   private final File myBase;
   private File myCurrentFile;
@@ -168,6 +176,10 @@
   private long matchAndGetRevision(final Pattern pattern, final String line) {
     final Matcher matcher = pattern.matcher(line);
     if (matcher.matches()) {
+      if (pattern == ourExportComplete) {
+        return 0;
+      }
+
       final String group = matcher.group(1);
       if (group == null) return -1;
       try {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java
index 0cfe815..f88c8eb 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java
@@ -340,14 +340,13 @@
 
   private void changeFormat(final WCInfo wcInfo) {
     ChangeFormatDialog dialog = new ChangeFormatDialog(myProject, new File(wcInfo.getPath()), false, ! wcInfo.isIsWcRoot());
-    dialog.setData(wcInfo.getFormat().getOption());
+    dialog.setData(wcInfo.getFormat());
     dialog.show();
     if (! dialog.isOK()) {
       return;
     }
-    final String newMode = dialog.getUpgradeMode();
-    if (! wcInfo.getFormat().getOption().equals(newMode)) {
-      final WorkingCopyFormat newFormat = WorkingCopyFormat.getInstance(newMode);
+    final WorkingCopyFormat newFormat = dialog.getUpgradeMode();
+    if (!wcInfo.getFormat().equals(newFormat)) {
       ApplicationManager.getApplication().saveAll();
       final Task.Backgroundable task = new SvnFormatWorker(myProject, newFormat, wcInfo) {
         @Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java
index ca596e9..a04f817 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java
@@ -894,7 +894,7 @@
       ExportOptionsDialog dialog = new ExportOptionsDialog(p, url, dir);
       dialog.show();
       if (dialog.isOK()) {
-        SvnCheckoutProvider.doExport(myProject, dir, url.toString(), dialog.getDepth(),
+        SvnCheckoutProvider.doExport(myProject, dir, url, dialog.getDepth(),
                 dialog.isIgnoreExternals(), dialog.isForce(), dialog.getEOLStyle());
       }
     }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java
index f9bf6bd..cb2fcda 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java
@@ -23,16 +23,19 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.SvnBundle;
-import org.jetbrains.idea.svn.SvnConfiguration;
+import org.jetbrains.idea.svn.WorkingCopyFormat;
 import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
 
 import javax.swing.*;
 import java.awt.*;
 import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
 
 public class UpgradeFormatDialog extends DialogWrapper  {
-  private JRadioButton myUpgradeAuto16Button;
-  private JRadioButton myUpgradeAuto17Button;
+
+  private ButtonGroup formatGroup = new ButtonGroup();
+  private List<JRadioButton> formatButtons = new ArrayList<JRadioButton>();
 
   protected File myPath;
 
@@ -61,11 +64,12 @@
     return "svn.upgradeDialog";
   }
 
-  public void setData(final String selectedFormat) {
-    if (SvnConfiguration.UPGRADE_AUTO_17.equals(selectedFormat)) {
-      myUpgradeAuto17Button.setSelected(true);
-    } else {
-      myUpgradeAuto16Button.setSelected(true);
+  public void setData(final WorkingCopyFormat selectedFormat) {
+    for (JRadioButton button : formatButtons) {
+      if (selectedFormat == getFormat(button)) {
+        button.setSelected(true);
+        break;
+      }
     }
   }
 
@@ -101,17 +105,9 @@
     panel.add(topLabel, gb);
     gb.gridy += 1;
 
-
-    myUpgradeAuto16Button = new JRadioButton(SvnBundle.message("radio.configure." + label + ".auto.16format"));
-    myUpgradeAuto17Button = new JRadioButton(SvnBundle.message("radio.configure." + label + ".auto.17format"));
-
-    ButtonGroup group = new ButtonGroup();
-    group.add(myUpgradeAuto16Button);
-    group.add(myUpgradeAuto17Button);
-    panel.add(myUpgradeAuto16Button, gb);
-    gb.gridy += 1;
-    panel.add(myUpgradeAuto17Button, gb);
-    gb.gridy += 1;
+    registerFormat(WorkingCopyFormat.ONE_DOT_SIX, label, panel, gb);
+    registerFormat(WorkingCopyFormat.ONE_DOT_SEVEN, label, panel, gb);
+    registerFormat(WorkingCopyFormat.ONE_DOT_EIGHT, label, panel, gb);
 
     final JPanel auxiliaryPanel = getBottomAuxiliaryPanel();
     if (auxiliaryPanel != null) {
@@ -122,6 +118,24 @@
     return panel;
   }
 
+  private void registerFormat(@NotNull WorkingCopyFormat format,
+                              @NotNull String label,
+                              @NotNull JPanel panel,
+                              @NotNull GridBagConstraints gb) {
+    JRadioButton button = new JRadioButton(SvnBundle.message("radio.configure." + label + ".auto." + getKey(format) + "format"));
+    button.putClientProperty("format", format);
+
+    panel.add(button, gb);
+    gb.gridy += 1;
+
+    formatGroup.add(button);
+    formatButtons.add(button);
+  }
+
+  private static String getKey(@NotNull WorkingCopyFormat format) {
+    return String.format("%d%d", format.getVersion().major, format.getVersion().minor);
+  }
+
   @Nullable
   protected JPanel getBottomAuxiliaryPanel() {
     return null;
@@ -135,14 +149,24 @@
     return true;
   }
 
-  @Nullable
-  public String getUpgradeMode() {
-    if (myUpgradeAuto17Button.isSelected()) {
-      return SvnConfiguration.UPGRADE_AUTO_17;
-    } else if (myUpgradeAuto16Button.isSelected()) {
-      return SvnConfiguration.UPGRADE_AUTO_16;
-    }
-    return null;
+  @NotNull
+  private static WorkingCopyFormat getFormat(@NotNull JRadioButton button) {
+    Object format = button.getClientProperty("format");
+
+    return format instanceof WorkingCopyFormat ? (WorkingCopyFormat)format : WorkingCopyFormat.UNKNOWN;
   }
 
+  @NotNull
+  public WorkingCopyFormat getUpgradeMode() {
+    WorkingCopyFormat result = WorkingCopyFormat.UNKNOWN;
+
+    for (JRadioButton button : formatButtons) {
+      if (button.isSelected()) {
+        result = getFormat(button);
+        break;
+      }
+    }
+
+    return result;
+  }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java
index fa11d6e..4123a6f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java
@@ -1,10 +1,7 @@
 package org.jetbrains.idea.svn.history;
 
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.VcsException;
-import com.intellij.util.LineSeparator;
-import com.intellij.util.containers.hash.HashMap;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.api.BaseSvnClient;
@@ -18,23 +15,22 @@
 import org.tmatesoft.svn.core.wc.SVNRevision;
 import org.tmatesoft.svn.core.wc2.SvnTarget;
 
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlValue;
 import java.io.File;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * @author Konstantin Kolosovsky.
  */
 public class CmdHistoryClient extends BaseSvnClient implements HistoryClient {
 
-  private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.CmdHistoryClient");
-
   @Override
   public void doLog(@NotNull File path,
                     @NotNull SVNRevision startRevision,
@@ -47,10 +43,6 @@
                     @Nullable String[] revisionProperties,
                     @Nullable ISVNLogEntryHandler handler) throws VcsException {
     // TODO: add revision properties parameter if necessary
-    // TODO: svn log command supports --xml option - could update parsing to use xml format
-
-    // TODO: after merge remove setting includeMergedRevisions to false and update parsing
-    includeMergedRevisions = false;
 
     List<String> parameters =
       prepareCommand(path, startRevision, endRevision, pegRevision, stopOnCopy, discoverChangedPaths, includeMergedRevisions, limit);
@@ -59,18 +51,39 @@
       SvnCommand command = CommandUtil.execute(myVcs, SvnTarget.fromFile(path, pegRevision), SvnCommandName.log, parameters, null);
       // TODO: handler should be called in parallel with command execution, but this will be in other thread
       // TODO: check if that is ok for current handler implementation
-      parseOutput(handler, command);
+      parseOutput(command, handler);
     }
     catch (SVNException e) {
       throw new VcsException(e);
     }
   }
 
-  private static void parseOutput(@Nullable ISVNLogEntryHandler handler, @NotNull SvnCommand command)
+  private static void parseOutput(@NotNull SvnCommand command, @Nullable ISVNLogEntryHandler handler)
     throws VcsException, SVNException {
-    Parser parser = new Parser(handler);
-    for (String line : StringUtil.splitByLines(command.getOutput(), false)) {
-      parser.onLine(line);
+    try {
+      LogInfo log = CommandUtil.parse(command.getOutput(), LogInfo.class);
+
+      if (handler != null && log != null) {
+        for (LogEntry entry : log.entries) {
+          iterateRecursively(entry, handler);
+        }
+      }
+    }
+    catch (JAXBException e) {
+      throw new VcsException(e);
+    }
+  }
+
+  private static void iterateRecursively(@NotNull LogEntry entry, @NotNull ISVNLogEntryHandler handler) throws SVNException {
+    handler.handleLogEntry(entry.toLogEntry());
+
+    for (LogEntry childEntry : entry.childEntries) {
+      iterateRecursively(childEntry, handler);
+    }
+
+    if (entry.hasChildren()) {
+      // empty log entry passed to handler to fully correspond to SVNKit behavior.
+      handler.handleLogEntry(SVNLogEntry.EMPTY_ENTRY);
     }
   }
 
@@ -92,133 +105,90 @@
       parameters.add("--limit");
       parameters.add(String.valueOf(limit));
     }
+    parameters.add("--xml");
 
     return parameters;
   }
 
-  private static class Parser {
-    private static final String REVISION = "\\s*r(\\d+)\\s*";
-    private static final String AUTHOR = "\\s*([^|]*)\\s*";
-    private static final String DATE = "\\s*([^|]*)\\s*";
-    private static final String MESSAGE_LINES = "\\s*(\\d+).*";
+  @XmlRootElement(name = "log")
+  public static class LogInfo {
 
-    private static final Pattern ENTRY_START = Pattern.compile("-+");
-    private static final Pattern DETAILS = Pattern.compile(REVISION + "\\|" + AUTHOR + "\\|" + DATE + "\\|" + MESSAGE_LINES);
+    @XmlElement(name = "logentry")
+    public List<LogEntry> entries = new ArrayList<LogEntry>();
+  }
 
-    private static final String STATUS = "\\s*(\\w)";
-    private static final String PATH = "\\s*(.*?)\\s*";
-    private static final String COPY_FROM_PATH = "(/[^:]*)";
-    private static final String COPY_FROM_REVISION = "(\\d+)\\))\\s*";
-    private static final String COPY_FROM_INFO = "((\\(from " + COPY_FROM_PATH + ":" + COPY_FROM_REVISION + ")?";
-    private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + PATH + COPY_FROM_INFO);
+  public static class LogEntry {
 
-    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
+    @XmlAttribute(name = "revision")
+    public long revision;
 
-    ISVNLogEntryHandler handler;
+    @XmlElement(name = "author")
+    public String author;
 
-    Entry entry;
-    boolean waitDetails;
-    boolean waitChangedPath;
-    boolean waitMessage;
+    @XmlElement(name = "date")
+    public Date date;
 
-    public Parser(@Nullable ISVNLogEntryHandler handler) {
-      this.handler = handler;
+    @XmlElement(name = "msg")
+    public String message;
+
+    @XmlElement(name = "paths")
+    public ChangedPaths changedPaths;
+
+    @XmlElement(name = "logentry")
+    public List<LogEntry> childEntries = new ArrayList<LogEntry>();
+
+    public boolean hasChildren() {
+      return !childEntries.isEmpty();
     }
 
-    public void onLine(@NotNull String line) throws VcsException, SVNException {
-      if (ENTRY_START.matcher(line).matches()) {
-        processEntryStart();
-      }
-      else if (waitDetails) {
-        processDetails(line);
-      }
-      else if (waitMessage) {
-        processMessage(line);
-      }
-      else if (StringUtil.isEmpty(line.trim())) {
-        processChangedPathsFinished();
-      }
-      else if (line.startsWith("Changed paths:")) {
-        processChangedPathsStarted();
-      }
-      else if (waitChangedPath) {
-        processChangedPath(line);
-      }
-      else {
-        throw new VcsException("unknown state on line " + line);
-      }
+    public SVNLogEntry toLogEntry() {
+      SVNLogEntry entry = new SVNLogEntry(toChangedPathsMap(), revision, author, date, message);
+
+      entry.setHasChildren(hasChildren());
+
+      return entry;
     }
 
-    private void processChangedPath(@NotNull String line) throws VcsException {
-      Matcher matcher = CHANGED_PATH.matcher(line);
-      if (!matcher.matches()) {
-        throw new VcsException("changed path not found in " + line);
+    public Map<String, SVNLogEntryPath> toChangedPathsMap() {
+      return changedPaths != null ? changedPaths.toMap() : ContainerUtil.<String, SVNLogEntryPath>newHashMap();
+    }
+  }
+
+  public static class ChangedPaths {
+
+    @XmlElement(name = "path")
+    public List<ChangedPath> changedPaths = new ArrayList<ChangedPath>();
+
+    public Map<String, SVNLogEntryPath> toMap() {
+      Map<String, SVNLogEntryPath> changes = ContainerUtil.newHashMap();
+
+      for (ChangedPath path : changedPaths) {
+        changes.put(path.path, path.toLogEntryPath());
       }
 
-      String path = matcher.group(2);
-      char type = CommandUtil.getStatusChar(matcher.group(1));
-      String copyPath = matcher.group(5);
-      long copyRevision = !StringUtil.isEmpty(matcher.group(6)) ? Long.valueOf(matcher.group(6)) : 0;
-
-      entry.changedPaths.put(path, new SVNLogEntryPath(path, type, copyPath, copyRevision));
+      return changes;
     }
+  }
 
-    private void processChangedPathsStarted() {
-      waitChangedPath = true;
-    }
+  public static class ChangedPath {
 
-    private void processChangedPathsFinished() {
-      waitChangedPath = false;
-      waitMessage = true;
-    }
+    @XmlAttribute(name = "kind")
+    public String kind;
 
-    private void processMessage(@NotNull String line) {
-      entry.message.append(line);
-      entry.message.append(LineSeparator.LF.getSeparatorString());
-    }
+    @XmlAttribute(name = "action")
+    public String action;
 
-    private void processDetails(@NotNull String line) throws VcsException {
-      Matcher matcher = DETAILS.matcher(line);
-      if (!matcher.matches()) {
-        throw new VcsException("details not found in " + line);
-      }
-      entry.revision = Long.valueOf(matcher.group(1));
-      entry.author = matcher.group(2).trim();
-      entry.date = tryGetDate(matcher.group(3));
+    @XmlAttribute(name = "copyfrom-path")
+    public String copyFromPath;
 
-      waitDetails = false;
-    }
+    @XmlAttribute(name = "copyfrom-rev")
+    public long copyFromRevision;
 
-    private void processEntryStart() throws SVNException {
-      if (entry != null) {
-        handler.handleLogEntry(entry.toLogEntry());
-      }
-      entry = new Entry();
-      waitDetails = true;
-      waitMessage = false;
-    }
+    @XmlValue
+    public String path;
 
-    private static Date tryGetDate(@NotNull String value) {
-      Date result = null;
-      try {
-        result = DATE_FORMAT.parse(value);
-      }
-      catch (ParseException e) {
-        LOG.debug(e);
-      }
-      return result;
-    }
-
-    private static class Entry {
-      Map<String, SVNLogEntryPath> changedPaths = new HashMap<String, SVNLogEntryPath>();
-      long revision;
-      String author;
-      Date date;
-      StringBuilder message = new StringBuilder();
-
-      private SVNLogEntry toLogEntry() {
-        return new SVNLogEntry(changedPaths, revision, author, date, message.toString());
-      }
+    public SVNLogEntryPath toLogEntryPath() {
+      return new SVNLogEntryPath(path, CommandUtil.getStatusChar(action), copyFromPath, copyFromRevision);
     }
   }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
index d67e29b..f45a294 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
@@ -36,13 +36,14 @@
 import com.intellij.util.Consumer;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.SvnPropertyKeys;
 import org.jetbrains.idea.svn.SvnUtil;
 import org.jetbrains.idea.svn.SvnVcs;
 import org.tmatesoft.svn.core.SVNException;
 import org.tmatesoft.svn.core.SVNPropertyValue;
 import org.tmatesoft.svn.core.SVNURL;
 import org.tmatesoft.svn.core.wc.SVNRevision;
-import org.tmatesoft.svn.core.wc.SVNWCClient;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
 
 /**
  * Created with IntelliJ IDEA.
@@ -133,7 +134,6 @@
 
     @Override
     public void run(@NotNull ProgressIndicator indicator) {
-      final SVNWCClient client = myVcs.createWCClient();
       final String url = myLocation.getURL();
       final SVNURL root;
       try {
@@ -142,12 +142,16 @@
           myException = new VcsException("Can not determine repository root for URL: " + url);
           return;
         }
-        client.doSetRevisionProperty(root, SVNRevision.create(myNumber), "svn:log",
-                                     SVNPropertyValue.create(myNewMessage), false, null);
+        SvnTarget target = SvnTarget.fromURL(root);
+        myVcs.getFactory(target).createPropertyClient()
+          .setRevisionProperty(target, SvnPropertyKeys.LOG, SVNRevision.create(myNumber), SVNPropertyValue.create(myNewMessage), false);
       }
       catch (SVNException e) {
         myException = new VcsException(e);
       }
+      catch (VcsException e) {
+        myException = e;
+      }
     }
 
     @Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
index 44870c1..a429999 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
@@ -20,6 +20,7 @@
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.FilePath;
 import com.intellij.openapi.vcs.VcsConfiguration;
 import com.intellij.openapi.vcs.VcsException;
@@ -42,7 +43,9 @@
 import org.tmatesoft.svn.core.*;
 import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
 import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
-import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc.SVNInfo;
+import org.tmatesoft.svn.core.wc.SVNLogClient;
+import org.tmatesoft.svn.core.wc.SVNRevision;
 import org.tmatesoft.svn.util.SVNLogType;
 
 import javax.swing.*;
@@ -502,6 +505,8 @@
           }
           SVNLogEntryPath entryPath = null;
           String copyPath = null;
+          final int mergeLevel = svnLogEntryIntegerPair.getSecond();
+
           if (! myLastPathCorrector.isRoot()) {
             myLastPathCorrector.handleLogEntry(logEntry);
             entryPath = myLastPathCorrector.getDirectlyMentioned();
@@ -511,11 +516,16 @@
             } else {
               // if there are no path with exact match, check whether parent or child paths had changed
               // "entry path" is allowed to be null now; if it is null, last path would be taken for revision construction
-              if (! checkForChildChanges(logEntry) && ! checkForParentChanges(logEntry)) return;
+
+              // Separate SVNLogEntry is issued for each "merge source" revision. These "merge source" revisions are treated as child
+              // revisions of some other revision - this way we construct merge hierarchy.
+              // mergeLevel >= 0 indicates that we are currently processing some "merge source" revision. This "merge source" revision
+              // contains changes from some other branch - so checkForChildChanges() and checkForParentChanges() return "false".
+              // Because of this case we apply these methods only for non-"merge source" revisions - this means mergeLevel < 0.
+              if (mergeLevel < 0 && !checkForChildChanges(logEntry) && !checkForParentChanges(logEntry)) return;
             }
           }
 
-          final int mergeLevel = svnLogEntryIntegerPair.getSecond();
           final SvnFileRevision revision = createRevision(logEntry, copyPath, entryPath);
           if (mergeLevel >= 0) {
             addToListByLevel((SvnFileRevision)myPrevious, revision, mergeLevel);
@@ -608,7 +618,47 @@
     }
   }
 
-  private class MergeSourceColumnInfo extends ColumnInfo<VcsFileRevision, String> {
+  private static class RevisionMergeSourceInfo {
+
+    @NotNull private final VcsFileRevision revision;
+
+    private RevisionMergeSourceInfo(@NotNull VcsFileRevision revision) {
+      this.revision = revision;
+    }
+
+    @NotNull
+    public SvnFileRevision getRevision() {
+      return (SvnFileRevision)revision;
+    }
+
+    // will be used, for instance, while copying (to clipboard) data from table
+    @Override
+    public String toString() {
+      return toString(revision);
+    }
+
+    private static String toString(@Nullable VcsFileRevision value) {
+      if (!(value instanceof SvnFileRevision)) return "";
+      final SvnFileRevision revision = (SvnFileRevision)value;
+      final List<SvnFileRevision> mergeSources = revision.getMergeSources();
+      if (mergeSources.isEmpty()) {
+        return "";
+      }
+      final StringBuilder sb = new StringBuilder();
+      for (SvnFileRevision source : mergeSources) {
+        if (sb.length() != 0) {
+          sb.append(", ");
+        }
+        sb.append(source.getRevisionNumber().asString());
+        if (!source.getMergeSources().isEmpty()) {
+          sb.append("*");
+        }
+      }
+      return sb.toString();
+    }
+  }
+
+  private class MergeSourceColumnInfo extends ColumnInfo<VcsFileRevision, RevisionMergeSourceInfo> {
     private final MergeSourceRenderer myRenderer;
 
     private MergeSourceColumnInfo(final SvnHistorySession session) {
@@ -621,8 +671,8 @@
       return myRenderer;
     }
 
-    public String valueOf(final VcsFileRevision vcsFileRevision) {
-      return vcsFileRevision == null ? "" : getText(vcsFileRevision);
+    public RevisionMergeSourceInfo valueOf(final VcsFileRevision vcsFileRevision) {
+      return vcsFileRevision != null ? new RevisionMergeSourceInfo(vcsFileRevision) : null;
     }
 
     public String getText(final VcsFileRevision vcsFileRevision) {
@@ -673,8 +723,8 @@
       int column = table.columnAtPoint(e.getPoint());
 
       final Object value = table.getModel().getValueAt(row, column);
-      if (value instanceof SvnFileRevision) {
-        return (SvnFileRevision)value;
+      if (value instanceof RevisionMergeSourceInfo) {
+        return ((RevisionMergeSourceInfo)value).getRevision();
       }
       return null;
     }
@@ -700,23 +750,7 @@
     }
 
     public String getText(final VcsFileRevision value) {
-      if (!(value instanceof SvnFileRevision)) return "";
-      final SvnFileRevision revision = (SvnFileRevision)value;
-      final List<SvnFileRevision> mergeSources = revision.getMergeSources();
-      if (mergeSources.isEmpty()) {
-        return "";
-      }
-      final StringBuilder sb = new StringBuilder();
-      for (SvnFileRevision source : mergeSources) {
-        if (sb.length() != 0) {
-          sb.append(", ");
-        }
-        sb.append(source.getRevisionNumber().asString());
-        if (!source.getMergeSources().isEmpty()) {
-          sb.append("*");
-        }
-      }
-      return sb.toString();
+      return RevisionMergeSourceInfo.toString(value);
     }
 
     protected void customizeCellRenderer(final JTable table,
@@ -729,22 +763,17 @@
         myListener = new MergeSourceDetailsLinkListener(MERGE_SOURCE_DETAILS_TAG, myFile);
         myListener.installOn(table);
       }
-      if (value instanceof String) {
-        append((String)value, SimpleTextAttributes.REGULAR_ATTRIBUTES);
-        return;
-      }
-      if (!(value instanceof SvnFileRevision)) {
-        append("", SimpleTextAttributes.REGULAR_ATTRIBUTES);
-        return;
-      }
-      final SvnFileRevision revision = (SvnFileRevision)value;
-      final String text = getText(revision);
-      if (text.length() == 0) {
-        append("", SimpleTextAttributes.REGULAR_ATTRIBUTES);
-        return;
-      }
+      appendMergeSourceText(table, row, column, value instanceof RevisionMergeSourceInfo ? value.toString() : null);
+    }
 
-      append(cutString(text, table.getCellRect(row, column, false).getWidth()), SimpleTextAttributes.REGULAR_ATTRIBUTES);
+    private void appendMergeSourceText(JTable table, int row, int column, @Nullable String text) {
+      if (StringUtil.isEmpty(text)) {
+        append("", SimpleTextAttributes.REGULAR_ATTRIBUTES);
+      }
+      else {
+        append(cutString(text, table.getCellRect(row, column, false).getWidth()), SimpleTextAttributes.REGULAR_ATTRIBUTES,
+               MERGE_SOURCE_DETAILS_TAG);
+      }
     }
 
     private String cutString(final String text, final double value) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java
index 5b76f6a..2bd8627 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java
@@ -15,28 +15,24 @@
  */
 package org.jetbrains.idea.svn.ignore;
 
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.vcs.VcsException;
 import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
 import com.intellij.openapi.vfs.VirtualFile;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.SvnPropertyKeys;
 import org.jetbrains.idea.svn.SvnVcs;
 import org.tmatesoft.svn.core.SVNDepth;
-import org.tmatesoft.svn.core.SVNException;
 import org.tmatesoft.svn.core.SVNPropertyValue;
 import org.tmatesoft.svn.core.wc.SVNPropertyData;
 import org.tmatesoft.svn.core.wc.SVNRevision;
-import org.tmatesoft.svn.core.wc.SVNWCClient;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
 
 import java.io.File;
 import java.util.*;
 
 public class SvnPropertyService {
-  private final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.ignore.SvnPropertyService");
 
   private SvnPropertyService() {
   }
@@ -67,22 +63,23 @@
 
   private static abstract class IgnorePropertyWorkTemplate {
     protected final SvnVcs myVcs;
-    protected final SVNWCClient myClient;
     protected final Project myProject;
     protected final boolean myUseCommonExtension;
     protected final boolean myCanUseCachedProperty;
     
     protected abstract void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data,
-                                          final SVNPropertyValue propertyValue) throws SVNException;
+                                          final SVNPropertyValue propertyValue) throws VcsException;
+
     protected abstract void onAfterProcessing(final VirtualFile[] file) throws VcsException;
-    protected abstract void onSVNException(SVNException e);
+
+    protected abstract void onSVNException(Exception e);
+
     protected abstract boolean stopIteration();
 
     private IgnorePropertyWorkTemplate(final SvnVcs activeVcs, final Project project, final boolean useCommonExtension,
                                        final boolean canUseCachedProperty) {
       myVcs = activeVcs;
       myCanUseCachedProperty = canUseCachedProperty;
-      myClient = activeVcs.createWCClient();
       myProject = project;
       myUseCommonExtension = useCommonExtension;
     }
@@ -100,12 +97,13 @@
             value = myVcs.getPropertyWithCaching(entry.getKey(), SvnPropertyKeys.SVN_IGNORE);
           } else {
             final SVNPropertyData data =
-              myVcs.createWCClient().doGetProperty(dir, SvnPropertyKeys.SVN_IGNORE, SVNRevision.UNDEFINED, SVNRevision.WORKING);
+              myVcs.getFactory(dir).createPropertyClient()
+                .getProperty(SvnTarget.fromFile(dir), SvnPropertyKeys.SVN_IGNORE, false, SVNRevision.WORKING);
             value = data == null ? null : data.getValue();
           }
           processFolder(entry.getKey(), dir, entry.getValue(), value);
         }
-        catch (SVNException e) {
+        catch (VcsException e) {
           onSVNException(e);
         }
       }
@@ -113,28 +111,6 @@
     }
   }
 
-  @Nullable
-  public static Set<String> getIgnoreStringsUnder(final SvnVcs vcs, final VirtualFile dir) {
-    try {
-      final SVNPropertyData data = vcs.createWCClient().doGetProperty(new File(dir.getPath()), SvnPropertyKeys.SVN_IGNORE, SVNRevision.WORKING, SVNRevision.WORKING);
-      final SVNPropertyValue value = (data == null) ? null : data.getValue();
-      if (value != null) {
-        final Set<String> ignorePatterns = new HashSet<String>();
-        final String propAsString = SVNPropertyValue.getPropertyAsString(value);
-        final StringTokenizer st = new StringTokenizer(propAsString, "\r\n ");
-        while (st.hasMoreElements()) {
-          final String ignorePattern = (String) st.nextElement();
-          ignorePatterns.add(ignorePattern);
-        }
-        return ignorePatterns;
-      }
-    }
-    catch (SVNException e) {
-      LOG.info(e);
-    }
-    return null;
-  }
-
   private static class IgnorePropertyChecker extends IgnorePropertyWorkTemplate {
     private final String myExtensionPattern;
     private boolean myFilesOk;
@@ -152,7 +128,7 @@
     }
 
     protected void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data, final SVNPropertyValue propertyValue)
-        throws SVNException {
+      throws VcsException {
       if (propertyValue == null) {
         myFilesOk = false;
         myExtensionOk = false;
@@ -176,7 +152,7 @@
     protected void onAfterProcessing(final VirtualFile[] file) throws VcsException {
     }
 
-    protected void onSVNException(final SVNException e) {
+    protected void onSVNException(final Exception e) {
       myFilesOk = false;
       myExtensionOk = false;
     }
@@ -207,10 +183,11 @@
     protected abstract String getNewPropertyValue(final Set<String> data, final SVNPropertyValue propertyValue);
 
     protected void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data, final SVNPropertyValue propertyValue)
-        throws SVNException {
+      throws VcsException {
       String newValue = getNewPropertyValue(data, propertyValue);
       newValue = (newValue.trim().isEmpty()) ? null : newValue;
-      myClient.doSetProperty(folderDir, SvnPropertyKeys.SVN_IGNORE, SVNPropertyValue.create(newValue), false, false, null);
+      myVcs.getFactory(folderDir).createPropertyClient()
+        .setProperty(folderDir, SvnPropertyKeys.SVN_IGNORE, SVNPropertyValue.create(newValue), SVNDepth.EMPTY, false);
 
       if (myUseCommonExtension) {
         dirtyScopeManager.dirDirtyRecursively(folder);
@@ -229,7 +206,7 @@
       }
     }
 
-    protected void onSVNException(final SVNException e) {
+    protected void onSVNException(final Exception e) {
       exceptions.add(e.getMessage());
     }
   }
@@ -247,21 +224,6 @@
     }
   }
 
-  public static void setIgnores(final SvnVcs vcs, final Collection<String> patterns, final File file)
-    throws SVNException {
-    final SVNWCClient client = vcs.createWCClient();
-    final StringBuilder sb = new StringBuilder();
-    for (String pattern : patterns) {
-      sb.append(pattern).append('\n');
-    }
-    if (! patterns.isEmpty()) {
-      final String value = sb.toString();
-      client.doSetProperty(file, SvnPropertyKeys.SVN_IGNORE, SVNPropertyValue.create(value), false, SVNDepth.EMPTY, null, null);
-    } else {
-      client.doSetProperty(file, SvnPropertyKeys.SVN_IGNORE, null, false, SVNDepth.EMPTY, null, null);
-    }
-  }
-
   private static String getNewPropertyValueForRemove(final Collection<String> data, @NotNull final String propertyValue) {
     final StringBuilder sb = new StringBuilder();
     final StringTokenizer st = new StringTokenizer(propertyValue, "\r\n ");
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java
deleted file mode 100644
index d69a47b..0000000
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java
+++ /dev/null
@@ -1,211 +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 org.jetbrains.idea.svn.portable;
-
-import org.tmatesoft.svn.core.SVNDepth;
-import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.SVNURL;
-import org.tmatesoft.svn.core.wc.ISVNEventHandler;
-import org.tmatesoft.svn.core.wc.SVNRevision;
-import org.tmatesoft.svn.core.wc.SVNUpdateClient;
-
-import java.io.File;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/1/12
- * Time: 12:11 PM
- */
-public class SvnSvnkitUpdateClient implements SvnUpdateClientI {
-  private final SVNUpdateClient myClient;
-  private ISVNEventHandler myDispatcher;
-
-  public SvnSvnkitUpdateClient(SVNUpdateClient client) {
-    myClient = client;
-  }
-
-  @Override
-  public long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException {
-    return myClient.doUpdate(file, revision, recursive);
-  }
-
-  @Override
-  public long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException {
-    return myClient.doUpdate(file, revision, recursive, force);
-  }
-
-  @Override
-  public long[] doUpdate(File[] paths,
-                         SVNRevision revision,
-                         SVNDepth depth,
-                         boolean allowUnversionedObstructions,
-                         boolean depthIsSticky) throws SVNException {
-    return myClient.doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky);
-  }
-
-  @Override
-  public long[] doUpdate(File[] paths,
-                         SVNRevision revision,
-                         SVNDepth depth,
-                         boolean allowUnversionedObstructions,
-                         boolean depthIsSticky,
-                         boolean makeParents) throws SVNException {
-    return myClient.doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents);
-  }
-
-  @Override
-  public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
-    throws SVNException {
-    return myClient.doUpdate(path, revision, depth, allowUnversionedObstructions, depthIsSticky);
-  }
-
-  @Override
-  public void setUpdateLocksOnDemand(boolean locksOnDemand) {
-    myClient.setUpdateLocksOnDemand(locksOnDemand);
-  }
-
-  @Override
-  public long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException {
-    return myClient.doSwitch(file, url, revision, recursive);
-  }
-
-  @Override
-  public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException {
-    return myClient.doSwitch(file, url, pegRevision, revision, recursive);
-  }
-
-  @Override
-  public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force)
-    throws SVNException {
-    return myClient.doSwitch(file, url, pegRevision, revision, recursive, force);
-  }
-
-  @Override
-  public long doSwitch(File path,
-                       SVNURL url,
-                       SVNRevision pegRevision,
-                       SVNRevision revision,
-                       SVNDepth depth,
-                       boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException {
-    return myClient.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky);
-  }
-
-  @Override
-  public long doSwitch(File path,
-                       SVNURL url,
-                       SVNRevision pegRevision,
-                       SVNRevision revision,
-                       SVNDepth depth,
-                       boolean allowUnversionedObstructions, boolean depthIsSticky, boolean ignoreAncestry) throws SVNException {
-    return myClient.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky, ignoreAncestry);
-  }
-
-  @Override
-  public long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException {
-    return myClient.doCheckout(url, dstPath, pegRevision, revision, recursive);
-  }
-
-  @Override
-  public long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force)
-    throws SVNException {
-    return myClient.doCheckout(url, dstPath, pegRevision, revision, recursive, force);
-  }
-
-  @Override
-  public long doCheckout(SVNURL url,
-                         File dstPath,
-                         SVNRevision pegRevision,
-                         SVNRevision revision,
-                         SVNDepth depth,
-                         boolean allowUnversionedObstructions) throws SVNException {
-    return myClient.doCheckout(url, dstPath, pegRevision, revision, depth, allowUnversionedObstructions);
-  }
-
-  @Override
-  public long doExport(SVNURL url,
-                       File dstPath,
-                       SVNRevision pegRevision,
-                       SVNRevision revision,
-                       String eolStyle,
-                       boolean force,
-                       boolean recursive) throws SVNException {
-    return myClient.doExport(url, dstPath, pegRevision, revision, eolStyle, force, recursive);
-  }
-
-  @Override
-  public long doExport(SVNURL url,
-                       File dstPath,
-                       SVNRevision pegRevision,
-                       SVNRevision revision,
-                       String eolStyle,
-                       boolean overwrite,
-                       SVNDepth depth) throws SVNException {
-    return myClient.doExport(url, dstPath, pegRevision, revision, eolStyle, overwrite, depth);
-  }
-
-  @Override
-  public long doExport(File srcPath,
-                       File dstPath,
-                       SVNRevision pegRevision,
-                       SVNRevision revision,
-                       String eolStyle,
-                       boolean force,
-                       boolean recursive) throws SVNException {
-    return myClient.doExport(srcPath, dstPath, pegRevision, revision, eolStyle, force, recursive);
-  }
-
-  @Override
-  public long doExport(File srcPath,
-                       File dstPath,
-                       SVNRevision pegRevision,
-                       SVNRevision revision,
-                       String eolStyle,
-                       boolean overwrite,
-                       SVNDepth depth) throws SVNException {
-    return myClient.doExport(srcPath, dstPath, pegRevision, revision, eolStyle, overwrite, depth);
-  }
-
-  @Override
-  public void doRelocate(File dst, SVNURL oldURL, SVNURL newURL, boolean recursive) throws SVNException {
-    myClient.doRelocate(dst, oldURL, newURL, recursive);
-  }
-
-  @Override
-  public void doCanonicalizeURLs(File dst, boolean omitDefaultPort, boolean recursive) throws SVNException {
-    myClient.doCanonicalizeURLs(dst, omitDefaultPort, recursive);
-  }
-
-  @Override
-  public void setExportExpandsKeywords(boolean expand) {
-    myClient.setExportExpandsKeywords(expand);
-  }
-
-  @Override
-  public void setEventHandler(ISVNEventHandler dispatcher) {
-    myDispatcher = dispatcher;
-    myClient.setEventHandler(dispatcher);
-  }
-
-  @Override
-  public void setIgnoreExternals(boolean ignoreExternals) {
-    myClient.setIgnoreExternals(ignoreExternals);
-  }
-
-  public ISVNEventHandler getEventHandler() {
-    return myDispatcher;
-  }
-}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java
deleted file mode 100644
index 8eaafa4..0000000
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java
+++ /dev/null
@@ -1,76 +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 org.jetbrains.idea.svn.portable;
-
-import org.tmatesoft.svn.core.SVNDepth;
-import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.SVNURL;
-import org.tmatesoft.svn.core.wc.ISVNEventHandler;
-import org.tmatesoft.svn.core.wc.SVNRevision;
-
-import java.io.File;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/1/12
- * Time: 11:59 AM
- */
-public interface SvnUpdateClientI extends SvnMarkerInterface {
-  long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException;
-
-  long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException;
-
-  long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
-
-  long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean makeParents) throws SVNException;
-
-  long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
-
-  void setUpdateLocksOnDemand(boolean locksOnDemand);
-
-  long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException;
-
-  long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException;
-
-  long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) throws SVNException;
-
-  long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
-
-  long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean ignoreAncestry) throws SVNException;
-
-  long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException;
-
-  long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) throws SVNException;
-
-  long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions) throws SVNException;
-
-  long doExport(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean force, boolean recursive) throws SVNException;
-
-  long doExport(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean overwrite, SVNDepth depth) throws SVNException;
-
-  long doExport(File srcPath, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean force, boolean recursive) throws SVNException;
-
-  long doExport(File srcPath, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean overwrite, SVNDepth depth) throws SVNException;
-
-  void doRelocate(File dst, SVNURL oldURL, SVNURL newURL, boolean recursive) throws SVNException;
-
-  void doCanonicalizeURLs(File dst, boolean omitDefaultPort, boolean recursive) throws SVNException;
-
-  void setExportExpandsKeywords(boolean expand);
-  void setEventHandler(ISVNEventHandler dispatcher);
-  void setIgnoreExternals(boolean ignoreExternals);
-}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnWcClientI.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnWcClientI.java
index 973058f..036de6b 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnWcClientI.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnWcClientI.java
@@ -19,7 +19,6 @@
 import org.tmatesoft.svn.core.wc.*;
 
 import java.io.File;
-import java.io.OutputStream;
 import java.util.Collection;
 
 /**
@@ -29,67 +28,7 @@
  * Time: 6:54 PM
  */
 public interface SvnWcClientI extends SvnMarkerInterface {
-  void setAddParameters(ISVNAddParameters addParameters);
-  ISVNCommitHandler getCommitHandler();
-  void setCommitHandler(ISVNCommitHandler handler);
-  void doGetFileContents(File path, SVNRevision pegRevision, SVNRevision revision,
-          boolean expandKeywords, OutputStream dst) throws SVNException;
-  void doGetFileContents(SVNURL url, SVNRevision pegRevision, SVNRevision revision,
-          boolean expandKeywords, OutputStream dst) throws SVNException;
-  void doCleanup(File path) throws SVNException;
-  void doCleanup(File path, boolean deleteWCProperties) throws SVNException;
-  void doSetProperty(File path, String propName, SVNPropertyValue propValue, boolean skipChecks,
-          SVNDepth depth, ISVNPropertyHandler handler, Collection changeLists) throws SVNException;
-  void doSetProperty(File path, ISVNPropertyValueProvider propertyValueProvider, boolean skipChecks,
-          SVNDepth depth, ISVNPropertyHandler handler, Collection changeLists) throws SVNException;
-  SVNCommitInfo doSetProperty(SVNURL url, String propName, SVNPropertyValue propValue,
-          SVNRevision baseRevision, String commitMessage, SVNProperties revisionProperties,
-          boolean skipChecks, ISVNPropertyHandler handler) throws SVNException;
-  void doSetRevisionProperty(File path, SVNRevision revision, String propName,
-          SVNPropertyValue propValue, boolean force, ISVNPropertyHandler handler) throws SVNException;
-  void doSetRevisionProperty(SVNURL url, SVNRevision revision, String propName,
-          SVNPropertyValue propValue, boolean force, ISVNPropertyHandler handler) throws SVNException;
-  SVNPropertyData doGetProperty( File path, String propName, SVNRevision pegRevision,
-          SVNRevision revision) throws SVNException;
-  SVNPropertyData doGetProperty( SVNURL url, String propName, SVNRevision pegRevision,
-          SVNRevision revision) throws SVNException;
-  void doGetProperty(File path, String propName, SVNRevision pegRevision, SVNRevision revision,
-          boolean recursive, ISVNPropertyHandler handler) throws SVNException;
-  void doGetProperty(File path, String propName, SVNRevision pegRevision, SVNRevision revision,
-          SVNDepth depth, ISVNPropertyHandler handler, Collection changeLists) throws SVNException;
-  void doGetProperty(SVNURL url, String propName, SVNRevision pegRevision, SVNRevision revision,
-          boolean recursive, ISVNPropertyHandler handler) throws SVNException;
-  void doGetProperty(SVNURL url, String propName, SVNRevision pegRevision, SVNRevision revision,
-          SVNDepth depth, ISVNPropertyHandler handler) throws SVNException;
-  void doGetRevisionProperty(File path, String propName, SVNRevision revision, ISVNPropertyHandler handler) throws SVNException;
-  long doGetRevisionProperty(SVNURL url, String propName, SVNRevision revision,
-          ISVNPropertyHandler handler) throws SVNException;
-  void doDelete(File path, boolean force, boolean dryRun) throws SVNException;
-  void doDelete(File path, boolean force, boolean deleteFiles, boolean dryRun) throws SVNException;
-  void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents,
-          boolean recursive) throws SVNException;
-  void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents,
-          boolean recursive, boolean includeIgnored) throws SVNException;
-  void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents,
-          SVNDepth depth, boolean includeIgnored, boolean makeParents) throws SVNException;
-  void doAdd(File[] paths, boolean force, boolean mkdir, boolean climbUnversionedParents,
-          SVNDepth depth, boolean depthIsSticky, boolean includeIgnored, boolean makeParents) throws SVNException;
-  void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents,
-          SVNDepth depth, boolean depthIsSticky, boolean includeIgnored, boolean makeParents) throws SVNException;
-  void doMarkReplaced(File path) throws SVNException;
-  void doRevert(File path, boolean recursive) throws SVNException;
-  void doRevert(File[] paths, boolean recursive) throws SVNException;
-  void doRevert(File[] paths, SVNDepth depth, Collection changeLists) throws SVNException;
-  void doResolve(File path, boolean recursive) throws SVNException;
-  void doResolve(File path, SVNDepth depth, SVNConflictChoice conflictChoice) throws SVNException;
-  void doResolve(File path, SVNDepth depth, boolean resolveContents, boolean resolveProperties,
-          SVNConflictChoice conflictChoice) throws SVNException;
-  void doResolve(File path, SVNDepth depth, boolean resolveContents, boolean resolveProperties,
-          boolean resolveTree, SVNConflictChoice conflictChoice) throws SVNException;
-  void doLock(File[] paths, boolean stealLock, String lockMessage) throws SVNException;
-  void doLock(SVNURL[] urls, boolean stealLock, String lockMessage) throws SVNException;
-  void doUnlock(File[] paths, boolean breakLock) throws SVNException;
-  void doUnlock(SVNURL[] urls, boolean breakLock) throws SVNException;
+
   void doInfo(File path, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException;
   void doInfo(File path, SVNRevision pegRevision, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException;
   void doInfo(File path, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth,
@@ -97,12 +36,6 @@
   void doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException;
   void doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth,
           ISVNInfoHandler handler) throws SVNException;
-  String doGetWorkingCopyID( File path, String trailURL) throws SVNException;
-  String doGetWorkingCopyID( File path, String trailURL, boolean committed) throws SVNException;
   SVNInfo doInfo(File path, SVNRevision revision) throws SVNException;
   SVNInfo doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision) throws SVNException;
-  void doCleanupWCProperties(File directory) throws SVNException;
-  void doSetWCFormat(File directory, int format) throws SVNException;
-  void doSetProperty(File path, String propName, SVNPropertyValue propValue, boolean force,
-          boolean recursive, ISVNPropertyHandler handler) throws SVNException;
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnStatusClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnStatusClient.java
index ddc7784..07edfa2 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnStatusClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnStatusClient.java
@@ -15,6 +15,9 @@
  */
 package org.jetbrains.idea.svn.portable;
 
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.SvnVcs;
 import org.tmatesoft.svn.core.SVNDepth;
 import org.tmatesoft.svn.core.SVNException;
 import org.tmatesoft.svn.core.wc.ISVNStatusHandler;
@@ -32,16 +35,19 @@
  * Time: 9:47 AM
  */
 public class SvnkitSvnStatusClient implements SvnStatusClientI {
-  private final SVNStatusClient myStatusClient;
 
-  public SvnkitSvnStatusClient(SVNStatusClient statusClient) {
+  @Nullable private final SVNStatusClient myStatusClient;
+  @NotNull private final SvnVcs myVcs;
+
+  public SvnkitSvnStatusClient(@NotNull SvnVcs vcs, @Nullable SVNStatusClient statusClient) {
+    myVcs = vcs;
     myStatusClient = statusClient;
   }
 
   @Override
   public long doStatus(File path, boolean recursive, boolean remote, boolean reportAll, boolean includeIgnored, ISVNStatusHandler handler)
     throws SVNException {
-    return myStatusClient.doStatus(path, recursive, remote, reportAll, includeIgnored, handler);
+    return getStatusClient().doStatus(path, recursive, remote, reportAll, includeIgnored, handler);
   }
 
   @Override
@@ -52,7 +58,7 @@
                        boolean includeIgnored,
                        boolean collectParentExternals,
                        ISVNStatusHandler handler) throws SVNException {
-    return myStatusClient.doStatus(path, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler);
+    return getStatusClient().doStatus(path, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler);
   }
 
   @Override
@@ -64,7 +70,7 @@
                        boolean includeIgnored,
                        boolean collectParentExternals,
                        ISVNStatusHandler handler) throws SVNException {
-    return myStatusClient.doStatus(path, revision, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler);
+    return getStatusClient().doStatus(path, revision, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler);
   }
 
   @Override
@@ -77,16 +83,22 @@
                        boolean collectParentExternals,
                        ISVNStatusHandler handler,
                        Collection changeLists) throws SVNException {
-    return myStatusClient.doStatus(path, revision, depth, remote, reportAll, includeIgnored, collectParentExternals, handler, changeLists);
+    return getStatusClient()
+      .doStatus(path, revision, depth, remote, reportAll, includeIgnored, collectParentExternals, handler, changeLists);
   }
 
   @Override
   public SVNStatus doStatus(File path, boolean remote) throws SVNException {
-    return myStatusClient.doStatus(path, remote);
+    return getStatusClient().doStatus(path, remote);
   }
 
   @Override
   public SVNStatus doStatus(File path, boolean remote, boolean collectParentExternals) throws SVNException {
-    return myStatusClient.doStatus(path, remote, collectParentExternals);
+    return getStatusClient().doStatus(path, remote, collectParentExternals);
+  }
+
+  @NotNull
+  private SVNStatusClient getStatusClient() {
+    return myStatusClient != null ? myStatusClient : myVcs.createStatusClient();
   }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnWcClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnWcClient.java
index 4b0076d..faee8ec 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnWcClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnWcClient.java
@@ -21,7 +21,6 @@
 import org.tmatesoft.svn.core.wc.*;
 
 import java.io.File;
-import java.io.OutputStream;
 import java.util.Collection;
 
 /**
@@ -43,279 +42,6 @@
   }
 
   @Override
-  public void setAddParameters(ISVNAddParameters addParameters) {
-    getClient().setAddParameters(addParameters);
-  }
-
-  @Override
-  public ISVNCommitHandler getCommitHandler() {
-    return getClient().getCommitHandler();
-  }
-
-  @Override
-  public void setCommitHandler(ISVNCommitHandler handler) {
-    getClient().setCommitHandler(handler);
-  }
-
-  @Override
-  public void doGetFileContents(File path, SVNRevision pegRevision, SVNRevision revision, boolean expandKeywords, OutputStream dst)
-    throws SVNException {
-    getClient().doGetFileContents(path, pegRevision, revision, expandKeywords, dst);
-  }
-
-  @Override
-  public void doGetFileContents(SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean expandKeywords, OutputStream dst)
-    throws SVNException {
-    getClient().doGetFileContents(url, pegRevision, revision, expandKeywords, dst);
-  }
-
-  @Override
-  public void doCleanup(File path) throws SVNException {
-    getClient().doCleanup(path);
-  }
-
-  @Override
-  public void doCleanup(File path, boolean deleteWCProperties) throws SVNException {
-    getClient().doCleanup(path, deleteWCProperties);
-  }
-
-  @Override
-  public void doSetProperty(File path,
-                            String propName,
-                            SVNPropertyValue propValue,
-                            boolean skipChecks,
-                            SVNDepth depth,
-                            ISVNPropertyHandler handler,
-                            Collection changeLists) throws SVNException {
-    getClient().doSetProperty(path, propName, propValue, skipChecks, depth, handler, changeLists);
-  }
-
-  @Override
-  public void doSetProperty(File path,
-                            ISVNPropertyValueProvider propertyValueProvider,
-                            boolean skipChecks,
-                            SVNDepth depth,
-                            ISVNPropertyHandler handler,
-                            Collection changeLists) throws SVNException {
-    getClient().doSetProperty(path, propertyValueProvider, skipChecks, depth, handler, changeLists);
-  }
-
-  @Override
-  public SVNCommitInfo doSetProperty(SVNURL url,
-                                     String propName,
-                                     SVNPropertyValue propValue,
-                                     SVNRevision baseRevision,
-                                     String commitMessage,
-                                     SVNProperties revisionProperties,
-                                     boolean skipChecks,
-                                     ISVNPropertyHandler handler) throws SVNException {
-    return getClient().doSetProperty(url, propName, propValue, baseRevision, commitMessage, revisionProperties, skipChecks, handler);
-  }
-
-  @Override
-  public void doSetRevisionProperty(File path,
-                                    SVNRevision revision,
-                                    String propName,
-                                    SVNPropertyValue propValue,
-                                    boolean force,
-                                    ISVNPropertyHandler handler) throws SVNException {
-    getClient().doSetRevisionProperty(path, revision, propName, propValue, force, handler);
-  }
-
-  @Override
-  public void doSetRevisionProperty(SVNURL url,
-                                    SVNRevision revision,
-                                    String propName,
-                                    SVNPropertyValue propValue,
-                                    boolean force,
-                                    ISVNPropertyHandler handler) throws SVNException {
-    getClient().doSetRevisionProperty(url, revision, propName, propValue, force, handler);
-  }
-
-  @Override
-  public SVNPropertyData doGetProperty(File path, String propName, SVNRevision pegRevision, SVNRevision revision) throws SVNException {
-    return getClient().doGetProperty(path, propName, pegRevision, revision);
-  }
-
-  @Override
-  public SVNPropertyData doGetProperty(SVNURL url, String propName, SVNRevision pegRevision, SVNRevision revision) throws SVNException {
-    return getClient().doGetProperty(url, propName, pegRevision, revision);
-  }
-
-  @Override
-  public void doGetProperty(File path,
-                            String propName,
-                            SVNRevision pegRevision,
-                            SVNRevision revision,
-                            boolean recursive,
-                            ISVNPropertyHandler handler) throws SVNException {
-    getClient().doGetProperty(path, propName, pegRevision, revision, recursive, handler);
-  }
-
-  @Override
-  public void doGetProperty(File path,
-                            String propName,
-                            SVNRevision pegRevision,
-                            SVNRevision revision,
-                            SVNDepth depth,
-                            ISVNPropertyHandler handler,
-                            Collection changeLists) throws SVNException {
-    getClient().doGetProperty(path, propName, pegRevision, revision, depth, handler, changeLists);
-  }
-
-  @Override
-  public void doGetProperty(SVNURL url,
-                            String propName,
-                            SVNRevision pegRevision,
-                            SVNRevision revision,
-                            boolean recursive,
-                            ISVNPropertyHandler handler) throws SVNException {
-    getClient().doGetProperty(url, propName, pegRevision, revision, recursive, handler);
-  }
-
-  @Override
-  public void doGetProperty(SVNURL url,
-                            String propName,
-                            SVNRevision pegRevision,
-                            SVNRevision revision,
-                            SVNDepth depth,
-                            ISVNPropertyHandler handler) throws SVNException {
-    getClient().doGetProperty(url, propName, pegRevision, revision, depth, handler);
-  }
-
-  @Override
-  public void doGetRevisionProperty(File path, String propName, SVNRevision revision, ISVNPropertyHandler handler) throws SVNException {
-    getClient().doGetRevisionProperty(path, propName, revision, handler);
-  }
-
-  @Override
-  public long doGetRevisionProperty(SVNURL url, String propName, SVNRevision revision, ISVNPropertyHandler handler) throws SVNException {
-    return getClient().doGetRevisionProperty(url, propName, revision, handler);
-  }
-
-  @Override
-  public void doDelete(File path, boolean force, boolean dryRun) throws SVNException {
-    getClient().doDelete(path, force, dryRun);
-  }
-
-  @Override
-  public void doDelete(File path, boolean force, boolean deleteFiles, boolean dryRun) throws SVNException {
-    getClient().doDelete(path, force, deleteFiles, dryRun);
-  }
-
-  @Override
-  public void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, boolean recursive) throws SVNException {
-    getClient().doAdd(path, force, mkdir, climbUnversionedParents, recursive);
-  }
-
-  @Override
-  public void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, boolean recursive, boolean includeIgnored)
-    throws SVNException {
-    getClient().doAdd(path, force, mkdir, climbUnversionedParents, recursive, includeIgnored);
-  }
-
-  @Override
-  public void doAdd(File path,
-                    boolean force,
-                    boolean mkdir,
-                    boolean climbUnversionedParents,
-                    SVNDepth depth,
-                    boolean includeIgnored,
-                    boolean makeParents) throws SVNException {
-    getClient().doAdd(path, force, mkdir, climbUnversionedParents, depth, includeIgnored, makeParents);
-  }
-
-  @Override
-  public void doAdd(File[] paths,
-                    boolean force,
-                    boolean mkdir,
-                    boolean climbUnversionedParents,
-                    SVNDepth depth,
-                    boolean depthIsSticky,
-                    boolean includeIgnored,
-                    boolean makeParents) throws SVNException {
-    getClient().doAdd(paths, force, mkdir, climbUnversionedParents, depth, depthIsSticky, includeIgnored, makeParents);
-  }
-
-  @Override
-  public void doAdd(File path,
-                    boolean force,
-                    boolean mkdir,
-                    boolean climbUnversionedParents,
-                    SVNDepth depth,
-                    boolean depthIsSticky,
-                    boolean includeIgnored,
-                    boolean makeParents) throws SVNException {
-    getClient().doAdd(path, force, mkdir, climbUnversionedParents, depth, depthIsSticky, includeIgnored, makeParents);
-  }
-
-  @Override
-  public void doMarkReplaced(File path) throws SVNException {
-    getClient().doMarkReplaced(path);
-  }
-
-  @Override
-  public void doRevert(File path, boolean recursive) throws SVNException {
-    getClient().doRevert(path, recursive);
-  }
-
-  @Override
-  public void doRevert(File[] paths, boolean recursive) throws SVNException {
-    getClient().doRevert(paths, recursive);
-  }
-
-  @Override
-  public void doRevert(File[] paths, SVNDepth depth, Collection changeLists) throws SVNException {
-    getClient().doRevert(paths, depth, changeLists);
-  }
-
-  @Override
-  public void doResolve(File path, boolean recursive) throws SVNException {
-    getClient().doResolve(path, recursive);
-  }
-
-  @Override
-  public void doResolve(File path, SVNDepth depth, SVNConflictChoice conflictChoice) throws SVNException {
-    getClient().doResolve(path, depth, conflictChoice);
-  }
-
-  @Override
-  public void doResolve(File path, SVNDepth depth, boolean resolveContents, boolean resolveProperties, SVNConflictChoice conflictChoice)
-    throws SVNException {
-    getClient().doResolve(path, depth, resolveContents, resolveProperties, conflictChoice);
-  }
-
-  @Override
-  public void doResolve(File path,
-                        SVNDepth depth,
-                        boolean resolveContents,
-                        boolean resolveProperties,
-                        boolean resolveTree,
-                        SVNConflictChoice conflictChoice) throws SVNException {
-    getClient().doResolve(path, depth, resolveContents, resolveProperties, resolveTree, conflictChoice);
-  }
-
-  @Override
-  public void doLock(File[] paths, boolean stealLock, String lockMessage) throws SVNException {
-    getClient().doLock(paths, stealLock, lockMessage);
-  }
-
-  @Override
-  public void doLock(SVNURL[] urls, boolean stealLock, String lockMessage) throws SVNException {
-    getClient().doLock(urls, stealLock, lockMessage);
-  }
-
-  @Override
-  public void doUnlock(File[] paths, boolean breakLock) throws SVNException {
-    getClient().doUnlock(paths, breakLock);
-  }
-
-  @Override
-  public void doUnlock(SVNURL[] urls, boolean breakLock) throws SVNException {
-    getClient().doUnlock(urls, breakLock);
-  }
-
-  @Override
   public void doInfo(File path, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException {
     getClient().doInfo(path, revision, recursive, handler);
   }
@@ -349,16 +75,6 @@
   }
 
   @Override
-  public String doGetWorkingCopyID(File path, String trailURL) throws SVNException {
-    return getClient().doGetWorkingCopyID(path, trailURL);
-  }
-
-  @Override
-  public String doGetWorkingCopyID(File path, String trailURL, boolean committed) throws SVNException {
-    return getClient().doGetWorkingCopyID(path, trailURL, committed);
-  }
-
-  @Override
   public SVNInfo doInfo(File path, SVNRevision revision) throws SVNException {
     return getClient().doInfo(path, revision);
   }
@@ -367,24 +83,4 @@
   public SVNInfo doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision) throws SVNException {
     return getClient().doInfo(url, pegRevision, revision);
   }
-
-  @Override
-  public void doCleanupWCProperties(File directory) throws SVNException {
-    getClient().doCleanupWCProperties(directory);
-  }
-
-  @Override
-  public void doSetWCFormat(File directory, int format) throws SVNException {
-    getClient().doSetWCFormat(directory, format);
-  }
-
-  @Override
-  public void doSetProperty(File path,
-                            String propName,
-                            SVNPropertyValue propValue,
-                            boolean force,
-                            boolean recursive,
-                            ISVNPropertyHandler handler) throws SVNException {
-    getClient().doSetProperty(path, propName, propValue, force, recursive, handler);
-  }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java
index f6d2c56..59ba154 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java
@@ -95,19 +95,47 @@
                           @Nullable SVNPropertyValue value,
                           @Nullable SVNDepth depth,
                           boolean force) throws VcsException {
+    runSetProperty(SvnTarget.fromFile(file), property, null, depth, value, force);
+  }
+
+  @Override
+  public void setRevisionProperty(@NotNull SvnTarget target,
+                                  @NotNull String property,
+                                  @NotNull SVNRevision revision,
+                                  @Nullable SVNPropertyValue value,
+                                  boolean force) throws VcsException {
+    runSetProperty(target, property, revision, null, value, force);
+  }
+
+  private void runSetProperty(@NotNull SvnTarget target,
+                              @NotNull String property,
+                              @Nullable SVNRevision revision,
+                              @Nullable SVNDepth depth,
+                              @Nullable SVNPropertyValue value,
+                              boolean force) throws VcsException {
     List<String> parameters = new ArrayList<String>();
     boolean isDelete = value == null;
 
     parameters.add(property);
+    if (revision != null) {
+      parameters.add("--revprop");
+      CommandUtil.put(parameters, revision);
+    }
     if (!isDelete) {
       parameters.add(SVNPropertyValue.getPropertyAsString(value));
       // --force could only be used in "propset" command, but not in "propdel" command
       CommandUtil.put(parameters, force, "--force");
     }
-    CommandUtil.put(parameters, file);
+    CommandUtil.put(parameters, target);
     CommandUtil.put(parameters, depth);
 
-    CommandUtil.execute(myVcs, SvnTarget.fromFile(file), isDelete ? SvnCommandName.propdel : SvnCommandName.propset, parameters, null);
+    // For some reason, command setting ignore property when working directory equals target directory (like
+    // "svn propset svn:ignore *.java . --depth empty") tries to set ignore also on child files and fails with error like
+    // "svn: E200009: Cannot set 'svn:ignore' on a file ('...File1.java')". So here we manually force home directory to be used.
+    // NOTE: that setting other properties (not svn:ignore) does not cause such error.
+    CommandUtil
+      .execute(myVcs, target, CommandUtil.getHomeDirectory(), isDelete ? SvnCommandName.propdel : SvnCommandName.propset, parameters,
+               null);
   }
 
   private void fillListParameters(@NotNull SvnTarget target,
@@ -211,7 +239,7 @@
     // such behavior is required to compatibility with SVNKit as some logic in merge depends on
     // whether null property data or property data with empty string value is returned
     if (value != null) {
-      result = new SVNPropertyData(property, SVNPropertyValue.create(value.trim()), null);
+      result = new SVNPropertyData(property, SVNPropertyValue.create(value.trim()), LF_SEPARATOR_OPTIONS);
     }
 
     return result;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
index 2f1ba5e..12bc0e9 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
@@ -1,11 +1,15 @@
 package org.jetbrains.idea.svn.properties;
 
 import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.util.LineSeparator;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.api.SvnClient;
 import org.tmatesoft.svn.core.SVNDepth;
 import org.tmatesoft.svn.core.SVNPropertyValue;
+import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
+import org.tmatesoft.svn.core.wc.ISVNOptions;
 import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
 import org.tmatesoft.svn.core.wc.SVNPropertyData;
 import org.tmatesoft.svn.core.wc.SVNRevision;
@@ -18,6 +22,13 @@
  */
 public interface PropertyClient extends SvnClient {
 
+  ISVNOptions LF_SEPARATOR_OPTIONS = new DefaultSVNOptions() {
+    @Override
+    public byte[] getNativeEOL() {
+      return CharsetToolkit.getUtf8Bytes(LineSeparator.LF.getSeparatorString());
+    }
+  };
+
   @Nullable
   SVNPropertyData getProperty(@NotNull final SvnTarget target,
                               @NotNull final String property,
@@ -39,4 +50,10 @@
                    @Nullable SVNPropertyValue value,
                    @Nullable SVNDepth depth,
                    boolean force) throws VcsException;
+
+  void setRevisionProperty(@NotNull SvnTarget target,
+                           @NotNull String property,
+                           @NotNull SVNRevision revision,
+                           @Nullable SVNPropertyValue value,
+                           boolean force) throws VcsException;
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
index ee72e59..d55eb68 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
@@ -31,9 +31,9 @@
     try {
       if (!revisionProperty) {
         if (target.isFile()) {
-          return myVcs.createWCClient().doGetProperty(target.getFile(), property, target.getPegRevision(), revision);
+          return createClient().doGetProperty(target.getFile(), property, target.getPegRevision(), revision);
         } else {
-          return myVcs.createWCClient().doGetProperty(target.getURL(), property, target.getPegRevision(), revision);
+          return createClient().doGetProperty(target.getURL(), property, target.getPegRevision(), revision);
         }
       } else {
         return getRevisionProperty(target, property, revision);
@@ -44,6 +44,14 @@
     }
   }
 
+  @NotNull
+  private SVNWCClient createClient() {
+    SVNWCClient client = myVcs.createWCClient();
+    client.setOptions(LF_SEPARATOR_OPTIONS);
+
+    return client;
+  }
+
   @Override
   public void getProperty(@NotNull SvnTarget target,
                           @NotNull String property,
@@ -68,7 +76,26 @@
                           @Nullable SVNDepth depth,
                           boolean force) throws VcsException {
     try {
-      myVcs.createWCClient().doSetProperty(file, property, value, force, depth, null, null);
+      createClient().doSetProperty(file, property, value, force, depth, null, null);
+    }
+    catch (SVNException e) {
+      throw new SvnBindException(e);
+    }
+  }
+
+  @Override
+  public void setRevisionProperty(@NotNull SvnTarget target,
+                                  @NotNull String property,
+                                  @NotNull SVNRevision revision,
+                                  @Nullable SVNPropertyValue value,
+                                  boolean force) throws VcsException {
+    try {
+      if (target.isFile()) {
+        createClient().doSetRevisionProperty(target.getFile(), revision, property, value, force, null);
+      }
+      else {
+        createClient().doSetRevisionProperty(target.getURL(), revision, property, value, force, null);
+      }
     }
     catch (SVNException e) {
       throw new SvnBindException(e);
@@ -80,7 +107,7 @@
                               @Nullable SVNRevision revision,
                               @Nullable SVNDepth depth,
                               @Nullable ISVNPropertyHandler handler) throws VcsException {
-    SVNWCClient client = myVcs.createWCClient();
+    SVNWCClient client = createClient();
 
     try {
       if (target.isURL()) {
@@ -94,7 +121,7 @@
   }
 
   private SVNPropertyData getRevisionProperty(@NotNull SvnTarget target, @NotNull final String property, @Nullable SVNRevision revision) throws SVNException{
-    final SVNWCClient client = myVcs.createWCClient();
+    final SVNWCClient client = createClient();
     final SVNPropertyData[] result = new SVNPropertyData[1];
     ISVNPropertyHandler handler = new ISVNPropertyHandler() {
       @Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java
index 72741ce..391077eb 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java
@@ -35,10 +35,7 @@
 import com.intellij.openapi.vcs.changes.patch.ApplyPatchExecutor;
 import com.intellij.openapi.vcs.changes.patch.FilePatchInProgress;
 import com.intellij.openapi.vcs.changes.patch.PatchWriter;
-import com.intellij.openapi.vfs.CharsetToolkit;
-import com.intellij.openapi.vfs.VfsUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileWrapper;
+import com.intellij.openapi.vfs.*;
 import com.intellij.util.WaitForProgressToShow;
 import com.intellij.util.containers.MultiMap;
 
@@ -79,7 +76,7 @@
       new FileSaverDescriptor("Save patch to", ""), myProject);
     final VirtualFile baseDir = myProject.getBaseDir();
     final VirtualFileWrapper save = dialog.save(baseDir, "TheirsChanges.patch");
-    if (save != null && save.getFile() != null) {
+    if (save != null) {
       final CommitContext commitContext = new CommitContext();
 
       final VirtualFile baseForPatch = myBaseForPatch == null ? baseDir : myBaseForPatch;
@@ -107,7 +104,7 @@
     for (Map.Entry<VirtualFile, Collection<FilePatchInProgress>> entry : patchGroups.entrySet()) {
       final VirtualFile vf = entry.getKey();
       final String currBasePath = vf.getPath();
-      final String relativePath = VfsUtil.getRelativePath(vf, baseDir, '/');
+      final String relativePath = VfsUtilCore.getRelativePath(vf, baseDir, '/');
       final boolean toConvert = !StringUtil.isEmptyOrSpaces(relativePath) && !".".equals(relativePath);
       for (FilePatchInProgress patchInProgress : entry.getValue()) {
         final TextFilePatch patch = patchInProgress.getPatch();
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java
new file mode 100644
index 0000000..a6a4d0f
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java
@@ -0,0 +1,187 @@
+/*
+ * 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 org.jetbrains.idea.svn.update;
+
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.commandLine.BaseUpdateCommandListener;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.*;
+import org.tmatesoft.svn.core.wc.SVNEvent;
+import org.tmatesoft.svn.core.wc.SVNEventAction;
+import org.tmatesoft.svn.core.wc.SVNInfo;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: Irina.Chernushina
+ * Date: 2/1/12
+ * Time: 12:13 PM
+ */
+// TODO: Currently make inherit SVNKit update implementation not to duplicate setXxx() methods.
+public class CmdUpdateClient extends SvnKitUpdateClient {
+  private static final Pattern ourExceptionPattern = Pattern.compile("svn: E(\\d{6}): .+");
+  private static final String ourAuthenticationRealm = "Authentication realm:";
+
+  @Override
+  public long[] doUpdate(final File[] paths, final SVNRevision revision, final SVNDepth depth, final boolean allowUnversionedObstructions,
+                         final boolean depthIsSticky, final boolean makeParents) throws SVNException {
+    // since one revision is passed -> I assume same repository here
+    checkWorkingCopy(paths[0]);
+
+    final List<String> parameters = new ArrayList<String>();
+
+    fillParameters(parameters, revision, depth, depthIsSticky, allowUnversionedObstructions);
+    CommandUtil.put(parameters, makeParents, "--parents");
+    CommandUtil.put(parameters, myIgnoreExternals, "--ignore-externals");
+    CommandUtil.put(parameters, paths);
+
+    return run(paths, parameters, SvnCommandName.up);
+  }
+
+  private void checkWorkingCopy(@NotNull File path) throws SVNException {
+    final SvnCommandLineInfoClient infoClient = new SvnCommandLineInfoClient(myVcs);
+    final SVNInfo info = infoClient.doInfo(path, SVNRevision.UNDEFINED);
+
+    if (info == null || info.getURL() == null) {
+      throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY, path.getPath()));
+    }
+  }
+
+  private long[] run(@NotNull File[] paths, @NotNull List<String> parameters, @NotNull SvnCommandName command) throws SVNException {
+    File base = paths[0];
+    base = base.isDirectory() ? base : base.getParentFile();
+
+    final AtomicReference<long[]> updatedToRevision = new AtomicReference<long[]>();
+    updatedToRevision.set(new long[0]);
+
+    final BaseUpdateCommandListener listener = createCommandListener(paths, updatedToRevision, base);
+    try {
+      CommandUtil.execute(myVcs, SvnTarget.fromFile(base), command, parameters, listener);
+    }
+    catch (VcsException e) {
+      throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e));
+    }
+
+    listener.throwIfException();
+
+    return updatedToRevision.get();
+  }
+
+  private BaseUpdateCommandListener createCommandListener(final File[] paths,
+                                                          final AtomicReference<long[]> updatedToRevision,
+                                                          final File base) {
+    return new BaseUpdateCommandListener(base, myDispatcher) {
+      final long[] myRevisions = new long[paths.length];
+
+      @Override
+      protected void beforeHandler(@NotNull SVNEvent event) {
+        if (SVNEventAction.UPDATE_COMPLETED.equals(event.getAction())) {
+          final long eventRevision = event.getRevision();
+          for (int i = 0; i < paths.length; i++) {
+            final File path = paths[i];
+            if (FileUtil.filesEqual(path, event.getFile())) {
+              myRevisions[i] = eventRevision;
+              break;
+            }
+          }
+        }
+      }
+
+      @Override
+      public void processTerminated(int exitCode) {
+        super.processTerminated(exitCode);
+        updatedToRevision.set(myRevisions);
+      }
+    };
+  }
+
+  private static void fillParameters(@NotNull List<String> parameters,
+                                     @Nullable SVNRevision revision,
+                                     @Nullable SVNDepth depth,
+                                     boolean depthIsSticky,
+                                     boolean allowUnversionedObstructions) {
+
+    CommandUtil.put(parameters, revision);
+    CommandUtil.put(parameters, depth, depthIsSticky);
+    CommandUtil.put(parameters, allowUnversionedObstructions, "--force");
+    parameters.add("--accept");
+    parameters.add("postpone");
+  }
+
+
+  private void checkForException(final StringBuffer sbError) throws SVNException {
+    if (sbError.length() == 0) return;
+    final String message = sbError.toString();
+    final Matcher matcher = ourExceptionPattern.matcher(message);
+    if (matcher.matches()) {
+      final String group = matcher.group(1);
+      if (group != null) {
+        try {
+          final int code = Integer.parseInt(group);
+          throw new SVNException(SVNErrorMessage.create(SVNErrorCode.getErrorCode(code), message));
+        } catch (NumberFormatException e) {
+          //
+        }
+      }
+    }
+    if (message.contains(ourAuthenticationRealm)) {
+      throw new SVNException(SVNErrorMessage.create(SVNErrorCode.AUTHN_CREDS_UNAVAILABLE, message));
+    }
+    throw new SVNException(SVNErrorMessage.create(SVNErrorCode.UNKNOWN, message));
+ }
+
+  @Override
+  public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
+    throws SVNException {
+    final long[] longs = doUpdate(new File[]{path}, revision, depth, allowUnversionedObstructions, depthIsSticky, false);
+    return longs[0];
+  }
+
+  @Override
+  public long doSwitch(File path,
+                       SVNURL url,
+                       SVNRevision pegRevision,
+                       SVNRevision revision,
+                       SVNDepth depth,
+                       boolean allowUnversionedObstructions,
+                       boolean depthIsSticky) throws SVNException {
+    checkWorkingCopy(path);
+
+    List<String> parameters = new ArrayList<String>();
+
+    CommandUtil.put(parameters, SvnTarget.fromURL(url, pegRevision));
+    CommandUtil.put(parameters, path, false);
+    fillParameters(parameters, revision, depth, depthIsSticky, allowUnversionedObstructions);
+    parameters.add("--ignore-ancestry");
+
+    long[] revisions = run(new File[]{path}, parameters, SvnCommandName.switchCopy);
+
+    return revisions != null && revisions.length > 0 ? revisions[0] : -1;
+  }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnKitUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnKitUpdateClient.java
new file mode 100644
index 0000000..a847975
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnKitUpdateClient.java
@@ -0,0 +1,93 @@
+/*
+ * 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 org.jetbrains.idea.svn.update;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc.SVNUpdateClient;
+
+import java.io.File;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: Irina.Chernushina
+ * Date: 2/1/12
+ * Time: 12:11 PM
+ */
+public class SvnKitUpdateClient extends BaseSvnClient implements UpdateClient {
+
+  @Nullable protected ISVNEventHandler myDispatcher;
+  protected boolean myIgnoreExternals;
+  protected boolean myLocksOnDemand;
+
+  @Override
+  public long[] doUpdate(File[] paths,
+                         SVNRevision revision,
+                         SVNDepth depth,
+                         boolean allowUnversionedObstructions,
+                         boolean depthIsSticky,
+                         boolean makeParents) throws SVNException {
+    return getClient().doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents);
+  }
+
+  @Override
+  public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
+    throws SVNException {
+    return getClient().doUpdate(path, revision, depth, allowUnversionedObstructions, depthIsSticky);
+  }
+
+  @Override
+  public long doSwitch(File path,
+                       SVNURL url,
+                       SVNRevision pegRevision,
+                       SVNRevision revision,
+                       SVNDepth depth,
+                       boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException {
+    return getClient().doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky);
+  }
+
+  @Override
+  public void setUpdateLocksOnDemand(boolean locksOnDemand) {
+    myLocksOnDemand = locksOnDemand;
+  }
+
+  @Override
+  public void setEventHandler(ISVNEventHandler dispatcher) {
+    myDispatcher = dispatcher;
+  }
+
+  @Override
+  public void setIgnoreExternals(boolean ignoreExternals) {
+    myIgnoreExternals = ignoreExternals;
+  }
+
+  @NotNull
+  private SVNUpdateClient getClient() {
+    SVNUpdateClient client = myVcs.createUpdateClient();
+
+    client.setEventHandler(myDispatcher);
+    client.setIgnoreExternals(myIgnoreExternals);
+    client.setUpdateLocksOnDemand(myLocksOnDemand);
+
+    return client;
+  }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
index 148d717..af9ef2e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
@@ -25,7 +25,6 @@
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.*;
 import org.jetbrains.idea.svn.api.ClientFactory;
-import org.jetbrains.idea.svn.portable.SvnUpdateClientI;
 import org.tmatesoft.svn.core.SVNException;
 import org.tmatesoft.svn.core.SVNURL;
 import org.tmatesoft.svn.core.io.SVNRepository;
@@ -83,11 +82,11 @@
       final boolean isSwitch = rootInfo != null && rootInfo.getUrl() != null && ! rootInfo.getUrl().equals(sourceUrl);
       final SVNRevision updateTo = rootInfo != null && rootInfo.isUpdateToRevision() ? rootInfo.getRevision() : SVNRevision.HEAD;
       if (isSwitch) {
-        final SvnUpdateClientI updateClient = createUpdateClient(configuration, root, true, sourceUrl);
+        final UpdateClient updateClient = createUpdateClient(configuration, root, true, sourceUrl);
         myHandler.addToSwitch(root, sourceUrl);
         rev = updateClient.doSwitch(root, rootInfo.getUrl(), SVNRevision.UNDEFINED, updateTo, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
       } else {
-        final SvnUpdateClientI updateClient = createUpdateClient(configuration, root, false, sourceUrl);
+        final UpdateClient updateClient = createUpdateClient(configuration, root, false, sourceUrl);
         rev = updateClient.doUpdate(root, updateTo, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
       }
 
@@ -96,14 +95,14 @@
       return rev;
     }
 
-    private SvnUpdateClientI createUpdateClient(SvnConfiguration configuration, File root, boolean isSwitch, SVNURL sourceUrl) {
+    private UpdateClient createUpdateClient(SvnConfiguration configuration, File root, boolean isSwitch, SVNURL sourceUrl) {
       boolean is17 = WorkingCopyFormat.ONE_DOT_SEVEN.equals(myVcs.getWorkingCopyFormat(root));
       boolean isSupportedProtocol =
         SvnAuthenticationManager.HTTP.equals(sourceUrl.getProtocol()) || SvnAuthenticationManager.HTTPS.equals(sourceUrl.getProtocol());
 
       // TODO: Update this with just myVcs.getFactory(root) when switch and authentication protocols are implemented for command line
       ClientFactory factory = is17 && (isSwitch || !isSupportedProtocol) ? myVcs.getSvnKitFactory() : myVcs.getFactory(root);
-      final SvnUpdateClientI updateClient = factory.createUpdateClient();
+      final UpdateClient updateClient = factory.createUpdateClient();
 
       if (! isSwitch) {
         updateClient.setIgnoreExternals(configuration.IGNORE_EXTERNALS);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateClient.java
new file mode 100644
index 0000000..b68829e
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateClient.java
@@ -0,0 +1,45 @@
+/*
+ * 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 org.jetbrains.idea.svn.update;
+
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: Irina.Chernushina
+ * Date: 2/1/12
+ * Time: 11:59 AM
+ */
+public interface UpdateClient extends SvnClient {
+
+  long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean makeParents) throws SVNException;
+
+  long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
+
+  void setUpdateLocksOnDemand(boolean locksOnDemand);
+
+  long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
+
+  void setEventHandler(ISVNEventHandler dispatcher);
+  void setIgnoreExternals(boolean ignoreExternals);
+}
diff --git a/plugins/terminal/lib/jediterm-pty-0.08.jar b/plugins/terminal/lib/jediterm-pty-0.08.jar
index f7073d5..e9ef4dd 100644
--- a/plugins/terminal/lib/jediterm-pty-0.08.jar
+++ b/plugins/terminal/lib/jediterm-pty-0.08.jar
Binary files differ
diff --git a/plugins/terminal/resources/META-INF/terminal.xml b/plugins/terminal/resources/META-INF/terminal.xml
index 24a8466..a0282b7 100644
--- a/plugins/terminal/resources/META-INF/terminal.xml
+++ b/plugins/terminal/resources/META-INF/terminal.xml
@@ -13,5 +13,14 @@
 
     <applicationService serviceInterface="org.jetbrains.plugins.terminal.TerminalView"
                         serviceImplementation="org.jetbrains.plugins.terminal.TerminalView"/>
+
+    <projectConfigurable instance="org.jetbrains.plugins.terminal.TerminalOptionsConfigurable"/>
   </extensions>
+
+  <application-components>
+    <component>
+      <interface-class>org.jetbrains.plugins.terminal.TerminalOptionsProvider</interface-class>
+      <implementation-class>org.jetbrains.plugins.terminal.TerminalOptionsProvider</implementation-class>
+    </component>
+  </application-components>
 </idea-plugin>
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
index fcf0627..3477859b 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
@@ -171,7 +171,7 @@
       openSession(terminalWidget, createTtyConnector(process));
     }
     catch (Exception e) {
-      throw new RuntimeException(e.getMessage(), e);
+      LOG.error("Can't open terminal session:" + e.getMessage(), e);
     }
   }
 }
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
index d5caf0b..56664cf 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
@@ -9,6 +9,7 @@
 import com.jediterm.terminal.ui.TerminalAction;
 import com.jediterm.terminal.ui.TerminalWidget;
 import com.jediterm.terminal.ui.settings.SettingsProvider;
+import com.jediterm.terminal.ui.settings.TabbedSettingsProvider;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -21,7 +22,7 @@
  */
 public class JBTabbedTerminalWidget extends TabbedTerminalWidget {
 
-  public JBTabbedTerminalWidget(@NotNull SettingsProvider settingsProvider, @NotNull Predicate<TerminalWidget> createNewSessionAction) {
+  public JBTabbedTerminalWidget(@NotNull TabbedSettingsProvider settingsProvider, @NotNull Predicate<TerminalWidget> createNewSessionAction) {
     super(settingsProvider, createNewSessionAction);
 
     convertActions(this, getActions());
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
index 84a9d2f..e8fd25b 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
@@ -20,6 +20,7 @@
 package org.jetbrains.plugins.terminal;
 
 import com.google.common.base.Predicate;
+import com.intellij.ide.ui.UISettings;
 import com.intellij.openapi.actionSystem.*;
 import com.intellij.openapi.ide.CopyPasteManager;
 import com.intellij.openapi.keymap.Keymap;
@@ -27,7 +28,6 @@
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.util.JBHiDPIScaledImage;
 import com.intellij.util.RetinaImage;
-import com.intellij.util.ui.GraphicsUtil;
 import com.intellij.util.ui.UIUtil;
 import com.jediterm.terminal.display.BackBuffer;
 import com.jediterm.terminal.display.StyleState;
@@ -96,8 +96,9 @@
     }
   }
 
-  protected void setupAntialiasing(Graphics graphics, boolean antialiasing) {
-    GraphicsUtil.setupAntialiasing(graphics, antialiasing, false);
+  @Override
+  protected void setupAntialiasing(Graphics graphics) {
+    UISettings.setupAntialiasing(graphics);
   }
 
   @Override
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSchemeColorPalette.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSchemeColorPalette.java
new file mode 100644
index 0000000..4803140
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSchemeColorPalette.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+import com.intellij.execution.process.ColoredOutputTypeRegistry;
+import com.intellij.execution.process.ConsoleHighlighter;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.jediterm.terminal.emulator.ColorPalette;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.*;
+
+/**
+ * @author traff
+ */
+public class JBTerminalSchemeColorPalette extends ColorPalette {
+
+  private final EditorColorsScheme myColorsScheme;
+
+  protected JBTerminalSchemeColorPalette(EditorColorsScheme scheme) {
+    super();
+    myColorsScheme = scheme;
+  }
+
+  @Override
+  public Color[] getIndexColors() {
+    Color[] result = XTERM_PALETTE.getIndexColors();
+    for (int i = 1; i < 7; i++) {
+      result[i] = myColorsScheme.getAttributes(ColoredOutputTypeRegistry.getAnsiColorKey(i)).getForegroundColor();
+    }
+    return result;
+  }
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
index b67002e9..b0f9cc3 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
@@ -2,9 +2,11 @@
 
 import com.intellij.application.options.OptionsConstants;
 import com.intellij.execution.ui.ConsoleViewContentType;
+import com.intellij.ide.ui.UISettings;
 import com.intellij.openapi.actionSystem.KeyboardShortcut;
 import com.intellij.openapi.actionSystem.Shortcut;
 import com.intellij.openapi.editor.colors.*;
+import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
 import com.intellij.openapi.editor.markup.TextAttributes;
 import com.intellij.openapi.keymap.KeymapManager;
 import com.intellij.openapi.options.FontSize;
@@ -18,6 +20,7 @@
 import com.jediterm.terminal.TtyConnector;
 import com.jediterm.terminal.emulator.ColorPalette;
 import com.jediterm.terminal.ui.settings.DefaultSettingsProvider;
+import com.jediterm.terminal.ui.settings.DefaultTabbedSettingsProvider;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -32,7 +35,7 @@
 /**
  * @author traff
  */
-class JBTerminalSystemSettingsProvider extends DefaultSettingsProvider {
+class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider {
 
   private final EditorColorsScheme myColorScheme;
 
@@ -52,7 +55,7 @@
 
   @Override
   public ColorPalette getTerminalColorPalette() {
-    return SystemInfo.isWindows ? ColorPalette.WINDOWS_PALETTE : ColorPalette.XTERM_PALETTE;
+    return new JBTerminalSchemeColorPalette(myColorScheme);
   }
 
   private KeyStroke[] getKeyStrokesByActionId(String actionId) {
@@ -74,6 +77,16 @@
   }
 
   @Override
+  public String tabName(TtyConnector ttyConnector, String sessionName) { //for local terminal use name from settings
+    if (ttyConnector instanceof PtyProcessTtyConnector) {
+      return TerminalOptionsProvider.getInstance().getTabName();
+    }
+    else {
+      return sessionName;
+    }
+  }
+
+  @Override
   public float getLineSpace() {
     return myColorScheme.getConsoleLineSpacing();
   }
@@ -131,10 +144,41 @@
     return (float)myColorScheme.getConsoleFontSize();
   }
 
+
+  @Override
+  public boolean useAntialiasing() {
+    return UISettings.getInstance().ANTIALIASING_IN_EDITOR;
+  }
+
+  @Override
+  public int caretBlinkingMs() {
+    return EditorSettingsExternalizable.getInstance().getBlinkPeriod();
+  }
+
   public EditorColorsScheme getColorScheme() {
     return createBoundColorSchemeDelegate(null);
   }
 
+  @Override
+  public boolean audibleBell() {
+    return TerminalOptionsProvider.getInstance().audibleBell();
+  }
+
+  @Override
+  public boolean enableMouseReporting() {
+    return TerminalOptionsProvider.getInstance().enableMouseReporting();
+  }
+
+  @Override
+  public boolean copyOnSelect() {
+    return TerminalOptionsProvider.getInstance().copyOnSelection();
+  }
+
+  @Override
+  public boolean pasteOnMiddleMouseClick() {
+    return TerminalOptionsProvider.getInstance().pasteOnMiddleMouseButton();
+  }
+
   @NotNull
   public EditorColorsScheme createBoundColorSchemeDelegate(@Nullable final EditorColorsScheme customGlobalScheme) {
     return new MyColorSchemeDelegate(customGlobalScheme);
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
index dc8c410..064dad9 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
@@ -39,21 +39,36 @@
     super(project);
     myDefaultCharset = Charset.forName("UTF-8");
 
+    String shellPath = TerminalOptionsProvider.getInstance().getShellPath();
+
     if (SystemInfo.isUnix) {
       File rcFile = findRCFile();
 
-      if (rcFile != null) {
-        myCommand = new String[]{"/bin/bash", "--rcfile", rcFile.getAbsolutePath(), "-i"};
+      String shellName = getShellName(shellPath);
+
+      if (rcFile != null && (shellName.equals("bash") || shellName.equals("sh"))) {
+        myCommand = new String[]{shellPath, "--rcfile", rcFile.getAbsolutePath(), "-i"};
+      }
+      else if (hasLoginArgument(shellName)) {
+        myCommand = new String[]{shellPath, "--login"};
       }
       else {
-        myCommand = new String[]{"/bin/bash", "--login"};
+        myCommand = shellPath.split(" ");
       }
     }
     else {
-      myCommand = new String[]{"cmd.exe"};
+      myCommand = new String[]{shellPath};
     }
   }
 
+  private static boolean hasLoginArgument(String name) {
+    return name.equals("bash") || name.equals("sh") || name.equals("zsh");
+  }
+
+  private static String getShellName(String path) {
+    return new File(path).getName();
+  }
+
   private static File findRCFile() {
     try {
       final String folder = PtyUtil.getJarFolder();
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsConfigurable.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsConfigurable.java
new file mode 100644
index 0000000..9ea8fa2
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsConfigurable.java
@@ -0,0 +1,100 @@
+/*
+ * 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;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * @author traff
+ */
+public class TerminalOptionsConfigurable implements SearchableConfigurable, Configurable.NoScroll, Disposable {
+  public static final String TERMINAL_SETTINGS_HELP_REFERENCE = "reference.settings.terminal";
+
+  private TerminalSettingsPanel myPanel;
+
+  private final TerminalOptionsProvider myOptionsProvider;
+  private Project myProject;
+
+  public TerminalOptionsConfigurable(Project project) {
+    myOptionsProvider = TerminalOptionsProvider.getInstance();
+    myProject = project;
+  }
+
+  @NotNull
+  @Override
+  public String getId() {
+    return "terminal";
+  }
+
+  @Override
+  public Runnable enableSearch(String option) {
+    return null;
+  }
+
+
+  @Nls
+  @Override
+  public String getDisplayName() {
+    return "Terminal";
+  }
+
+  @Override
+  public String getHelpTopic() {
+    return TERMINAL_SETTINGS_HELP_REFERENCE;
+  }
+
+  @Override
+  public JComponent createComponent() {
+    myPanel = new TerminalSettingsPanel();
+
+    return myPanel.createPanel(myOptionsProvider);
+  }
+
+  @Override
+  public boolean isModified() {
+    return myPanel.isModified();
+  }
+
+  @Override
+  public void apply() throws ConfigurationException {
+    myPanel.apply();
+  }
+
+
+  @Override
+  public void reset() {
+    myPanel.reset();
+  }
+
+  @Override
+  public void disposeUIResources() {
+    Disposer.dispose(this);
+  }
+
+  @Override
+  public void dispose() {
+    myPanel = null;
+  }
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsProvider.java
new file mode 100644
index 0000000..dd59065
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsProvider.java
@@ -0,0 +1,163 @@
+/*
+ * 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;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
+import com.jediterm.terminal.emulator.ColorPalette;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+/**
+ * @author traff
+ */
+@State(
+  name = "TerminalOptionsProvider",
+  storages = {
+    @Storage(
+      file = StoragePathMacros.APP_CONFIG + "/terminal.xml"
+    )}
+)
+public class TerminalOptionsProvider implements PersistentStateComponent<TerminalOptionsProvider.State>, ExportableApplicationComponent {
+  private State myState = new State();
+
+  public static TerminalOptionsProvider getInstance() {
+    return ApplicationManager.getApplication().getComponent(TerminalOptionsProvider.class);
+  }
+
+  @Override
+  public State getState() {
+    return myState;
+  }
+
+  @Override
+  public void loadState(State state) {
+    myState.myShellPath = state.myShellPath;
+    myState.myCloseSessionOnLogout = state.myCloseSessionOnLogout;
+    myState.myReportMouse = state.myReportMouse;
+    myState.mySoundBell = state.mySoundBell;
+    myState.myTabName = state.myTabName;
+    myState.myCopyOnSelection = state.myCopyOnSelection;
+    myState.myPasteOnMiddleMouseButton = state.myPasteOnMiddleMouseButton;
+  }
+
+  public boolean closeSessionOnLogout() {
+    return myState.myCloseSessionOnLogout;
+  }
+
+  public boolean enableMouseReporting() {
+    return myState.myReportMouse;
+  }
+
+  public boolean audibleBell() {
+    return myState.mySoundBell;
+  }
+
+  public String getTabName() {
+    return myState.myTabName;
+  }
+
+  public static class State {
+    public String myShellPath = getDefaultShellPath();
+    public String myTabName = "Local";
+    public boolean myCloseSessionOnLogout = true;
+    public boolean myReportMouse = true;
+    public boolean mySoundBell = true;
+    public boolean myCopyOnSelection = true;
+    public boolean myPasteOnMiddleMouseButton = true;
+  }
+
+  public String getShellPath() {
+    return myState.myShellPath;
+  }
+
+  private static String getDefaultShellPath() {
+    if (SystemInfo.isUnix) {
+      return "/bin/bash";
+    }
+    else {
+      return "cmd.exe";
+    }
+  }
+
+  public void setShellPath(String shellPath) {
+    myState.myShellPath = shellPath;
+  }
+
+  public void setTabName(String tabName) {
+    myState.myTabName = tabName;
+  }
+
+  public void setCloseSessionOnLogout(boolean closeSessionOnLogout) {
+    myState.myCloseSessionOnLogout = closeSessionOnLogout;
+  }
+
+  public void setReportMouse(boolean reportMouse) {
+    myState.myReportMouse = reportMouse;
+  }
+
+  public void setSoundBell(boolean soundBell) {
+    myState.mySoundBell = soundBell;
+  }
+
+  public boolean copyOnSelection() {
+    return myState.myCopyOnSelection;
+  }
+
+  public void setCopyOnSelection(boolean copyOnSelection) {
+    myState.myCopyOnSelection = copyOnSelection;
+  }
+
+  public boolean pasteOnMiddleMouseButton() {
+    return myState.myPasteOnMiddleMouseButton;
+  }
+
+  public void setPasteOnMiddleMouseButton(boolean pasteOnMiddleMouseButton) {
+    myState.myPasteOnMiddleMouseButton = pasteOnMiddleMouseButton;
+  }
+
+  @Override
+  public void initComponent() {
+  }
+
+  @Override
+  public void disposeComponent() {
+  }
+
+  @NotNull
+  @Override
+  public File[] getExportFiles() {
+    return new File[]{new File(PathManager.getOptionsPath() + File.separatorChar + "terminal.xml")};
+  }
+
+  @NotNull
+  @Override
+  public String getPresentableName() {
+    return "TerminalOptions";
+  }
+
+  @NotNull
+  @Override
+  public String getComponentName() {
+    return "TerminalOptionsProvider";
+  }
+}
+
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.form b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.form
new file mode 100644
index 0000000..45678d4
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.form
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.terminal.TerminalSettingsPanel">
+  <grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="20" y="20" width="500" height="400"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <grid id="8f9b9" layout-manager="GridLayoutManager" row-count="6" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <clientProperties>
+          <BorderFactoryClass class="java.lang.String" value=""/>
+        </clientProperties>
+        <border type="none"/>
+        <children>
+          <grid id="57ec0" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+            <margin top="0" left="0" bottom="0" right="0"/>
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+            <border type="none"/>
+            <children>
+              <component id="b854b" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <horizontalTextPosition value="2"/>
+                  <text value="Default shell"/>
+                </properties>
+              </component>
+              <component id="8b4db" class="javax.swing.JTextField" binding="myShellTextField">
+                <constraints>
+                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                    <preferred-size width="150" height="-1"/>
+                  </grid>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="f633a" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <horizontalTextPosition value="2"/>
+                  <text value="Tab name"/>
+                </properties>
+              </component>
+              <component id="5495b" class="javax.swing.JTextField" binding="myTabNameTextField">
+                <constraints>
+                  <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                    <preferred-size width="150" height="-1"/>
+                  </grid>
+                </constraints>
+                <properties/>
+              </component>
+            </children>
+          </grid>
+          <vspacer id="d777c">
+            <constraints>
+              <grid row="5" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+            </constraints>
+          </vspacer>
+          <grid id="caa1d" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+            <margin top="0" left="0" bottom="0" right="0"/>
+            <constraints>
+              <grid row="1" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+            <border type="none"/>
+            <children>
+              <component id="f974" class="com.intellij.ui.components.JBCheckBox" binding="myCloseSessionCheckBox">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <text value="Close session when it ends"/>
+                </properties>
+              </component>
+              <hspacer id="4d085">
+                <constraints>
+                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                </constraints>
+              </hspacer>
+              <grid id="b4260" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+                <margin top="0" left="0" bottom="0" right="0"/>
+                <constraints>
+                  <grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <component id="7a03b" class="com.intellij.ui.components.JBCheckBox" binding="mySoundBellCheckBox">
+                    <constraints>
+                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties>
+                      <text value="Audible bell"/>
+                    </properties>
+                  </component>
+                  <hspacer id="d3b9">
+                    <constraints>
+                      <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                  </hspacer>
+                </children>
+              </grid>
+            </children>
+          </grid>
+          <grid id="efc62" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+            <margin top="0" left="0" bottom="0" right="0"/>
+            <constraints>
+              <grid row="2" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+            <border type="none"/>
+            <children>
+              <component id="e2773" class="com.intellij.ui.components.JBCheckBox" binding="myMouseReportCheckBox">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <text value="Mouse reporting"/>
+                </properties>
+              </component>
+              <hspacer id="2f4aa">
+                <constraints>
+                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                </constraints>
+              </hspacer>
+            </children>
+          </grid>
+          <grid id="e134" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+            <margin top="0" left="0" bottom="0" right="0"/>
+            <constraints>
+              <grid row="3" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+            <border type="none"/>
+            <children>
+              <component id="f1844" class="com.intellij.ui.components.JBCheckBox" binding="myCopyOnSelectionCheckBox">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <text value="Copy to clipboard on selection"/>
+                </properties>
+              </component>
+              <hspacer id="f4740">
+                <constraints>
+                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                </constraints>
+              </hspacer>
+            </children>
+          </grid>
+          <grid id="5aa62" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+            <margin top="0" left="0" bottom="0" right="0"/>
+            <constraints>
+              <grid row="4" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+            <border type="none"/>
+            <children>
+              <component id="8a427" class="com.intellij.ui.components.JBCheckBox" binding="myPasteOnMiddleButtonCheckBox">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <text value="Paste on middle mouse button click"/>
+                </properties>
+              </component>
+              <hspacer id="cfc3e">
+                <constraints>
+                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                </constraints>
+              </hspacer>
+            </children>
+          </grid>
+        </children>
+      </grid>
+    </children>
+  </grid>
+  <buttonGroups>
+    <group name="1">
+      <member id="3c34e"/>
+      <member id="97f18"/>
+      <member id="12b2e"/>
+    </group>
+  </buttonGroups>
+</form>
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.java
new file mode 100644
index 0000000..0400bb3
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.java
@@ -0,0 +1,74 @@
+/*
+ * 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;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.ui.components.JBCheckBox;
+
+import javax.swing.*;
+
+/**
+ * @author traff
+ */
+public class TerminalSettingsPanel {
+  private JPanel myWholePanel;
+  private JTextField myShellTextField;
+  private JBCheckBox mySoundBellCheckBox;
+  private JBCheckBox myCloseSessionCheckBox;
+  private JBCheckBox myMouseReportCheckBox;
+  private JTextField myTabNameTextField;
+  private JBCheckBox myPasteOnMiddleButtonCheckBox;
+  private JBCheckBox myCopyOnSelectionCheckBox;
+  private TerminalOptionsProvider myOptionsProvider;
+
+  public JComponent createPanel(TerminalOptionsProvider provider) {
+    myOptionsProvider = provider;
+
+    return myWholePanel;
+  }
+
+  public boolean isModified() {
+    return !Comparing.equal(myShellTextField.getText(), myOptionsProvider.getShellPath())
+           || !Comparing.equal(myTabNameTextField.getText(), myOptionsProvider.getTabName())
+           || (myCloseSessionCheckBox.isSelected() != myOptionsProvider.closeSessionOnLogout())
+           || (myMouseReportCheckBox.isSelected() != myOptionsProvider.enableMouseReporting())
+           || (mySoundBellCheckBox.isSelected() != myOptionsProvider.audibleBell())
+           || (myCopyOnSelectionCheckBox.isSelected() != myOptionsProvider.copyOnSelection())
+           || (myPasteOnMiddleButtonCheckBox.isSelected() != myOptionsProvider.pasteOnMiddleMouseButton())
+      ;
+  }
+
+  public void apply() {
+    myOptionsProvider.setShellPath(myShellTextField.getText());
+    myOptionsProvider.setTabName(myTabNameTextField.getText());
+    myOptionsProvider.setCloseSessionOnLogout(myCloseSessionCheckBox.isSelected());
+    myOptionsProvider.setReportMouse(myMouseReportCheckBox.isSelected());
+    myOptionsProvider.setSoundBell(mySoundBellCheckBox.isSelected());
+    myOptionsProvider.setCopyOnSelection(myCopyOnSelectionCheckBox.isSelected());
+    myOptionsProvider.setPasteOnMiddleMouseButton(myPasteOnMiddleButtonCheckBox.isSelected());
+  }
+
+  public void reset() {
+    myShellTextField.setText(myOptionsProvider.getShellPath());
+    myTabNameTextField.setText(myOptionsProvider.getTabName());
+    myCloseSessionCheckBox.setSelected(myOptionsProvider.closeSessionOnLogout());
+    myMouseReportCheckBox.setSelected(myOptionsProvider.enableMouseReporting());
+    mySoundBellCheckBox.setSelected(myOptionsProvider.audibleBell());
+    myCopyOnSelectionCheckBox.setSelected(myOptionsProvider.copyOnSelection());
+    myPasteOnMiddleButtonCheckBox.setSelected(myOptionsProvider.pasteOnMiddleMouseButton());
+  }
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
index 188be8f..ff54c00 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
@@ -2,11 +2,13 @@
 
 import com.intellij.icons.AllIcons;
 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;
+import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.wm.ToolWindow;
 import com.intellij.openapi.wm.ToolWindowManager;
 import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
@@ -75,6 +77,15 @@
         }
       }
     });
+
+    Disposer.register(project, new Disposable() {
+      @Override
+      public void dispose() {
+        if (myTerminalWidget != null) {
+          myTerminalWidget.dispose();
+        }
+      }
+    });
   }
 
   private Content createToolWindowContentPanel(@Nullable LocalTerminalDirectRunner terminalRunner,
@@ -102,7 +113,7 @@
     content.setCloseable(true);
 
     content.setPreferredFocusableComponent(terminalWidget.getComponent());
-    
+
     return content;
   }
 
diff --git a/plugins/testng/src/META-INF/plugin.xml b/plugins/testng/src/META-INF/plugin.xml
index fe64bc8..fff400d 100644
--- a/plugins/testng/src/META-INF/plugin.xml
+++ b/plugins/testng/src/META-INF/plugin.xml
@@ -56,6 +56,10 @@
       <forcedElementWeigher implementation="com.theoryinpractice.testng.TestNGForcedElementWeigher"/>
       <gotoRelatedProvider implementation="com.theoryinpractice.testng.TestNGRelatedFilesProvider"/>
       <methodReferencesSearch implementation="com.theoryinpractice.testng.DataProviderSearcher"/>
+      <stacktrace.fold substring="at org.testng.internal."/>
+      <stacktrace.fold substring="at org.testng.TestRunner."/>
+      <stacktrace.fold substring="at org.testng.SuiteRunner."/>
+      <stacktrace.fold substring="at org.testng.TestNG.run"/>
     </extensions>
     <extensionPoints >
       <extensionPoint qualifiedName="com.theoryinpractice.testng.listener" interface="org.testng.IDEATestNGListener"/>
diff --git a/plugins/testng/src/com/theoryinpractice/testng/TestNGFramework.java b/plugins/testng/src/com/theoryinpractice/testng/TestNGFramework.java
index 0df50c5..1cf1f53 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/TestNGFramework.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/TestNGFramework.java
@@ -167,6 +167,11 @@
     return inClass;
   }
 
+  @Override
+  public char getMnemonic() {
+    return 'N';
+  }
+
   public FileTemplateDescriptor getSetUpMethodFileTemplateDescriptor() {
     return new FileTemplateDescriptor("TestNG SetUp Method.java");
   }
diff --git a/resources-en/src/messages/CompilerBundle.properties b/resources-en/src/messages/CompilerBundle.properties
index 902e3df..b9167ee 100644
--- a/resources-en/src/messages/CompilerBundle.properties
+++ b/resources-en/src/messages/CompilerBundle.properties
@@ -155,7 +155,7 @@
 label.text.class.path=Class &Path:
 element.type.name.artifact=Artifact
 dialog.title.choose.artifacts=Choose Artifacts
-node.text.0.directory.content=''{0}'' directory content
+node.text.0.directory.content=''{0}'' directory contents
 element.type.name.library.files=Library Files
 node.text.0.compile.output=''{0}'' compile output
 node.text.0.test.compile.output=''{0}'' test compile output
diff --git a/resources-en/src/messages/DebuggerBundle.properties b/resources-en/src/messages/DebuggerBundle.properties
index 11189d3..01984ee 100644
--- a/resources-en/src/messages/DebuggerBundle.properties
+++ b/resources-en/src/messages/DebuggerBundle.properties
@@ -445,3 +445,5 @@
 action.kill.process.text=Kill Process
 action.kill.process.description=Forcibly terminate debugged application
 evaluation.error.unknown.method.return.type=Cannot resolve method return type: {0}
+
+java.breakpoint.title=Java Line Breakpoints
diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml
index b83adb0..1460baf 100644
--- a/resources/src/META-INF/IdeaPlugin.xml
+++ b/resources/src/META-INF/IdeaPlugin.xml
@@ -1429,8 +1429,6 @@
     <wizardMode implementation="com.intellij.ide.util.newProjectWizard.modes.CreateProjectFromSourcesMode" id="CreateProjectFromSourcesMode" order="after CreateFromScratchMode"/>
     <wizardMode implementation="com.intellij.ide.util.newProjectWizard.modes.CreateModuleFromSourcesMode" id="CreateModuleFromSourcesMode" order="after CreateProjectFromSourcesMode"/>
 
-    <projectWizard.projectCategory implementation="com.intellij.ide.projectWizard.CommonJavaProjectCategory"/>
-
     <projectTemplateParameterFactory implementation="com.intellij.openapi.module.BasePackageParameterFactory"/>
 
     <projectStructureDetector implementation="com.intellij.ide.util.projectWizard.importSources.impl.JavaProjectStructureDetector" order="first"/>
@@ -1478,6 +1476,8 @@
                      implementationClass="org.jetbrains.generate.tostring.inspection.FieldNotUsedInToStringInspection"/>
 
     <codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.jarFinder.FindJarQuickFixProvider"/>
+
+    <xdebugger.breakpointType implementation="org.jetbrains.java.debugger.breakpoints.JavaBreakpointType"/>
   </extensions>
 
   <actions>
diff --git a/spellchecker/src/com/intellij/spellchecker/dictionary/ProjectDictionary.java b/spellchecker/src/com/intellij/spellchecker/dictionary/ProjectDictionary.java
index b72c8f4..dd8c11c 100644
--- a/spellchecker/src/com/intellij/spellchecker/dictionary/ProjectDictionary.java
+++ b/spellchecker/src/com/intellij/spellchecker/dictionary/ProjectDictionary.java
@@ -31,7 +31,6 @@
   private String activeName;
   private Set<EditableDictionary> dictionaries;
 
-
   public ProjectDictionary() {
   }
 
@@ -50,10 +49,6 @@
     return DEFAULT_PROJECT_DICTIONARY_NAME;
   }
 
-  public String getActiveName() {
-    return activeName;
-  }
-
   public void setActiveName(String name) {
     activeName = name;
   }
@@ -124,7 +119,6 @@
     return result;
   }
 
-
   @Override
   public void replaceAll(@Nullable Collection<String> words) {
     getActiveDictionary().replaceAll(words);
@@ -144,7 +138,10 @@
     }
     Set<String> words = new HashSet<String>();
     for (Dictionary dictionary : dictionaries) {
-      words.addAll(dictionary.getWords());
+      Set<String> otherWords = dictionary.getWords();
+      if (otherWords != null) {
+        words.addAll(otherWords);
+      }
     }
     return words;
   }
diff --git a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
index b660e4c..8e65b7f 100644
--- a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
+++ b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
@@ -11,6 +11,7 @@
 arity
 asensitive
 aspectj
+async
 attr
 attlist
 auth
@@ -84,6 +85,7 @@
 cron
 ctrl
 customizer
+cyclomatic
 datafile
 datafiles
 datetime
diff --git a/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionarySplitter.java b/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionarySplitter.java
index 247ae43..998732f 100644
--- a/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionarySplitter.java
+++ b/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionarySplitter.java
@@ -16,7 +16,6 @@
 package com.intellij.spellchecker.state;
 
 import com.intellij.openapi.components.StateSplitter;
-import com.intellij.openapi.util.JDOMUtil;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.util.text.UniqueNameGenerator;
@@ -31,22 +30,20 @@
  * @author shkate@jetbrains.com
  */
 public class ProjectDictionarySplitter implements StateSplitter {
-
+  @Override
   public List<Pair<Element, String>> splitState(Element e) {
     final UniqueNameGenerator generator = new UniqueNameGenerator();
-
     List<Pair<Element, String>> result = new ArrayList<Pair<Element, String>>();
-    for (Element element : JDOMUtil.getElements(e)) {
-      final String name = generator.generateUniqueName(FileUtil.sanitizeFileName(element.getAttributeValue(DictionaryState.NAME_ATTRIBUTE))) + ".xml";
-
-      result.add(new Pair<Element, String>(element, name));
+    for (Element element : e.getChildren()) {
+      result.add(Pair.create(element, generator.generateUniqueName(FileUtil.sanitizeFileName(element.getAttributeValue(DictionaryState.NAME_ATTRIBUTE))) + ".xml"));
     }
     return result;
   }
 
+  @Override
   public void mergeStatesInto(Element target, Element[] elements) {
     for (Element e : elements) {
       target.addContent(e);
     }
   }
-}
+}
\ No newline at end of file
diff --git a/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionaryState.java b/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionaryState.java
index 717af47..4237d88 100644
--- a/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionaryState.java
+++ b/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionaryState.java
@@ -16,7 +16,6 @@
 package com.intellij.spellchecker.state;
 
 import com.intellij.openapi.components.*;
-import com.intellij.openapi.project.Project;
 import com.intellij.spellchecker.dictionary.EditableDictionary;
 import com.intellij.spellchecker.dictionary.ProjectDictionary;
 import com.intellij.util.xmlb.annotations.AbstractCollection;
@@ -36,31 +35,17 @@
              scheme = StorageScheme.DIRECTORY_BASED, stateSplitter = ProjectDictionarySplitter.class)
   }
 )
-public class ProjectDictionaryState implements PersistentStateComponent<ProjectDictionaryState>{
-
+public class ProjectDictionaryState implements PersistentStateComponent<ProjectDictionaryState> {
   @Property(surroundWithTag = false) @AbstractCollection(surroundWithTag = false, elementTypes = DictionaryState.class)
   public List<DictionaryState> dictionaryStates = new ArrayList<DictionaryState>();
 
-
   private ProjectDictionary projectDictionary;
-  private String currentUser;
-  private Project project;
 
   public ProjectDictionaryState() {
   }
 
-  public void setProject(Project project) {
-     this.project = project;
-   }
-
-   public void setCurrentUser(String currentUser) {
-     this.currentUser = currentUser;
-   }
-
-
   @Transient
   public void setProjectDictionary(ProjectDictionary projectDictionary) {
-    currentUser = projectDictionary.getActiveName();
     dictionaryStates.clear();
     Set<EditableDictionary> projectDictionaries = projectDictionary.getDictionaries();
     if (projectDictionaries != null) {
@@ -72,21 +57,22 @@
 
   @Transient
   public ProjectDictionary getProjectDictionary() {
-    if (projectDictionary==null){
+    if (projectDictionary == null) {
       projectDictionary = new ProjectDictionary();
     }
     return projectDictionary;
   }
 
+  @Override
   public ProjectDictionaryState getState() {
-    if (projectDictionary!=null){
+    if (projectDictionary != null) {
       //ensure all dictionaries within project dictionary will be stored
       setProjectDictionary(projectDictionary);
     }
     return this;
   }
-  
 
+  @Override
   public void loadState(ProjectDictionaryState state) {
     if (state != null) {
       this.dictionaryStates = state.dictionaryStates;
diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/moveUpDown/XmlMover.java b/xml/impl/src/com/intellij/codeInsight/editorActions/moveUpDown/XmlMover.java
index 98e646c..770ac7a 100644
--- a/xml/impl/src/com/intellij/codeInsight/editorActions/moveUpDown/XmlMover.java
+++ b/xml/impl/src/com/intellij/codeInsight/editorActions/moveUpDown/XmlMover.java
@@ -19,6 +19,7 @@
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.UnfairTextRange;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.PsiNamedElement;
@@ -106,7 +107,7 @@
       movedLineStart = updateMovedRegionStart(document, movedLineStart, textRange.getStartOffset(), info, down);
     }
 
-    final TextRange moveDestinationRange = new TextRange(
+    final TextRange moveDestinationRange = new UnfairTextRange(
       document.getLineStartOffset(info.toMove2.startLine),
       document.getLineEndOffset(info.toMove2.endLine - 1)
     );
diff --git a/xml/impl/src/com/intellij/ide/highlighter/HtmlFileHighlighter.java b/xml/impl/src/com/intellij/ide/highlighter/HtmlFileHighlighter.java
index daff833..151b4aa 100644
--- a/xml/impl/src/com/intellij/ide/highlighter/HtmlFileHighlighter.java
+++ b/xml/impl/src/com/intellij/ide/highlighter/HtmlFileHighlighter.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.
@@ -80,11 +80,13 @@
     keys1.put(XmlTokenType.XML_BAD_CHARACTER, HighlighterColors.BAD_CHARACTER);
   }
 
+  @Override
   @NotNull
   public Lexer getHighlightingLexer() {
     return new HtmlHighlightingLexer();
   }
 
+  @Override
   @NotNull
   public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
     return pack(XmlHighlighterColors.HTML_CODE, pack(keys1.get(tokenType), keys2.get(tokenType)));
diff --git a/xml/impl/src/com/intellij/ide/highlighter/XmlFileHighlighter.java b/xml/impl/src/com/intellij/ide/highlighter/XmlFileHighlighter.java
index 4b68ad9..6c515a1 100644
--- a/xml/impl/src/com/intellij/ide/highlighter/XmlFileHighlighter.java
+++ b/xml/impl/src/com/intellij/ide/highlighter/XmlFileHighlighter.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.
@@ -134,6 +134,7 @@
     myIsXHtml = xhtml;
   }
 
+  @Override
   @NotNull
   public Lexer getHighlightingLexer() {
     if (myIsDtd) {
@@ -145,6 +146,7 @@
     }
   }
 
+  @Override
   @NotNull
   public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
     return pack(keys1.get(tokenType), keys2.get(tokenType));
diff --git a/xml/impl/src/com/intellij/lexer/HtmlHighlightingLexer.java b/xml/impl/src/com/intellij/lexer/HtmlHighlightingLexer.java
index 5a44c3f..660e215 100644
--- a/xml/impl/src/com/intellij/lexer/HtmlHighlightingLexer.java
+++ b/xml/impl/src/com/intellij/lexer/HtmlHighlightingLexer.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.
@@ -23,6 +23,7 @@
 import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.xml.XmlTokenType;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public class HtmlHighlightingLexer extends BaseHtmlLexer {
@@ -96,7 +97,7 @@
     registerHandler(XmlTokenType.XML_COMMENT_CHARACTERS,value);
   }
 
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     super.start(buffer, startOffset, endOffset, initialState);
 
     if ((initialState & EMBEDDED_LEXER_ON)!=0) {
diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java
index f16484d..b6911cc 100644
--- a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java
+++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java
@@ -25,6 +25,7 @@
 import com.intellij.util.text.CharArrayUtil;
 import gnu.trove.TIntIntHashMap;
 import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.kohsuke.rngom.parse.compact.*;
 
@@ -130,6 +131,7 @@
     return CharArrayUtil.fromSequence(myBuffer);
   }
 
+  @NotNull
   @Override
   public CharSequence getBufferSequence() {
     return myBuffer;
@@ -173,7 +175,7 @@
   }
 
   @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     myBuffer = buffer;
 
     final Reader reader = new CharSequenceReader(buffer, startOffset, endOffset);
diff --git a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/DTDFileType.java b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/DTDFileType.java
index 276837d..3c9005d 100644
--- a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/DTDFileType.java
+++ b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/DTDFileType.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.
@@ -30,21 +30,25 @@
     super(DTDLanguage.INSTANCE);
   }
 
+  @Override
   @NotNull
   public String getName() {
     return "DTD";
   }
 
+  @Override
   @NotNull
   public String getDescription() {
     return IdeBundle.message("filetype.description.dtd");
   }
 
+  @Override
   @NotNull
   public String getDefaultExtension() {
     return "dtd";
   }
 
+  @Override
   public Icon getIcon() {
     return AllIcons.FileTypes.Dtd;
   }
diff --git a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XHtmlFileType.java b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XHtmlFileType.java
index 9d282e2..f8d96be 100644
--- a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XHtmlFileType.java
+++ b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XHtmlFileType.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.
@@ -29,21 +29,25 @@
     super(XHTMLLanguage.INSTANCE);
   }
 
+  @Override
   @NotNull
   public String getName() {
     return "XHTML";
   }
 
+  @Override
   @NotNull
   public String getDescription() {
     return IdeBundle.message("filetype.description.xhtml");
   }
 
+  @Override
   @NotNull
   public String getDefaultExtension() {
     return "xhtml";
   }
 
+  @Override
   public Icon getIcon() {
     return AllIcons.FileTypes.Xhtml;
   }
diff --git a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XmlFileType.java b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XmlFileType.java
index 7c0447d..fecf473 100644
--- a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XmlFileType.java
+++ b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XmlFileType.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.
@@ -32,21 +32,25 @@
     super(XMLLanguage.INSTANCE);
   }
 
+  @Override
   @NotNull
   public String getName() {
     return "XML";
   }
 
+  @Override
   @NotNull
   public String getDescription() {
     return IdeBundle.message("filetype.description.xml");
   }
 
+  @Override
   @NotNull
   public String getDefaultExtension() {
     return DEFAULT_EXTENSION;
   }
 
+  @Override
   public Icon getIcon() {
     return AllIcons.FileTypes.Xml;
   }
diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java b/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java
index 5cb76ec..013d94e 100644
--- a/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java
+++ b/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.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.
@@ -26,6 +26,7 @@
 import com.intellij.psi.xml.XmlTokenType;
 import com.intellij.util.text.CharArrayUtil;
 import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Collection;
@@ -239,7 +240,7 @@
     tokenHandlers.put(elementType,value);
   }
 
-  public void start(final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
+  public void start(@NotNull final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
     initState(initialState);
     super.start(buffer, startOffset, endOffset, initialState & BASE_STATE_MASK);
   }
diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java b/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java
index 98858a3..34864b6 100644
--- a/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java
+++ b/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.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.
@@ -23,6 +23,7 @@
 import com.intellij.psi.TokenType;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.xml.XmlTokenType;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * @author Maxim.Mossienko
@@ -51,7 +52,7 @@
   private int myTokenEnd;
 
   @Override
-  public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+  public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
     myTokenType = null;
     super.start(buffer, startOffset, endOffset, initialState);
   }
diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/_XmlLexer.java b/xml/xml-psi-impl/src/com/intellij/lexer/_XmlLexer.java
index d78deb8..199ce9d 100644
--- a/xml/xml-psi-impl/src/com/intellij/lexer/_XmlLexer.java
+++ b/xml/xml-psi-impl/src/com/intellij/lexer/_XmlLexer.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,6 +19,8 @@
 /* It's an automatically generated code. Do not modify it. */
 package com.intellij.lexer;
 
+import org.jetbrains.annotations.NotNull;
+
 public class _XmlLexer extends FlexAdapter {
   private int myState = __XmlLexer.YYINITIAL;
 
@@ -43,7 +45,7 @@
     packState();
   }
 
-  public void start(final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
+  public void start(@NotNull final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
     super.start(buffer, startOffset, endOffset, initialState);
     handleState(initialState);
   }
diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/parsing/xml/DtdParsing.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/parsing/xml/DtdParsing.java
index 8819dc3..b8c6b2a 100644
--- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/parsing/xml/DtdParsing.java
+++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/parsing/xml/DtdParsing.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.
@@ -34,6 +34,7 @@
 import com.intellij.psi.tree.TokenSet;
 import com.intellij.psi.xml.XmlElementType;
 import com.intellij.psi.xml.XmlEntityDecl;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * @author Mike
@@ -65,7 +66,7 @@
         new DtdLexer(false) {
           final int myInitialState = getLexerInitialState(type, contextType);
           @Override
-          public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+          public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
             super.start(buffer, startOffset, endOffset, myInitialState);
           }
         }, chars
diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java
index c986bb1..b030815 100644
--- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java
@@ -296,7 +296,7 @@
     final String schemaLocationDeclaration = getAttributeValue("schemaLocation", XmlUtil.XML_SCHEMA_INSTANCE_URI);
 
     if (noNamespaceDeclaration != null) {
-      map = initializeSchema(XmlUtil.EMPTY_URI, null, noNamespaceDeclaration, map);
+      map = initializeSchema(XmlUtil.EMPTY_URI, null, noNamespaceDeclaration, null);
     }
     if (schemaLocationDeclaration != null) {
       final StringTokenizer tokenizer = new StringTokenizer(schemaLocationDeclaration);
@@ -334,7 +334,7 @@
     return null;
   }
 
-  private Map<String, CachedValue<XmlNSDescriptor>> initializeSchema(final String namespace,
+  private Map<String, CachedValue<XmlNSDescriptor>> initializeSchema(final @NotNull String namespace,
                                                                      @Nullable final String version,
                                                                      final String fileLocation,
                                                                      Map<String, CachedValue<XmlNSDescriptor>> map) {
@@ -422,7 +422,7 @@
   }
 
   @Nullable
-  private PsiMetaOwner retrieveOwner(final XmlFile file, final String namespace) {
+  private PsiMetaOwner retrieveOwner(final XmlFile file, final @NotNull String namespace) {
     if (file == null) {
       return namespace.equals(XmlUtil.getTargetSchemaNsFromTag(this)) ? this : null;
     }