Snapshot 020d29497847701e84e383d965abf543b80758e2 from idea/133.370 of git://git.jetbrains.org/idea/community.git

020d294: platform: incompatible KTerm option stripped
589c8be: ui: correct icon for facet editor panel
00b8db5: skip invalid highlighters (EA-37197) - 8K reports! (cherry picked from commit 3688a79) [r=Peter.Gromov]
663de5b: IDEA-114952 Eclipse code style import: would be nice to remember imported file location (URL fix for Windows) (cherry picked from commit 7f1b705)
fd13ff8: IDEA-116071 (Field can be final inspection change) (cherry picked from commit e1eab58)[CR-IC-3389]
ae3b411: IDEA-116508 ("Local variable or parameter can be final" inspection use generates uncompilable code not extracting a really finalizable variable) (cherry picked from commit 49639e8)[CR-IC-3388]
e31eafc: EA-52123 (IAE: InvertBooleanHandler.invoke) (cherry picked from commit 18e2e69)
b318047: 2x more compact mapping storage for 7bit ascii paths [r=Eugene.Zhuravlev] (cherry picked from commit 2f10822)
42fa68e: IDEA-117378 Privilege escalation via JetBrains products by local attacker (cherry picked from commit 81b56c6)
87e3a49: IDEA-118063 Gradle: cosmetic fix 'Add gradle plugin' action: 'Choose plugin' popup has lots of not clickable links (cherry picked from commit ca4f7bc)
1245a78: IDEA-117792 Gradle Run/Debug Configuration: support adding Gradle specific parameters; review - http://crucible.labs.intellij.net/cru/CR-IC-3727
8558b99: 13.0.2 with EAP
997edcb: no smart icons and no parameter info in power save mode (cherry picked from commit 4bb3242)
bdd56c0: [^jeka] tolerate mysterious groovy class file corruption
a346506: IDEA-118397 Resume build not working (cherry picked from commit ea2b802) +review CR-IC
a659297: IDEA-118245 Retain the last used command line in the Execute Maven Goal dialog (cherry picked from commit 26a7d57) +review CR-IC
a604811: IDEA-118102 Maven: artifacts name not properly generated from pom in IDEA 13 (cherry picked from commit e610603) +review CR-IC
a8ffcf9: IDEA-118053 Editor "deprived of mind" when editing settings.xml (cherry picked from commit ed529d5) +review CR-IC
0e9a065: IDEA-78508 [Maven] Good Code Red with empty variables in classifiers (cherry picked from commit 0831af1) +review CR-IC
cbd34cb: IDEA-116921 Run configuration can't resolve test dependency when "Resolve workspace artifacts" ticked on. (cherry picked from commit d06f31a) +review CR-IC
75e374a: Fix for IDEA-116940 @formatter off still generating braces [CR-IC-3478] (cherry picked from commit 3340beb)
1f6f81f: avoid unconditional trace properly (cherry picked from commit 2e72fcc)
5f45643: Compilation fix
a4749db: IDEA-118292 (process idea.properties in declaration order)
679e1c4: IDEA-118111 (OpenJDK 6 check made strict)
950225b: restore classes in nav bar (IDEA-118168)
cfe1124: NPE
0a41d99: method may be static: process default methods (IDEA-118272)
6ff67d9: redundant cast: ensure that temp variable would have unique name (IDEA-118197)
9549258: distinct prover: distinguish types when type parameter has bounds (IDEA-118037)
0dcb258: show param info: highlight overload vararg method
c40975b: method references: smart completion to filter by return type
319017d: disable lambda completion after inserted qualifier
ed361ec: do not register fixes which need editor in batch mode (IDEA-116248)
30cba59: EA-52652 - NPE:  ExceptionUtil.getUnhandledExceptions
c9199b7: redundant type args: process nested calls (IDEA-117945)
fad3ead: IDEA-117989 JUnit: Run/Debug java test output "scroll to stacktrace" not working as expected
c9d58cc: IDEA-117911 Delegate methods duplicate @Override
35afc12: generate javadoc: search for modules under progress
bf0ec72: IDEA-117883 make <--tooltip end--> logic work in Inspections View; provide additional tooltip bounds
056b529: new inference: propagate outer method to constraints, initial (IDEA-117803)
cd65706: IDEA-117827 Invalid "ambiguous method call" error
8251b5d: IDEA-117780 Bad code is green: non-static class T cannot be referenced from a static context
4a1ae2f: restore suppressions (IDEA-117763)
b7003c6: pull up: ignore conflicts coming from access object when it is also moved (IDEA-117671)
282c332: remember different working dirs for rerun (IDEA-116110)
8224a17: scope to check for cheap search (IDEA-117665)
b2affde: refactoring high level listeners (IDEA-115905)
a2ae64e: NPE
f75829b: extend local scope a set of containing files as visitors expect file level (IDEA-117649)
c72c42f: tests notification: separate not started notification from ignored when no 'not started' tests were detected (IDEA-116825)
5a0aebc: suspicious names: highlight only variable name (IDEA-116475)
62ba24a: disable introduce variable from part of literal expression which is not a string
740bbf2: testng: ignore default annotations attributes (IDEA-117575)
52c384c: add explicit arguments: eliminate wildcards (IDEA-106741)
31e57cc: check lambda return values during constant&conditions (IDEA-117420)
c8ff7ea: javafx: allow to configure custom manifest attributes (IDEA-115252)
99b89cc: IDEA-117314 Can not compile Java project with Eclipse dependencies storage format
528f2d5: introduce variable inside lambda: do not step out of lambda block
48cb2be: IDEA-117252 Extract variable bug
8724806: IDEA-113339 "replace with method reference" ignores side effect of expression: ignore any new expressions in qualifiers
6f6d61b: lambda -> method ref: do not convert if resulted ref would be ambiguous (IDEA-116964)
d9a89a1: EA-52426 - NPE: JavaDocInfoGenerator.generateSuperMethodsSection
df01945: IDEA-118264 Rearrange Entries stopped working in Intellij 13
5e7d560: files compiled on first round may require additional recompilation on the next round (second part for IDEA-116914)  constant search on the IDE side rewritten: only direct dependencies are returned for each search round; all transitive dependencies will be additionally handled by make
4792865: handling cases when added class hides imported class with the same short name (IDEA-116914 Incremental compilation of Java project fails)
e99d464: correct check
ea90776: safely skipping some invalid usages
3a16b61: proper synchronization
0c9c72e: IDEA-117249 Optimize make's constant search algorithm, so that read action is not held for long time
f19231c: do not search usages of removed constant fields in injected PSI
d6ef061: Merge branch '133' of git.labs.intellij.net:idea/community into 133
fa65f8e: IDEA-35996 Ant integration: provide more informative message in case ant file execution is stopped due to unknown command line argument
9519530: IDEA-117904 Ant integration: running: with an error (javac) the result is reported as "successful": perform all status calculations after all messages are processed
5a9f9a8: IDEA-111702 Java Rearranger illegal forward reference on fields rearrangement [CR-IC-3034] (cherry picked from commit 7f01bcd)
a2dd3a6: IDEA-115786 Allow the number of Maven threads to be specified (cherry picked from commit 9d05ff2) +review CR-IC
abfd9a5: IDEA-114418 (Grails SDK of an dependency)  -Dgrails.disable.structure.update=true should work for JDK synchronization. (cherry picked from commit 009ca28) +review CR-IU
491ceb6: IDEA-96723 Java Rearranger deletes blank lines in field declarations (cherry picked from commit 15869e7)
85fe89f: IDEA-118159 "Search Everywhere" inconsistent api on ItemPresentation (cherry picked from commit 9729ea9) [r=Konstantin.Bulenkov]
bcf528b: revert platform fix for PY-6095, apply Python specifix fix instead (cherry picked from commit 0dfae8b)
fec8fe7: IDEA-117864
930439c: cosmetics
6c1df41: IDEA-108838 Wrong code when introducing variable in injection (cherry picked from commit f119c2e)
2a40aeb: Merge remote-tracking branch 'origin/133' into 133
d92cdcc: IDEA-117391 (annotation highlighting fixed)
05a20ae: IDEA-117772 (start application loading in EDT)
ef18d70: DevKit: refine DOM stubs + test (cherry picked from commit 84d8e52)
15d7962: IDEA-117583 DevKit: highlight <idea-version> "min"|"max" as deprecated (cherry picked from commit ce277a1)
be71e9a: cleanup, update "since-build" (cherry picked from commit f56ca26)
e9aa79b: IDEA-117573 DevKit: highlight <vendor> "logo" as obsolete (cherry picked from commit d552ee4)
d5d86be: EA-52563 - assert: ChooseModulesDialog$MyTableCellRenderer$.customizeCellRenderer (cherry picked from commit d24d279)
009d144: CodeInsightTestUtil#doIntentionTest(): remove Throwable declaration (cherry picked from commit d7e8e2a)
e543b44: lazy class loading for PtyProcess (r=Eugene.Zhuravlev), 2 (cherry picked from commit 85700e4)
edd9c56: save / load per project key hash codes (cherry picked from commit c847d67) [r=Eugene.Zhuravlev]
eff72da: avoid garbage creation in JDK7 due to calling StringBuilder.toString() that copies buffer now (cherry picked from commit 03f7413) [r=Peter.Gromov]
40c73d4: no need to create strings of PsiFile's Text when we can avoid it or use charsequence (cherry picked from commit d8ec59b) [r=Peter.Gromov]
10c479c: introduced cvs.roots.refresh.uses.vfs property (true by default) and uses its value to refresh cvs roots after update using vfs to avoid performance problems (IDEA-112132) (cherry picked from commit 1958e9a) [r=Peter.Gromov]
8cac2e5: - detect proper encoding for html5's <meta charset="charsetname"> - [performance fix] avoid (light) parsing of html content if there is no charset\s*= pattern inside the string (cherry picked from commit 2f4be38) [r=Alexey.Kudryavtsev]
cee6644: IDEA-78206 Constructing 'mailto' link -> cannot resolve file 'mailto' (cherry picked from commit 3166c04) [r=Konstantin.Ulitin]
98571ff: Cyclic Expand Word leaves word highlighted (IDEA-115727) (cherry picked from commit 29bb231) [r=Peter.Gromov]
31fe1a1: refixing IDEA-57940 : the variants from other editors are suggested AFTER finishing variants from current file (cherry picked from commit e76fe51) [r=Peter.Gromov]
e3975be: avoid allocating sun.nio.cs.US_ASCII$Decoder when converting byte[] to String
1053bdb: don't create TIntArrayList(DEPTH_LIMIT) before we have clear indication that we might have a loop (parentId >= id) (cherry picked from commit 5478fdf) [r=Alexey.Kudryavtsev]
364e80e: avoid unconditional trace (cherry picked from commit 2e72fcc) [r=Alexey.Kudryavtsev]
70980d8: don't call toString() without need to avoid garbage (cherry picked from commit 75c030c) [r=Alexey.Kudryavtsev]
466dc64: Apply again "update stubs per filetype  reverted for 133 branch"
3f66295: Apply again "IDEA-113684 Soft wraps insert additional spaces"
028b3ae: Darcula: combobox as cell renderer/editor fixes
e96975a: fix default size of SourceMapInspector window (cherry picked from commit a64047e)
edfb4da: if IDEA sees text/plain and extension .java, perhaps it should infer that it's actually Java, because not everyone will set up their HTTP servers with language-specific mime types? (Particularly when following a URL to a source file in a sourcemap.) +review (cherry picked from commit 5ea95e3)
6162222: fix ClassCastException: com.intellij.openapi.fileEditor.FileEditorState$1 cannot be cast to com.intellij.openapi.fileEditor.impl.text.TextEditorState (cherry picked from commit 44f0697)
6c8dbc0: update progress on test done (finished, failed, or ignored), not on test started (cherry picked from commit dbcb907)
a4038dd: REGISTERED state added (cherry picked from commit 08677f9)
bf0da3a: fix PersistenceRenameTest blinking: inconsistent @NameValue placement and random methods order in DomGenericInfo
1f08879: PsiBuilder/GPUB: zero-length token parsing support (lexer-based macros)
352056d: EA-52484 - IOOBE: ConsoleHistoryModel.getHistoryPrev
21ab06f: EA-52027 - assert: TextRange.<init>
b452663: IDEA-116383 cannot reconnect Some RuntimeException contains not serializable class 'org.apache.maven.model.building.DefaultModelProblem'. So IDEA throw java.rmi.UnmarshalException  caused by java.io.NotSerializableException. (cherry picked from commit 9f7fb6c) +review CR-IC
a4e9447: Revert "IDEA-113684 Soft wraps insert additional spaces"
231adec: Revert "update stubs per filetype  reverted for 133 branch"
d62a526: use method instead of manual hack
cae16e2: better combobox rendering on aqua: no focus ring around combo button, fixed 1px size difference
7d9b58c: fix TextFieldWithHistory rendering on mac
95d40df: determine tag end by doctype #WEB-2229 fixed
556c3bc: lazy class loading for PtyProcess (r=Eugene.Zhuravlev) (cherry picked from commit 96c8bca)
749d89f: RUBY-14672: better name for gracefulProcessTermination() (reviewed by Dennis Ushakov and Sergey Simonchik ) (cherry picked from commit 908538b)
dd5dd11: RUBY-14672: we need to send SIGINT to Ruby debugger twice (reviewed by Dennis Ushakov and Sergey Simonchik ) (cherry picked from commit 4546732)
3c01a72: Merge remote-tracking branch 'origin/133' into 133
6378e77: [git] IDEA-118265 Fix showing Git Branches menu
b9446e2: close process's input stream after process termination (cherry picked from commit e962648) CR-WS-272
c8fbe68: support Windows soft kills using runnerw.exe in KillableColoredProcessHandler (cherry picked from commit 77e0f1a) CR-IC-3459
988c990: fix showValuePopup — incorrect scrolling (cherry picked from commit 594785c)
1f67166: IDEA-105450 Attribute id in OSGI reference element not allowed: XmlHighlightingTest.testXhtmlSchemaHighlighting fixed (cherry picked from commit 69daed6)
eb3a323: IDEA-105450 Attribute id in OSGI reference element not allowed: get schemaLocation from import tag (cherry picked from commit ec44bbd)
8bb9587: IDEA-105450 Attribute id in OSGI reference element not allowed: namespaces from standard resources should be considered relevant (cherry picked from commit d30684d)
a129c6c: IDEA-84166 Support "CTRL+H" on class in .xml file (cherry picked from commit da3cbf3)
7162d4b: update stubs per filetype  reverted for 133 branch
377bf70: IDEA-113684 Soft wraps insert additional spaces (cherry picked from commit 0e1c820)
643cd5d: use direct call to storage.resize() so that IOException is not masked with RuntimeException (IDEA-118107)
2e7c85f: Plugin for IDEA 133.286 3.0.1 EAP CE
f75f35e: Merge branch '133' of git.labs.intellij.net:idea/community into 133
9186d35: PyCharm 3.1
58936a1: add create method
ecf556d: do nothing if state didn't change
dcfbfb5: IDEA-115859 Presentation mode is broken
1d6443d: Javascript tests fixed, IDEA-113977 Formatter: caret is moved on next line if closing brace has wrong indent  [CR-IC-3034] (cherry picked from commit dd55e70)
b75041b: Merge branch '133' of git.labs.intellij.net:idea/community into 133
2a74e83: Pty lib updated - run in console mode.
390900e: Guava and Pty4J libraries dependencies.
10a39d8: Contains in branches feature implemented for mercurial log.
37a14b0: Added logging.
9355a2b: improved user experience with run configuration producers
78e57f9: Better multiline code handling in console.
fc7702f: Correct test data path.
6bba62d: Detect SQL fragments only in the beginning of string literals
ba5ff19: Fixed LiteralTextEscaper.getOffsetInHost() for partial ranges inside host that contain escapes
df0c579: Added caching of decoded fragments of string literals
f93a871: Fixed detecting file references in Python strings without delimiters
01bf006: Removed unused PyStringLiteralExpression.iterateCharacterRanges()
147ed7a: Switched to new string value iteration in Python file references inside string literals
f8e775c: Use Pair instead of a custom class
0106a10: Switched to new string value iteration in Python spellchecker
69ac8c5: Added PyStringLiteralExpression.getDecodedFragments()
d703ca5: reverted module type from plugin_module to java_module for localization and rest
2cb9a61: fixed tests since we don't propose to make static decorated method
d6ed1d7: fixed PY-10998 Wrong highlight in rst (restructured texts) for headlines
5511e2f: Fix NPE.
9f0c134: Don't break compatibility (PY-11499).
f80fc2e: fixed PY-11500 False positive in method may be static inspection for decorated methods
0bfaaf2: fixed PY-2984 Surround with try/except reformats entire file
0ed12da: args can be immutable (PY-11465).
1bb8318: fixed PY-11435 Can't run script by context menu action if it has method named test
0336898: Fixed detection of the largest string literal for right parts of '%' operator
cb5714e: fixed PY-11452 tcunittest errors with single-character failure message
2503a60: fixed test data
16aa28c: fixed PY-11476 No error given for mismatched accolade and squarebracket
403b937: Allow to run processes with PTY.
4740054: Added comment-based language injector for Python
f56fecc: fixed tests
45a824c: Fixed un-inject language availability for temporary Python injections
ea707eb: Method renamed.
4b349d3: Extracted PyInjectionBase.registerInjection
909a31d: Don't inject any language into percent-based Python formatting even without formatting operator (PY-10771)
b928248: Fixed SQL select IntelliLang pattern (PY-10926)
55239bf: If command executed but is incomplete and more lines are needed prompt shouldn't be changed to ordinary one in this case.
a061c7e: Fix modified console options modified after creation.
52b6eb3: Jython doesn't support 'exec' symbol in interactive console.
1213be2: PyConsole: correctly indent after execution of incomplete multi-line string.
38b4e20: Fixed execution of incomplete multiline code fragments.
5306cfb: First evaluate more then add to queue.
4f18cfe: Simplified.
9688ef7: Attribute renamed.
10a0e30: NotNull annotation.
5e5c546: Fixed IPython and debug console broken by console execution model changes.
e53607e: Fixed write lock assertion.
78ea78d: Execute multi-line code fragments by runsrouce with 'exec' option instead of one line by one (PY-10769).
0dcf990: Cleanup.
9f4dca96: Broken indentetion in console fixed (PY-10776).
3c4550e: Fixed saving of env in console settings. Mappings format saving changed.
699255f: Fixed working directory setting in console settings.
9b98ce9: Fixed saving path mappings in console settings (PY-9855).
14fbafd: Don't ask to reconnect remote interpreter in case of fail as it never helps but causes problems (PY-10590).
f8a096a: Support for temporary and configuration-based IntelliLang injections in Python (PY-10983, PY-10721)
5def9d3: fixed http://youtrack.jetbrains.com/issue/PY-2953
e6a24df: fixed PY-11394 "no tests were found" with django 1.6 DiscoverRunner
1fb4a8a: used consistent name prefix
923f8c0: fixed PY-11415 GAE: Lazy Handler reference is not updated when moving to other module
0a3c840: fixed PY-9967 App Engine: do not resolve to installed to interpreter library
ea42fbf: [log] Fix showing dot in the root table header
decac91: [log] Fix background of the details panel content (cherry picked from commit 2ad2cba)
224a2be: [log] fix name of variable
f79c2e4: [log] IDEA-115675 IDEA-116040 Fix table columns sizing
668c021: [log] IDEA-117500 Don't repaint branches panel on every updateUI
ed4a8ca: [log] IDEA-117500 Optimize grouping of branch references
a98e6c8: [git] Don't modify the unmodifiable collection (cherry picked from commit 007dc0d)
9321b17: [git] IDEA-117500 Don't copy, just wrap in unmodifiable
f3cd826: [git] remove unused method
d7db0fc: [log] Separate loading indicator for "Contained in branches"
ab8606f: [log] Fix "Containing branches" for filtered list & for Mercurial
c190668: [git] Move & rename method to get branches to GitBranchUtil for reuse (cherry picked from commit f78700e)
0ae4458: [git] Simplify method to get branches: use branch names.
423dbc6: IDEA-117936 IDEA13 fails to stop at breakpoint inside advised method
4587a46: IDEA-117613 Gradle: tool window is missing after the update, safe check for newly created project added
18e44f3: IDEA-117613 Gradle: tool window is missing after the update review: http://crucible.labs.intellij.net/cru/CR-IC-3629
b9b4c6c: fixed IDEA-111701 Emacs: pressing Ctrl+k several times should add lines to muti-line buffer (regression for IDEA-18764, broken in IDEA-111275)
a843386: we must not use getKnownFileTypeOrAssociate on navigate (cherry picked from commit 476b30d)
cf363b6: fix actionSystem.fixLostTyping.description (cherry picked from commit caf3ece) CR-IC-3481
4dfe767: IDEA-117548 Bad function parameters highlight (cherry picked from commit d4507c9)
b83ac23: fix assertion (cherry picked from commit 5743c3c)
f7e5eeb: WEB-10231 first navigation to http file doesn't open desired location (cherry picked from commit 384f8f9)
fe39b87: wait smart mode checks for isReadAccessAllowed too, so, we must not call it (cherry picked from commit a5dd92c)
f4c9d17: optimization — check isEmpty (cherry picked from commit 44727c2)
cd8fb58: VmFileEditor — prepare to fix postponed navigation problem in our HTTP file editor. VmFileEditor supports postponed navigation. (cherry picked from commit db4ca37)
c669320: "Run in background" option from now on means "show build messages immediately" rather than "execute with modal dialog"
d83aedd: don't generate large substrings when creating CompletionResultSet [r=Peter.Gromov]
87ad24b: 13.0.1
14361cd: avoid easy garbage java.util.ArrayList$Itr: 1,720,417,512 (1%) bytes in 71,684,063 (2%) objects (avg size 24 bytes) 	java.util.ArrayList.iterator: 1,720,392,864 (99%) bytes in 71,683,036 (99%) objects 		com.intellij.openapi.projectRoots.impl.ProjectJdkTableImpl.findJdk: 938,831,640 (54%) bytes in 39,117,985 (54%) objects 		com.intellij.openapi.editor.impl.ComplementaryFontsRegistry.getFontAbleToDisplay: 218,420,520 (12%) bytes in 9,100,855 (12%) objects (cherry picked from commit 9207b87) [r=Peter.Gromov]
41efe97: look for xml properties in files with xml file type only (cherry picked from commit b6ae811) [r=Dmitry.Avdeev]
ea2590e: WEB-10191 Weird field in the Configure NodeJS Modules Sources (cherry picked from commit 0f61ced) http://crucible.labs.intellij.net/cru/CR-IC-3556
a2b39c2: Gradle: fix dependencies scope merge IDEA-117556 Gradle custom provided configuration added with compile scope IDEA-117601 Gradle integration ignores scopes.TEST.plus in build.gradle (cherry picked from commit f80d692) Safe hotfix, the code works in a separate process (in gradle daemon, not in IDE process)
ce53010: External system: build files modification triggers threads continuously if "auto-import" feature enabled review- http://crucible.labs.intellij.net/cru/CR-IC-3533
4d9ae0c: Gradle: fix dependency scope merge to respect artifact classifier option related bug - IDEA-117627 Transitive dependencies missing from imported Gradle project Safe hotfix, the code works in a separate process (in gradle daemon, mot in IDE process)
d9c3f83: IDEA-117669 gradle multi-module project executing subtask uses wrong gradle version review - http://crucible.labs.intellij.net/cru/CR-IC-3564
87819e2: Gradle: IDEA-116880 Intellij 13 doesn't auto-save files before Gradle task (cherry picked from commit e5c53c6)
5b87b39: Gradle: fix MultipleRepositoryUrlsInspection to operate on gradle-relevant files only (cherry picked from commit 95fbdc9)
1c2f07c: IDEA-117432 Do not fail while resolving client factory for upgrade if "other factory" is configured incorrectly (cherry picked from commit 0694e5d)
d11b435: IDEA-117432 Do not fail while resolving client factory for checkout if "other factory" is configured incorrectly (cherry picked from commit 6242d70)
db15422: Branch information checks moved to appropriated separated methods. (cherry picked from commit 9492982)
6f85df3: Method name simplified (cherry picked from commit 0924c2b)
16e2328: IDEA-115906 Throwable ; IDEA-117401 IAE fixed
eedd7fe: HEAD branch filter in new log fixed (cherry picked from commit 7793e6f)
a787eb2: VcsRootDetector and NotifierError tests fixed (there were .git in T ot tmp dir above, so appropriate checker found its root,then error)
ddc643d: remove outdated and buggy (in case of library code) property java.debugger.xBreakpoint.onlyIfHasFacets (cherry picked from commit 5b7f60f)
ab9cce8: CR-IC-3511 CFR-63806 (cherry picked from commit e800ade)
d3e739f: introduce newUrl (cherry picked from commit bb94f47)
5009fbf: VisualizeScriptSourcemap action (cherry picked from commit 2694a1f)
2051c1e: cleanup (cherry picked from commit 30d4cdf)
586ef62: Merge remote-tracking branch 'origin/133' into 133
3a93fee: rollback IDEA-117378. It will be available in 13.0.2
d72ed2a: IDEA-117227 load imports from stubs [^Peter]
5568b0d: Groovy: injection in command expression [^Peter]
b0ef47e: IDEA-117389 Groovy: Introduce constant from string part [^Peter]
7076f89: IDEA-117227 stubs for Groovy imports [^Peter]
605a0a9: IDEA-117390 'IntelliJIdeaRulezzz' in Code Completion [^peter]
ac4417e: fix testdata
8607b4d: IDEA-116547 optimization in reassigned vars check [^peter]
1e7c610: WEB-10019 Don't show emmet preview after simply dot (cherry picked from commit 127560f)
4b36aad: WEB-9986 CSS: fuzzy search shows turned off abbreviations (cherry picked from commit 56e0385)
4b4958e: WEB-10017 New "Surround with emmet" popup breaks usability (cherry picked from commit 8bdc013)
0bd5b71: automatically starts rebuild if java builder caches are corrupted (IDEA-117024) [rev by Jeka]
f536c49: Merge remote-tracking branch 'origin/133' into 133
81b56c6: IDEA-117378 Privilege escalation via JetBrains products by local attacker
633cd5e: a temporary workaround for HiDPI on Windows/Linux
b7a8a38: Local VCS tests quick fix (ignore temp. FS)
eecd3d1: make history almost unlimited
72de836: no delay after tab or escape
96b5a46: re-create components on every call (laf change fix)
9aa347b: Extracted Python path walking and fixed broken symlink check (PY-10534)
66b3393: differentiate between Sun and Oracle VMs
6b27a51: fixed silent installation mode.
0e4a0fc: IDEA-117378 Privilege escalation via JetBrains products by local attacker IDEA-113862 Confusing Run as dialog
a7300cd: [^maxim] FrequentEventDetector: log outside of synchronized (IDEA-117426)
9d0b588: [^nik] GroovyHotSwapper: use FileTypeIndex
3228a63: [^nik] cache GroovyHotSwapper.containsGroovyClasses (IDEA-116851)
57ff2da: IDEA-103199 Undo: UTF problem (after-review improvements) (cherry picked from commit 0a0aecf)
75ed596: IDEA-103199 Undo: UTF problem (cherry picked from commit ea49ecf)
0a705a8: correct definition of "oracle vm" for java 6
7464e2f: can not clear JarFileHandler caches (e.g. on JDK 7) -> no logging (cherry picked from commit 5012a9b) [r=Alexey.Kudryavtsev]
299f014: IDEA-117498 Caret locks up after using ctrl+tab to switch editors [r=Peter.Gromov] (cherry picked from commit 38f2f05)
99b71dc: IDEA-117494 133.193: Importing grails modules not labeled as grails enabled +review CR-IU (cherry picked from commit 588cd01) reviewer: Peter Gromov
48ce506: do not auto-switch current suspend context if a new thread with suspenPolicy=thread hits a breakpoint (IDEA-116160)
64dc9f5: CR-IC-3489 restore old API
f1dcd4c: Merge remote-tracking branch 'origin/133' into 133
4b41e83: [log] IDEA-117365 Expect "empty" git tag; protect against errors
725c360: [log] Register disposable right away, not after initialization (cherry picked from commit 1e48680)
265d0df: EA-51913 - assert: DomNamespaceKeyIndex.hasStubElementsWithNamespaceKey (cherry picked from commit 6763822) CR-IC-3472
42ecb1a: CR-IC-3471 (cherry picked from commit b213f10)
89ee113: finalize consts (cherry picked from commit 73b245e)
d033d07: gwt, ability to debug — one idea module to many gwt modules (cherry picked from commit 8086f92)
056f905: NullFileEditorState +review (cherry picked from commit 561c8d1)
ca7af60: overrides (cherry picked from commit aaa236a)
4f2af9c: CR-IU-366 (cherry picked from commit 40ae21d)
c8c0d46: Problem — we use short gwt module name (Hello) instead of output name (hello, rename-to specified in Hello.gwt.xml). 1) if rename-to specified, url will be http://localhost:9876/sourcemaps/{rename-to} rename-to=“hello” => http://localhost:9876/sourcemaps/hello 2) if rename-to is not specified, url will be http://localhost:9876/sourcemaps/{qualified name} com.google.gwt.sample.hello.Hello => http://localhost:9876/sourcemaps/com.google.gwt.sample.hello.Hello
40f41b5: IDEA-116260 ISE: RPC handler object "AddOnlineUser" not found at com.intellij.ide.XmlRpcServerImpl.process (cherry picked from commit 5aa9b8e)
3265387: enable all lafs by passing a special registry key
bf2b0c6: Rename "Java" -> "JVMOptions" so MacOS doesn't require java 1.6 download from Apple.
c825894: [log] Make fields volatile
3cc0a09: [git] IDEA-116690 Fix "Select in Git Log" from File History
8b85de3: fixing IDEA-117328 java.lang.NoSuchMethodError: com.sun.tools.javac.util.Paths.clearPathExistanceCache()
7e1850e: Merge remote-tracking branch 'origin/133' into 133
f2aed4c: IDEA-117347 Search Everywhere popup is too wide
3675b82: merging ConcurrentMapFactory and ContainerUtil
98ef79b: fix Url equality (scheme) (cherry picked from commit e668634)
290e4a4: fix NPE — url could be in any form, so, parsed can be null (cherry picked from commit ec22c2e)
f90eaba: allow V8 map on IBM JDK 1.7
845ffae: do not disable "ext.dirs" location, because IBM jdk stores some of its essential jars there
5278615: EA-52516 - IAE: HighlightUsagesHandlerBase.addOccurrence
cae4139: EA-52505 - NPE: MethodCandidateInfo.getPertinentApplicabilityLevel
9b6b81e: default concurrency level upper limit
91cefef: encapsulation of factory's implementation details
1081168: IDEA-117298 Darcula&IntelliJ on Windows: Inspection description is too small in Settings
7799dc3: IDEA-117095 Goto File: checkbox 'include non-project files' is remembered between invocations [r=Anna.Kozlova] (cherry picked from commit 7cf6caa)
8eecc0f: all code in "util" module to create CHM implementation via dedicated factory (see IDEA-116404 Java code compilation does not work with IBM JDK)
81ae633: [Filechooser sheets] IDEA-102449 Mac OS + JDK 1.7: dialog sheets go to background if focus is moved from IDEA and then back
ea058b0: fix NPEs
8fbca43: Remove broken dependency on 'markdownj' from tasks-core module
5c1098b: IDEA-117258 IntelliJ theme: selected tabs in Debugger and in Run <application server> views get black color
5e02eb3: IDEA-116558 Update state transition requests for JIRA REST API 2
c2f531a: "read access" assertion and NPE fixes
ea4f96b: fix "read access" assertion
787438f: IDEA-117265 java.lang.ClassCastException: com.intellij.psi.impl.source.tree.java.PsiParenthesizedExpressionImpl cannot be cast to com.intellij.psi.PsiCallExpression
99ae1f5: NPE on invalid expressions
ffc7fa5: IDEA-115953 Editor: Line Spacing < 1.0 no longer works (reviewed by Roman Shevchenko)
886b675: External system: add support for different naming of external entities within IDEA models. E.g. external lib name: 'somelib' -> IDEA lib name: 'Gradle: somelib'. external module name: 'some/module' -> IDEA module name: 'some_module'. (cherry picked from commit bb941b0)
0634d95: enable abbreviations (cherry picked from commit 0ecc836)
1dc77a9: more searchable options
31750db: fix history and symbols 'More' action
bc4db67: Merge remote-tracking branch 'origin/133' into 133
84f584a4: add new actions
5a49390: change action place to Main Menu
4a50f96: don't use smart search for files (don't use space as a separator)
93dd505: ready to nulls (EA-52470 - IAE: TypeCompatibilityConstraint.<init>)
174531a: EA-52436 - IAE: PsiElementFactoryImpl.createType
e58f16d: IDEA-115412 Diff window is minimized  after the appearance (cherry picked from commit b2307d0)
8146462: IDEA-117059 (error reporting in updater fixed)
be1c105: NPE in mouse handler
a460658: IDEA-111388 Built-in server not "available external" — it is unclear that port number must be also changed (cherry picked from commit 6ccdae5)
dfdaaae: continue WEB-9968 Dart: ClassCastException when debugging web application in Dartium (cherry picked from commit c19e163)
ee28c75: newHttpUrl — authority must be NotNull (cherry picked from commit a708a6e)
01efd39: NetUtils.tryToFindAvailableSocketPort (cherry picked from commit fa39c70)
ca466c8: introduce Urls.newUri, prepare to fix WEB-9968 Dart: ClassCastException when debugging web application in Dartium (cherry picked from commit 4ecac7f)
e6b739a: IDEA-117059 (same temp. directory for updater)
2679834: introduced idea.register.bundled.fonts registry to be able to switch off bundled fonts registration in order to avoid garbled text in editor (IDEA-93404) [r=Konstantin.Bulenkov] (cherry picked from commit e2cdb6d)
16eb783: fix null project
05de913: report missing optimizedFileManager only once
1b747fe: correct place for optimizedFileManager.jar
4713bfc: Merge branch '133' of git.labs.intellij.net:idea/community into 133
c2c0281: Jediterm updated.
26cf0f4: Mouse selection should always work in Terminal (IDEA-117210).
1f68d01: reconfigure navbar toolbar actions
1ae092c: show separators in navbar toolbar
afcfe95: Setup composite as it is done in EditorImpl.paintComponent.
66f161d: Behave the same as EditorImpl.
013c138: Use Source Code Pro as we don't have problems with unprintable pseudo-graphics as we iterate fonts to find suitable one for unprintable characters.
9796737: special icon for generated test root [rev by Peter]
2398eb9: make adapt_builder_() overridable (initState -> public)
2ef1c62: [git] Quick-fix for IDEA-115581: don't fail, just skip such hashes
1578562: [vcs] IDEA-109608 Apply patch: Fix path detection for new files + test
080813c: update Source Code Pro to version 17
f9c2953: IDEA-117211 empty elements in Search Everywhere
32ebdf3: error reporting in 'Project Structure' dialog: merge UI updates (IDEA-116808, IDEA-110799) [rev by Maxim M.]
2bab20f: added quick-fix to delete all unused libraries (IDEA-99885) [rev by Maxim M.]
f069657: disable GroovyShell because it doesn't work on win {^Peter]
637a5ba: Merge branch '133' of git.labs.intellij.net:idea/community into 133
dd8e18a: moved to core-impl
47f94f0: IDEA-104734 Dracula: Cannot see well active tab in Modules Settings
e2c1637: removed LOG.error for null syntax highlighter (cherry picked from commit 3e4c22c) [r=Peter.Gromov]
d4240b2: check that index for which indexUnsavedDocument is performed can be applied to given file type (EA-47740) [r=Eugene.Zhuravlev] (cherry picked from commit 0057f81)
acede1f: Merge branch '133' of git.labs.intellij.net:idea/community into 133
5ffb206: PsiSearchHelper changes cherry-picked (r:Peter)
1669188: avoid blocking runReadAction in debug logging
ba70dd4: Minor typo fix (IDEA-116432 Incorrect Spelling of Eclipse) (cherry picked from commit 3c553d6)
aadedc9: IDEA-117192 NavBar popup shows in wrong place when navigating to the directory from popup
c3b6615: Merge remote-tracking branch 'origin/133' into 133
a915da31: Merge remote-tracking branch 'origin/133' into 133
9a90c16: IDEA-116866 (path overriding for plugins/log dirs fixed once again)
bc3d847: Merge remote-tracking branch 'origin/133' into 133
6081b4f: removed signing for CE launchers.
21cd0c7: tuned UI for got it button
f986c7c: method refs: do not choose more specific method between methods with different number of params
aa7db43: IDEA-116756 Gradle multi-module project with deep-nested modules - idea places iml file in the wrong directory (cherry picked from commit 8e2ad06)
3bd2a55: plugin advertiser: ensure that older plugins won't be ever suggested
f739564: plugins advertise: download plugin if it was not explicitly disabled (IDEA-117003)
df398a9: plugins advertiser: provide loading plugin version for renderer
751d401: CCE (IDEA-117119)
03b253b: lambda: do not distinguish between ellipsis and arrays for formal lambda params checks (IDEA-117124)
ca191c9: index property optimization [^Peter]
4f7ba3a: class searching optimization [^Peter]
4e7ff49: IDEA-116628 No nulls in type parameters [^Peter]
a30f59b: typo [^Peter]
580cb5e: Merge branch '133' of git.labs.intellij.net:idea/community into 133
9c2489a: Take default shell from env variable.
9b2b7f3: File chooser for shell path (PY-11334).
9758753: Take shell path setting before every process creation.
3dbe4eb: use the same background color
8b8c0df: set lower limit of 1 for max_worker_threads_count (for low-profile cpu)
2a67fed: test for unzipping malformed zip archive (cherry picked from commit cd35a94) CR-WS-267
2c74d46: target error message for a newly created project (cherry picked from commit 8e10c3a) CR-WS-267
41311ea: use ZipFile, because it throws exception for a malformed zip archive (cherry picked from commit 02da50f) CR-WS-267
323523c: make IntelliJ laf by default on Linux
9d74b04: update artwork for version 13
d7ce47d: add history
42733a8: utility class holding two colors for gradient painting
537dd04: better colors? fix balloon and popup borders
787ec72: added signing for community launchers in zip distr.
f577493: use backported V8 CHM only for Oracle or Apple JDK (IDEA-116404 Java code compilation does not work with IBM JDK)
ae19efc: isEap = false, no error reporting
7e1f100: ~update mockJDK-1.7 used classes to be at least from jdk 1.5
c812622: do not create raw outer types during diamond inference
d0bc4ad: Merge branch '133' of git.labs.intellij.net:idea/community into 133
b6fe06f: FinderRecursivePanel: do not perform getListItems() in EDT on update (cherry picked from commit a128fa5) CR-IC-3413
e189085: IDEA-116866 (path overriding for plugins/log dirs fixed)
c50b1f1: Cleanup (punctuation)
cf75962: External System: support for multiple tasks execution added (cherry picked from commit a6f9141)
60418e9: IDEA-100294 Cannot edit a file - text jumps all over the screen (cherry picked from commit 36bacc0) [cdr]
3da28ad: Merge remote-tracking branch 'origin/133' into 133
86b3924: mock 1.8 jdk
ae8c2b0: switching to java.util.ConcurrentHashMap in jps code; eliminate unneeded map queries
f3d2761: EA-52322 (diagnostic)
f0d71c1: copyright: fix for 2 open projects
e797eb4: javadoc: keep whitespaces in {@code} tags (IDEA-109997) (cherry picked from commit d08af6dfed35217f3bb03093e8c549ec3065d258)
aa52879: IDEA-117082 Anonymous class assigned to final field (cherry picked from commit 02cabc4e849835259d9d837f86493c5e4ff7269c)
c040d2f: junit: do not reuse directory configuration from another test root (IDEA-116871) (cherry picked from commit 354fece7efab569fa05b135ab912bee758a6d3f7)
99043c6: junit: do not create directory configuration when selection is not under test root, e.g. module content root (IDEA-116871) (cherry picked from commit effc865ab3bff89d4651054569ef7ac4f86d7b33)
f8ff71b: product name -> full product name (IDEA-117070) (cherry picked from commit 2b4dc107514b4bd13ec4dced1144c81de79a0bb7)
d60166d: plugins advertiser: ensure that all installed plugins would be enabled - check also unknown plugins (IDEA-117068) (cherry picked from commit 99ffd837ba1ec2523ae8c4faa2060c84b5941986)
b3ed3c2: plugins advertiser: do not suggest to update to ultimate on implicitly disabled plugins (IDEA-117040) (cherry picked from commit e5452974f1a45693dd8ddb967525d37cd54f3ba4)
61ebb02: IDEA-116991 "IDE is up to date" message (cherry picked from commit 094ac76636050b6f0796c9802342cb3d431eeab0)
a4dc3a5: lambda: process lambda as parameter for anonymous class (IDEA-116987) (cherry picked from commit bf64625fb2e79f29f924d47fb68ec55d7c46d954)
7be1ec1: IDEA-117071 (language level in decompiled .class files)
5e5d914: relative path - special url, encoding is not required (cherry picked from commit 58704c7)
7f786c5: cleanup (cherry picked from commit 3868464)
208311d: cleanup (cherry picked from commit d58146c)
53f1175: CR-IC-3246 (cherry picked from commit 5d6a0c8)
a186992: CR-IC-3246 (cherry picked from commit 51864f4)
04cd96d: open in browser — choose url, show full url, not only path (decoded form with parameters) (cherry picked from commit b3fff55)
bb59091: WeightBasedComparator — string natural compare (cherry picked from commit 86971b9)
52c78b1: overrides (cherry picked from commit 716766a)
5b53293: Urls.newFromIdea returns not-null (cherry picked from commit f47f98a)
fde95ae: move Url to platform - avoid raw string (cherry picked from commit d4e4a40)
7dabf92: UriUtil.trimLastSlash refine Url nullability (newFromIdea is not yet done) (cherry picked from commit 9b8aac5)
e1bcebb: CR-IC-2986 (cherry picked from commit 34ef731)
6a65720: cleanup (cherry picked from commit e50df4c)
60e168b: CR-IC-2986 MessageBuilder -> MessageDialogBuilder (cherry picked from commit 1999b51)
be3b2ec: some memory tune-ups
cfbafa0: IDEA-117077 Can't remove files from Recent Files
3f42891: EA-52338 - assert: ComponentManagerImpl.getComponent (cherry picked from commit 7c076b6)
58bc683: IDEA-117030 Groovy/Gradle frequent, severe hangs (cherry picked from commit aadeb26)
0ef7db2: IDEA-117073 Recent files and Switcher are not centred in ide window
4a2dde3: file watchers tips should be in WS only
39ee2d2: update complete statement tips
292b280: remove image tag
bffe81e: missed images
b975e7d: Add missing module definition.
3cd9608: Add license for "aether-api-0.9.0.M2.jar" (cherry picked from commit 0df2a18)
d63a566: IDEA-116452 "Resolve workspace artifacts" option doesn't work with Maven 3.1.x (cherry picked from commit 8c35e68)
9103476: Enter in SE should close popup if selection is a setting
4f37f20:  button placed on top, should be in the middle
6c28556: [log] IDEA-116399 Fix filter by branch
7684e66: IDEA-116881 Please time stamp gradle tasks (cherry picked from commit 79c4e6e)
db139a1: IDEA-116891 gradle import creates a lot of extra empty directories (cherry picked from commit 9732da7)
9ed8e39: WEB-9933 What should happen when creating node.js Express App as New Module? (cherry picked from commit a0c7d51) CR-WS-262
2e2fd29: IDEA-116891 gradle import creates a lot of extra empty directories (cherry picked from commit ca7e083)
5902fb8: IDEA-116974 Gradle Plugin doesn't handle 'providedCompile' dependencies in 'war' projects correctly (cherry picked from commit d3f9d06)
0e97c89: Merge remote-tracking branch 'origin/133' into 133
5be1c50: IDEA-115546 Full Screen Mode: main menu persists on screen, when invoked by the keyboard shortcut(reviewed by kb)
4055528: IDEA-111161 Flat tool window design PATCH(reviewed by kb)
17913b8: Lens pixel hunting (reviewed by kb)
38dd8e8: select correct shell runner in title [^Peter]
57befaf: IDEA-116917 check for jansi in classpath [^Peter]
93e3010: IDEA-66494 Switching between search and replace (cherry picked from commit d7dc6ca) [r=Peter.Gromov]
45d852b: IDEA-66494 Switching between search and replace (cherry picked from commit d7dc6ca) [r=Peter.Gromov]
7673aeb: IDEA-116952 IntelliJ LAF issue (set label.disabledForeground to 999999)
56d2cb6: IDEA-116911 Speed search: wrong background in recent files
6ecd960: IDEA-115577 Commit Changes: keyboard shortcut for Commit Message History does not work
27aa855: IDEA-115708 Add workaround by setting global SSLContext (cherry picked from commit fc3f452bbbef193a3ebf6fd28d7e0bffb14a9a5a)
7c3e066: get rid of invoke later [^Peter]
3f10d5b: special icon for 'generated source' roots: added file forgotten by first cherry-pick (cherry picked from commit 35806f22)
6f3780e: grayed text is invisible on Linux
f64ba46: menu is not visible on Linux + IntelliJ theme
e7f0816: [vcs] IDEA-115571 Don't clean change lists's commit message until committed
f0226f9: [log] Make "show details" & "show long edges" actions dumb aware (cherry picked from commit 726ffc1)
8ca08ac: [log] IDEA-116950 Draw just "tag +" instead of "tag + 5 more" (cherry picked from commit 49a033a)
976a8ef: [log] IDEA-116950 Don't display all tags if there are too many of them
4a1db8f: [log] Refactor: move ref painter & drawRefs & calc refs padding to the common parent class (cherry picked from commit 3bb3524)
5dd3597: IDEA-113730 Implemented "cat" command to read content as binary data (not to read as text data and then convert to bytes using some encoding) (cherry picked from commit efd5985)
4201c87: update tips
5c4c6e0: special icon for 'generated source' roots [rev by Peter] (cherry picked from commit 35806f2)
fcc237f: [^nicity] fix outdated javadoc (completion is performed in a read action) (cherry picked from commit d4e5553)
0f918a9: [^nicity] support hippie completion at the file start (EA-52100) (cherry picked from commit 3334c0b)
41b5038: IDEA-102449 Mac OS + JDK 1.7: dialog sheets go to background if focus is moved from IDEA and then back
aff52ee: IDEA-116784 Error Parsing Regex /\s/ in Groovy [^Peter]
8bf0c61: IDEA-95170 closure parameter type [^peter]
8f7c63d: IDEA-116378 only expressions are available in loop conditions [^peter]
d889262: IDEA-116837 Groovy: don't suggest to shorten references in comments [^peter]
f835a08: IDEA-116621 Groovy: Extract Parameter Refactoring: 'Replace this occurrence only' replaces all occurrences in current method [^peter]
6ee4359: [log] fix action's update()
5b8fb93: do not update recent projects on closing in headless mode
3fb3322: Merge remote-tracking branch 'origin/133' into 133
9251d90: SSH console - credentials validation (cherry picked from commit 8b7b23a)
9947162: IDEA-116824 Gradle: Provide an inspection & quickfix for multiple custom maven repo links (cherry picked from commit 810199f)

Change-Id: I47b8e5f8b6b865ec46d5625dd1838900539d7d93
diff --git a/python/IntelliLang-python/src/META-INF/intellilang-python-support.xml b/python/IntelliLang-python/src/META-INF/intellilang-python-support.xml
index 2ffa9f7..ce37b6b 100644
--- a/python/IntelliLang-python/src/META-INF/intellilang-python-support.xml
+++ b/python/IntelliLang-python/src/META-INF/intellilang-python-support.xml
@@ -7,5 +7,8 @@
   </extensions>
   <extensions defaultExtensionNs="com.intellij">
     <patterns.patternClass className="com.jetbrains.python.patterns.PythonPatterns" alias="py"/>
+    <multiHostInjector implementation="com.jetbrains.python.intelliLang.PyCommentInjector"/>
+    <multiHostInjector implementation="com.jetbrains.python.intelliLang.PyConfigurationInjector"/>
+    <multiHostInjector implementation="com.jetbrains.python.intelliLang.PyTemporaryInjector"/>
   </extensions>
 </idea-plugin>
\ No newline at end of file
diff --git a/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyCommentInjector.java b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyCommentInjector.java
new file mode 100644
index 0000000..45eb96b
--- /dev/null
+++ b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyCommentInjector.java
@@ -0,0 +1,25 @@
+package com.jetbrains.python.intelliLang;
+
+import com.intellij.lang.Language;
+import com.intellij.psi.PsiElement;
+import com.jetbrains.python.codeInsight.PyInjectorBase;
+import org.intellij.plugins.intelliLang.inject.InjectedLanguage;
+import org.intellij.plugins.intelliLang.inject.InjectorUtils;
+import org.intellij.plugins.intelliLang.inject.config.BaseInjection;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author vlan
+ */
+public class PyCommentInjector extends PyInjectorBase {
+  @Nullable
+  @Override
+  public Language getInjectedLanguage(@NotNull PsiElement context) {
+    final BaseInjection injection = InjectorUtils.findCommentInjection(context, "comment", null);
+    if (injection != null) {
+      return InjectedLanguage.findLanguageById(injection.getInjectedLanguageId());
+    }
+    return null;
+  }
+}
diff --git a/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyConfigurationInjector.java b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyConfigurationInjector.java
new file mode 100644
index 0000000..f672f5d
--- /dev/null
+++ b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyConfigurationInjector.java
@@ -0,0 +1,33 @@
+package com.jetbrains.python.intelliLang;
+
+import com.intellij.lang.Language;
+import com.intellij.psi.PsiElement;
+import com.jetbrains.python.codeInsight.PyInjectorBase;
+import org.intellij.plugins.intelliLang.Configuration;
+import org.intellij.plugins.intelliLang.inject.InjectedLanguage;
+import org.intellij.plugins.intelliLang.inject.InjectorUtils;
+import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport;
+import org.intellij.plugins.intelliLang.inject.config.BaseInjection;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author vlan
+ */
+public class PyConfigurationInjector extends PyInjectorBase {
+  @Nullable
+  @Override
+  public Language getInjectedLanguage(@NotNull PsiElement context) {
+    for (LanguageInjectionSupport support : InjectorUtils.getActiveInjectionSupports()) {
+      if (support instanceof PyLanguageInjectionSupport) {
+        final Configuration configuration = Configuration.getInstance();
+        for (BaseInjection injection : configuration.getInjections(support.getId())) {
+          if (injection.acceptsPsiElement(context)) {
+            return InjectedLanguage.findLanguageById(injection.getInjectedLanguageId());
+          }
+        }
+      }
+    }
+    return null;
+  }
+}
diff --git a/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyLanguageInjectionSupport.java b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyLanguageInjectionSupport.java
index 5a91db5..dee16d2 100644
--- a/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyLanguageInjectionSupport.java
+++ b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyLanguageInjectionSupport.java
@@ -15,22 +15,17 @@
  */
 package com.jetbrains.python.intelliLang;
 
-import com.intellij.lang.Language;
-import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.Ref;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiLanguageInjectionHost;
 import com.jetbrains.python.patterns.PythonPatterns;
 import com.jetbrains.python.psi.PyElement;
-import com.jetbrains.python.psi.PyStringLiteralExpression;
 import org.intellij.plugins.intelliLang.inject.AbstractLanguageInjectionSupport;
 import org.intellij.plugins.intelliLang.inject.config.BaseInjection;
-import org.jdom.Element;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.List;
-
 /**
  * @author yole
  */
@@ -54,36 +49,15 @@
     return host instanceof PyElement;
   }
 
-  @Override
-  public boolean useDefaultInjector(PsiLanguageInjectionHost host) {
-    return true;
-  }
-
-  @Override
-  public BaseInjection createInjection(Element element) {
-    // This is how DefaultLanguageInjector gets its injection ranges
-    return new BaseInjection(getId()) {
-      @NotNull
-      @Override
-      public List<TextRange> getInjectedArea(PsiElement element) {
-        if (element instanceof PyStringLiteralExpression) {
-          return ((PyStringLiteralExpression)element).getStringValueTextRanges();
-        }
-        return super.getInjectedArea(element);
-      }
-    };
-  }
-
-  @Override
-  public boolean addInjectionInPlace(Language language, PsiLanguageInjectionHost psiElement) {
-    // XXX: Disable temporary injections via intention actions for Python elements, since TemporaryPlacesInjector cannot handle elements
-    // with multiple injection text ranges (PY-10691)
-    return true;
-  }
-
   @Nullable
   @Override
   public String getHelpId() {
     return "reference.settings.language.injection.generic.python";
   }
+
+  @Nullable
+  @Override
+  public BaseInjection findCommentInjection(@NotNull PsiElement host, @Nullable Ref<PsiElement> commentRef) {
+    return null;
+  }
 }
diff --git a/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyTemporaryInjector.java b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyTemporaryInjector.java
new file mode 100644
index 0000000..0bbcdef
--- /dev/null
+++ b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyTemporaryInjector.java
@@ -0,0 +1,40 @@
+package com.jetbrains.python.intelliLang;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.injection.MultiHostRegistrar;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiLanguageInjectionHost;
+import com.jetbrains.python.codeInsight.PyInjectorBase;
+import org.intellij.plugins.intelliLang.inject.InjectedLanguage;
+import org.intellij.plugins.intelliLang.inject.InjectorUtils;
+import org.intellij.plugins.intelliLang.inject.TemporaryPlacesRegistry;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author vlan
+ */
+public class PyTemporaryInjector extends PyInjectorBase {
+  @Override
+  public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) {
+    if (registerInjection(registrar, context)) {
+      final TemporaryPlacesRegistry registry = TemporaryPlacesRegistry.getInstance(context.getProject());
+      InjectorUtils.registerSupport(registry.getLanguageInjectionSupport(), false, registrar);
+    }
+  }
+
+  @Nullable
+  @Override
+  public Language getInjectedLanguage(@NotNull PsiElement context) {
+    final TemporaryPlacesRegistry registry = TemporaryPlacesRegistry.getInstance(context.getProject());
+    if (context instanceof PsiLanguageInjectionHost) {
+      final PsiFile file = context.getContainingFile();
+      final InjectedLanguage injectedLanguage = registry.getLanguageFor((PsiLanguageInjectionHost)context, file);
+      if (injectedLanguage != null) {
+        return injectedLanguage.getLanguage();
+      }
+    }
+    return null;
+  }
+}
diff --git a/python/IntelliLang-python/src/pyInjections.xml b/python/IntelliLang-python/src/pyInjections.xml
index e9ae34e..f561c1d 100644
--- a/python/IntelliLang-python/src/pyInjections.xml
+++ b/python/IntelliLang-python/src/pyInjections.xml
@@ -9,6 +9,6 @@
   </injection>
   <injection language="SQL" injector-id="python">
     <display-name>"SQL select/delete/insert/update/create"</display-name>
-    <place><![CDATA[pyLiteralExpression().withText(string().matchesBrics(" *(((SELECT|DELETE) .*FROM)|((INSERT|REPLACE) .*INTO)|(UPDATE .* SET)|((CREATE|DROP|ALTER) +(TABLE|INDEX))) .*"))]]></place>
+    <place><![CDATA[pyLiteralExpression().withText(string().matchesBrics("[UuRrBb\\\"\\' \t]*(((SELECT|DELETE) .*FROM)|((INSERT|REPLACE) .*INTO)|(UPDATE .* SET)|((CREATE|DROP|ALTER) +(TABLE|INDEX))) .*"))]]></place>
   </injection>
 </component>
diff --git a/python/helpers/generator3.py b/python/helpers/generator3.py
index 5fced92..fe24620 100644
--- a/python/helpers/generator3.py
+++ b/python/helpers/generator3.py
@@ -38,12 +38,12 @@
     return fname
 
 
-def redo_module(mod_name, outfile, module_file_name, doing_builtins):
+def redo_module(module_name, outfile, module_file_name, doing_builtins):
     # gobject does 'del _gobject' in its __init__.py, so the chained attribute lookup code
     # fails to find 'gobject._gobject'. thus we need to pull the module directly out of
     # sys.modules
-    mod = sys.modules.get(mod_name)
-    mod_path = mod_name.split('.')
+    mod = sys.modules.get(module_name)
+    mod_path = module_name.split('.')
     if not mod and sys.platform == 'cli':
         # "import System.Collections" in IronPython 2.7 doesn't actually put System.Collections in sys.modules
         # instead, sys.modules['System'] get set to a Microsoft.Scripting.Actions.NamespaceTracker and Collections can be
@@ -54,16 +54,16 @@
                 mod = getattr(mod, component)
             except AttributeError:
                 mod = None
-                report("Failed to find CLR module " + mod_name)
+                report("Failed to find CLR module " + module_name)
                 break
     if mod:
         action("restoring")
         r = ModuleRedeclarator(mod, outfile, module_file_name, doing_builtins=doing_builtins)
-        r.redo(mod_name, ".".join(mod_path[:-1]) in MODULES_INSPECT_DIR)
+        r.redo(module_name, ".".join(mod_path[:-1]) in MODULES_INSPECT_DIR)
         action("flushing")
         r.flush()
     else:
-        report("Failed to find imported module in sys.modules " + mod_name)
+        report("Failed to find imported module in sys.modules " + module_name)
 
 # find_binaries functionality
 def cut_binary_lib_suffix(path, f):
@@ -122,6 +122,18 @@
             os.path.exists(os.path.join(root, d, "__init__.pyo")))
 
 
+def walk_python_path(path):
+    for root, dirs, files in os.walk(path):
+        if root.endswith('__pycache__'):
+            continue
+        dirs_copy = list(dirs)
+        for d in dirs_copy:
+            if d.endswith('__pycache__') or not is_module(d, root):
+                dirs.remove(d)
+        # some files show up but are actually non-existent symlinks
+        yield root, [f for f in files if os.path.exists(os.path.join(root, f))]
+
+
 def list_binaries(paths):
     """
     Finds binaries in the given list of paths.
@@ -139,13 +151,7 @@
     paths = sorted_no_case(paths)
     for path in paths:
         if path == os.path.dirname(sys.argv[0]): continue
-        for root, dirs, files in os.walk(path):
-            if root.endswith('__pycache__'): continue
-            dirs_copy = list(dirs)
-            for d in dirs_copy:
-                if d.endswith("__pycache__") or not is_module(d, root):
-                    dirs.remove(d)
-
+        for root, files in walk_python_path(path):
             cutpoint = path.rfind(SEP)
             if cutpoint > 0:
                 preprefix = path[(cutpoint + len(SEP)):] + '.'
@@ -180,17 +186,10 @@
 
             path = os.path.normpath(path)
 
-            for root, dirs, files in os.walk(path):
-                if root.endswith('__pycache__'): continue
-                dirs_copy = list(dirs)
-                for d in dirs_copy:
-                    if d.endswith("__pycache__") or not is_module(d, root):
-                        dirs.remove(d)
+            for root, files in walk_python_path(path):
                 for name in files:
                     if name.endswith('.py'):
                         file_path = os.path.join(root, name)
-                        # some files show up but are actually non-existent symlinks
-                        if not os.path.exists(file_path): continue
                         say("%s\t%s\t%d", os.path.normpath(file_path), path, os.path.getsize(file_path))
         say('END')
         sys.stdout.flush()
diff --git a/python/helpers/pycharm/tcunittest.py b/python/helpers/pycharm/tcunittest.py
index 07da02d..b6950c9 100644
--- a/python/helpers/pycharm/tcunittest.py
+++ b/python/helpers/pycharm/tcunittest.py
@@ -47,7 +47,7 @@
     quot = val[0]
     count = 1
     quote_ind = val[count:].find(quot)
-    while val[count+quote_ind-1] == "\\" and quote_ind != -1:
+    while quote_ind != -1 and val[count+quote_ind-1] == "\\":
       count = count + quote_ind + 1
       quote_ind = val[count:].find(quot)
 
@@ -60,16 +60,15 @@
       val = val[val_index+2:].strip()
       quot = val[0]
       quote_ind = val[count:].find(quot)
-      while val[count+quote_ind-1] == "\\" and quote_ind != -1:
+      while quote_ind != -1 and val[count+quote_ind-1] == "\\":
         count = count + quote_ind + 1
         quote_ind = val[count:].find(quot)
       return val[0:quote_ind+count+1]
 
     else:
       quot = val[-1]
-      count = 0
-      quote_ind = val[:len(val)-count-1].rfind(quot)
-      while val[quote_ind-1] == "\\":
+      quote_ind = val[:len(val)-1].rfind(quot)
+      while quote_ind != -1 and val[quote_ind-1] == "\\":
         quote_ind = val[:quote_ind-1].rfind(quot)
       return val[quote_ind:]
 
diff --git a/python/helpers/pydev/pydev_console_utils.py b/python/helpers/pydev/pydev_console_utils.py
index ee62910..54a8585 100644
--- a/python/helpers/pydev/pydev_console_utils.py
+++ b/python/helpers/pydev/pydev_console_utils.py
@@ -4,6 +4,7 @@
 import traceback
 
 from pydevd_constants import USE_LIB_COPY
+from pydevd_constants import IS_JYTHON
 
 try:
     if USE_LIB_COPY:
@@ -132,6 +133,16 @@
             return '\n'
 
 
+class CodeFragment:
+    def __init__(self, text, is_single_line=True):
+        self.text = text
+        self.is_single_line = is_single_line
+        
+    def append(self, code_fragment):
+        self.text = self.text + "\n" + code_fragment.text
+        if not code_fragment.is_single_line:
+            self.is_single_line = False
+
 #=======================================================================================================================
 # BaseInterpreterInterface
 #=======================================================================================================================
@@ -140,22 +151,16 @@
         self.mainThread = mainThread
         self.interruptable = False
         self.exec_queue = _queue.Queue(0)
-        self.buffer = []
+        self.buffer = None
 
-    def needMore(self, buffer, line):
-        if not buffer:
-            buffer = []
-        buffer.append(line)
-        source = "\n".join(buffer)
+    def needMoreForCode(self, source):
         if hasattr(self.interpreter, 'is_complete'):
             return not self.interpreter.is_complete(source)
-
         try:
-            code = self.interpreter.compile(source, "<input>", "single")
+            code = self.interpreter.compile(source, '<input>', 'exec')
         except (OverflowError, SyntaxError, ValueError):
             # Case 1
             return False
-
         if code is None:
             # Case 2
             return True
@@ -163,10 +168,15 @@
         # Case 3
         return False
 
+    def needMore(self, code_fragment):
+        if self.buffer is None:
+            self.buffer = code_fragment
+        else:
+            self.buffer.append(code_fragment)
+        
+        return self.needMoreForCode(self.buffer.text)
 
-    def addExec(self, line):
-        #f_opened = open('c:/temp/a.txt', 'a')
-        #f_opened.write(line+'\n')
+    def addExec(self, code_fragment):
         original_in = sys.stdin
         try:
             help = None
@@ -199,14 +209,14 @@
                             self._input_error_printed = True
                             sys.stderr.write('\nError when trying to update pydoc.help.input\n')
                             sys.stderr.write('(help() may not work -- please report this as a bug in the pydev bugtracker).\n\n')
-                            import traceback;
+                            import traceback
 
                             traceback.print_exc()
 
                 try:
                     self.startExec()
-                    more = self.doAddExec(line)
-                    self.finishExec()
+                    more = self.doAddExec(code_fragment)
+                    self.finishExec(more)
                 finally:
                     if help is not None:
                         try:
@@ -226,12 +236,10 @@
 
             traceback.print_exc()
 
-        #it's always false at this point
-        need_input = False
-        return more, need_input
+        return more
 
 
-    def doAddExec(self, line):
+    def doAddExec(self, codeFragment):
         '''
         Subclasses should override.
         
@@ -309,15 +317,31 @@
             return ''
 
 
-    def execLine(self, line):
+    def doExecCode(self, code, is_single_line):
         try:
-            #buffer = self.interpreter.buffer[:]
-            self.exec_queue.put(line)
-            return self.needMore(self.buffer, line)
+            code_fragment = CodeFragment(code, is_single_line)
+            more = self.needMore(code_fragment)
+            if not more:
+                code_fragment = self.buffer
+                self.buffer = None
+                self.exec_queue.put(code_fragment)
+
+            return more
         except:
             traceback.print_exc()
             return False
 
+    def execLine(self, line):
+        return self.doExecCode(line, True)
+
+
+    def execMultipleLines(self, lines):
+        if IS_JYTHON:
+            for line in lines.split('\n'):
+                self.doExecCode(line, True)
+        else:
+            return self.doExecCode(lines, False)
+
 
     def interrupt(self):
         try:
@@ -343,13 +367,13 @@
         else:
             return None
 
-    def finishExec(self):
+    def finishExec(self, more):
         self.interruptable = False
 
         server = self.get_server()
 
         if server is not None:
-            return server.NotifyFinished()
+            return server.NotifyFinished(more)
         else:
             return True
 
diff --git a/python/helpers/pydev/pydev_ipython_console.py b/python/helpers/pydev/pydev_ipython_console.py
index d3d4ae8..6a8e056 100644
--- a/python/helpers/pydev/pydev_ipython_console.py
+++ b/python/helpers/pydev/pydev_ipython_console.py
@@ -39,14 +39,14 @@
     def get_greeting_msg(self):
         return self.interpreter.get_greeting_msg()
 
-    def doAddExec(self, line):
+    def doAddExec(self, codeFragment):
         self.notify_about_magic()
-        if (line.rstrip().endswith('??')):
+        if (codeFragment.text.rstrip().endswith('??')):
             print('IPython-->')
         try:
-            res = bool(self.interpreter.addExec(line))
+            res = bool(self.interpreter.addExec(codeFragment.text))
         finally:
-            if (line.rstrip().endswith('??')):
+            if (codeFragment.text.rstrip().endswith('??')):
                 print('<--IPython')
 
         return res
diff --git a/python/helpers/pydev/pydev_monkey.py b/python/helpers/pydev/pydev_monkey.py
index 07c7e2b..8dd94ab 100644
--- a/python/helpers/pydev/pydev_monkey.py
+++ b/python/helpers/pydev/pydev_monkey.py
@@ -37,8 +37,9 @@
                 host, port = pydevd.dispatch()
 
                 if port is not None:
-                    args[indC + 1] = "import sys; sys.path.append('%s'); import pydevd; pydevd.settrace(host='%s', port=%s, suspend=False); %s"%(helpers, host, port, args[indC + 1])
-                    return args
+                    new_args.extend(args)
+                    new_args[indC + 1] = "import sys; sys.path.append('%s'); import pydevd; pydevd.settrace(host='%s', port=%s, suspend=False); %s"%(helpers, host, port, args[indC + 1])
+                    return new_args
             else:
                 new_args.append(args[0])
         else:
@@ -99,8 +100,9 @@
     args = str_to_args(new_arg_str)
     if not is_python(args[0]):
         return arg_str
-    art = args_to_str(patch_args(args))
-    return art
+    arg_str = args_to_str(patch_args(args))
+    pydev_log.debug("New args: %s"% arg_str)
+    return arg_str
 
 def monkey_patch_module(module, funcname, create_func):
     if hasattr(module, funcname):
diff --git a/python/helpers/pydev/pydevconsole.py b/python/helpers/pydev/pydevconsole.py
index 026fb7f..e8b8d29 100644
--- a/python/helpers/pydev/pydevconsole.py
+++ b/python/helpers/pydev/pydevconsole.py
@@ -10,7 +10,7 @@
 import sys
 
 from pydevd_constants import USE_LIB_COPY
-from pydevd_utils import *
+from pydevd_constants import IS_JYTHON
 
 if USE_LIB_COPY:
     import _pydev_threading as threading
@@ -51,6 +51,7 @@
     setattr(__builtin__, 'False', 0)
 
 from pydev_console_utils import BaseInterpreterInterface
+from pydev_console_utils import CodeFragment
 
 IS_PYTHON_3K = False
 
@@ -72,56 +73,30 @@
 except ImportError:
     import _pydev_xmlrpclib as xmlrpclib
 
-try:
-    class ExecState:
-        FIRST_CALL = True
-        PYDEV_CONSOLE_RUN_IN_UI = False #Defines if we should run commands in the UI thread.
 
-    from org.python.pydev.core.uiutils import RunInUiThread #@UnresolvedImport
-    from java.lang import Runnable #@UnresolvedImport
+class Command:
+    def __init__(self, interpreter, code_fragment):
+        """
+        :type code_fragment: CodeFragment
+        :type interpreter: InteractiveConsole
+        """
+        self.interpreter = interpreter
+        self.code_fragment = code_fragment
+        self.more = None
 
-    class Command(Runnable):
-        def __init__(self, interpreter, line):
-            self.interpreter = interpreter
-            self.line = line
-
-        def run(self):
-            if ExecState.FIRST_CALL:
-                ExecState.FIRST_CALL = False
-                sys.stdout.write('\nYou are now in a console within Eclipse.\nUse it with care as it can halt the VM.\n')
-                sys.stdout.write(
-                    'Typing a line with "PYDEV_CONSOLE_TOGGLE_RUN_IN_UI"\nwill start executing all the commands in the UI thread.\n\n')
-
-            if self.line == 'PYDEV_CONSOLE_TOGGLE_RUN_IN_UI':
-                ExecState.PYDEV_CONSOLE_RUN_IN_UI = not ExecState.PYDEV_CONSOLE_RUN_IN_UI
-                if ExecState.PYDEV_CONSOLE_RUN_IN_UI:
-                    sys.stdout.write(
-                        'Running commands in UI mode. WARNING: using sys.stdin (i.e.: calling raw_input()) WILL HALT ECLIPSE.\n')
-                else:
-                    sys.stdout.write('No longer running commands in UI mode.\n')
-                self.more = False
-            else:
-                self.more = self.interpreter.push(self.line)
-
-
-    def Sync(runnable):
-        if ExecState.PYDEV_CONSOLE_RUN_IN_UI:
-            return RunInUiThread.sync(runnable)
+    @staticmethod
+    def symbol_for_fragment(code_fragment):
+        if code_fragment.is_single_line:
+            symbol = 'single'
         else:
-            return runnable.run()
+            symbol = 'exec' # Jython doesn't support this
+        return symbol
 
-except:
-    #If things are not there, define a way in which there's no 'real' sync, only the default execution.
-    class Command:
-        def __init__(self, interpreter, line):
-            self.interpreter = interpreter
-            self.line = line
+    def run(self):
+        text = self.code_fragment.text
+        symbol = self.symbol_for_fragment(self.code_fragment)
 
-        def run(self):
-            self.more = self.interpreter.push(self.line)
-
-    def Sync(runnable):
-        runnable.run()
+        self.more = self.interpreter.runsource(text, '<input>', symbol)
 
 try:
     try:
@@ -152,9 +127,9 @@
         self._input_error_printed = False
 
 
-    def doAddExec(self, line):
-        command = Command(self.interpreter, line)
-        Sync(command)
+    def doAddExec(self, codeFragment):
+        command = Command(self.interpreter, codeFragment)
+        command.run()
         return command.more
 
 
@@ -185,14 +160,13 @@
     while 1:
         try:
             try:
-                line = interpreter.exec_queue.get(block=True, timeout=0.05)
+                codeFragment = interpreter.exec_queue.get(block=True, timeout=0.05)
             except _queue.Empty:
                 continue
 
-            if not interpreter.addExec(line):     #TODO: think about locks here
-                interpreter.buffer = []
+            more = interpreter.addExec(codeFragment)
         except KeyboardInterrupt:
-            interpreter.buffer = []
+            interpreter.buffer = None
             continue
         except SystemExit:
             raise
@@ -274,6 +248,7 @@
         raise
 
     server.register_function(interpreter.execLine)
+    server.register_function(interpreter.execMultipleLines)
     server.register_function(interpreter.getCompletions)
     server.register_function(interpreter.getFrame)
     server.register_function(interpreter.getVariable)
@@ -339,17 +314,17 @@
 def get_frame():
     return interpreterInterface.getFrame()
 
-def exec_expression(expression, globals, locals):
+def exec_code(code, globals, locals):
     interpreterInterface = get_interpreter()
 
     interpreterInterface.interpreter.update(globals, locals)
 
-    res = interpreterInterface.needMore(None, expression)
+    res = interpreterInterface.needMore(code)
 
     if res:
         return True
 
-    interpreterInterface.addExec(expression)
+    interpreterInterface.addExec(code)
 
     return False
 
@@ -399,7 +374,7 @@
     updated_globals.update(frame.f_locals) #locals later because it has precedence over the actual globals
 
     if IPYTHON:
-        return exec_expression(expression, updated_globals, frame.f_locals)
+        return exec_code(CodeFragment(expression), updated_globals, frame.f_locals)
 
     interpreter = ConsoleWriter()
 
diff --git a/python/helpers/pydev/pydevd_constants.py b/python/helpers/pydev/pydevd_constants.py
index 34759f7..5e78e15 100644
--- a/python/helpers/pydev/pydevd_constants.py
+++ b/python/helpers/pydev/pydevd_constants.py
@@ -41,6 +41,10 @@
 
 import os
 
+import pydevd_vm_type
+
+IS_JYTHON = pydevd_vm_type.GetVmType() == pydevd_vm_type.PydevdVmType.JYTHON
+
 #=======================================================================================================================
 # Python 3?
 #=======================================================================================================================
diff --git a/python/helpers/pydev/test_debug.py b/python/helpers/pydev/test_debug.py
index 89051c8..bc55de1 100644
--- a/python/helpers/pydev/test_debug.py
+++ b/python/helpers/pydev/test_debug.py
@@ -1,16 +1,20 @@
 __author__ = 'Dmitry.Trofimov'
 
 import unittest
+import os
+
+test_data_path = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..', 'python', 'testData', 'debug'))
 
 class PyDevTestCase(unittest.TestCase):
     def testZipFileExits(self):
         from pydevd_file_utils import exists
-        self.assertTrue(exists('../../../testData/debug/zipped_lib.zip/zipped_module.py'))
-        self.assertFalse(exists('../../../testData/debug/zipped_lib.zip/zipped_module2.py'))
-        self.assertFalse(exists('../../../testData/debug/zipped_lib2.zip/zipped_module.py'))
+
+        self.assertTrue(exists(test_data_path +'/zipped_lib.zip/zipped_module.py'))
+        self.assertFalse(exists(test_data_path + '/zipped_lib.zip/zipped_module2.py'))
+        self.assertFalse(exists(test_data_path + '/zipped_lib2.zip/zipped_module.py'))
 
 
     def testEggFileExits(self):
         from pydevd_file_utils import exists
-        self.assertTrue(exists('../../../testData/debug/pycharm-debug.egg/pydev/pydevd.py'))
-        self.assertFalse(exists('../../../testData/debug/pycharm-debug.egg/pydev/pydevd2.py'))
+        self.assertTrue(exists(test_data_path + '/pycharm-debug.egg/pydev/pydevd.py'))
+        self.assertFalse(exists(test_data_path + '/pycharm-debug.egg/pydev/pydevd2.py'))
diff --git a/python/openapi/src/com/jetbrains/python/psi/PyStringLiteralFileReferenceSet.java b/python/openapi/src/com/jetbrains/python/psi/PyStringLiteralFileReferenceSet.java
index e74cd80..6c470c7 100644
--- a/python/openapi/src/com/jetbrains/python/psi/PyStringLiteralFileReferenceSet.java
+++ b/python/openapi/src/com/jetbrains/python/psi/PyStringLiteralFileReferenceSet.java
@@ -20,17 +20,19 @@
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.PsiReferenceProvider;
 import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
-import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * @author traff
  */
 public class PyStringLiteralFileReferenceSet extends RootFileReferenceSet {
+  public static final Pattern DELIMITERS = Pattern.compile("\\\\|/");
   private final PyStringLiteralExpression myStringLiteralExpression;
 
 
@@ -57,61 +59,33 @@
   protected void reparse() {
     //noinspection ConstantConditions
     if (myStringLiteralExpression != null) {
-      MyTextRangeConsumer textRangeConsumer = new MyTextRangeConsumer(this);
-
-      myStringLiteralExpression.iterateCharacterRanges(textRangeConsumer);
-      textRangeConsumer.finish();
-
-      List<FileReference> referencesList = textRangeConsumer.myReferenceList;
-
-      myReferences = referencesList.toArray(new FileReference[referencesList.size()]);
+      final List<FileReference> references = getFileReferences(myStringLiteralExpression);
+      myReferences = references.toArray(new FileReference[references.size()]);
     }
   }
 
-  private static class MyTextRangeConsumer implements PyStringLiteralExpression.TextRangeConsumer {
-    private final StringBuilder myItem = new StringBuilder();
-    private int myStartOffset = -1;
-    private int myIndex = 0;
-    private int myEndOffset = -1;
-    private final FileReferenceSet myFileReferenceSet;
-
-
-    private final List<FileReference> myReferenceList = new ArrayList<FileReference>();
-
-    private MyTextRangeConsumer(FileReferenceSet set) {
-      myFileReferenceSet = set;
-    }
-
-    @Override
-    public boolean process(int startOffset, int endOffset, String value) {
-      if ("\\".equals(value) || "/".equals(value)) {
-        addReference(startOffset);
+  @NotNull
+  private List<FileReference> getFileReferences(@NotNull PyStringLiteralExpression expression) {
+    final String value = expression.getStringValue();
+    final Matcher matcher = DELIMITERS.matcher(value);
+    int start = 0;
+    int index = 0;
+    final List<FileReference> results = new ArrayList<FileReference>();
+    while (matcher.find()) {
+      final String s = value.substring(start, matcher.start());
+      if (!s.isEmpty()) {
+        final TextRange range = TextRange.create(expression.valueOffsetToTextOffset(start),
+                                                 expression.valueOffsetToTextOffset(matcher.start()));
+        results.add(createFileReference(range, index++, s));
       }
-      else {
-        if (myStartOffset == -1) {
-          myStartOffset = startOffset;
-        }
-        myEndOffset = endOffset;
-        myItem.append(value);
-      }
-      return true;
+      start = matcher.end();
     }
-
-    private void addReference(int startOffset) {
-      if (myStartOffset != -1) {
-        final FileReference ref = myFileReferenceSet.createFileReference(
-          new TextRange(myStartOffset, startOffset),
-          myIndex++,
-          myItem.toString());
-        myReferenceList.add(ref);
-        myStartOffset = -1;
-        myItem.setLength(0);
-      }
+    final String s = value.substring(start);
+    if (!s.isEmpty()) {
+      final TextRange range = TextRange.create(expression.valueOffsetToTextOffset(start),
+                                               expression.valueOffsetToTextOffset(value.length()));
+      results.add(createFileReference(range, index, s));
     }
-
-
-    public void finish() {
-      addReference(myEndOffset);
-    }
+    return results;
   }
 }
diff --git a/python/pluginResources/META-INF/plugin.xml b/python/pluginResources/META-INF/plugin.xml
index 0d0d760..f263de7 100644
--- a/python/pluginResources/META-INF/plugin.xml
+++ b/python/pluginResources/META-INF/plugin.xml
@@ -4,9 +4,9 @@
 
   <id>PythonCore</id>
   <name>Python Community Edition</name>
-  <idea-version since-build="130.0" until-build="133.*"/>
+  <idea-version since-build="133.286" until-build="133.*"/>
   <description>Smart editing for Python scripts</description>
-  <version>3.1 Beta</version>
+  <version>3.1 Beta 2</version>
   <depends>com.intellij.modules.java</depends>
 
 
diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyStringLiteralExpression.java b/python/psi-api/src/com/jetbrains/python/psi/PyStringLiteralExpression.java
index 8c3182d..f7dd122 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PyStringLiteralExpression.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyStringLiteralExpression.java
@@ -16,8 +16,10 @@
 package com.jetbrains.python.psi;
 
 import com.intellij.lang.ASTNode;
+import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.PsiLanguageInjectionHost;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
 
@@ -28,20 +30,6 @@
 
   int valueOffsetToTextOffset(int valueOffset);
 
-  void iterateCharacterRanges(TextRangeConsumer consumer);
-
-  /**
-   * Iterator over decoded string characters.
-   */
-  interface TextRangeConsumer {
-    /**
-     * Process a decoded character.
-     *
-     * @param startOffset start offset in the un-decoded string
-     * @param endOffset end offset in the un-decoded string
-     * @param value decoded character value
-     * @return false in order to stop iteration
-     */
-    boolean process(int startOffset, int endOffset, String value);
-  }
+  @NotNull
+  List<Pair<TextRange, String>> getDecodedFragments();
 }
diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/PyResolveResultRater.java b/python/psi-api/src/com/jetbrains/python/psi/impl/PyResolveResultRater.java
new file mode 100644
index 0000000..961293f
--- /dev/null
+++ b/python/psi-api/src/com/jetbrains/python/psi/impl/PyResolveResultRater.java
@@ -0,0 +1,26 @@
+/*
+ * 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.jetbrains.python.psi.impl;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+public interface PyResolveResultRater {
+  ExtensionPointName<PyResolveResultRater> EP_NAME = ExtensionPointName.create("Pythonid.resolveResultRater");
+
+  int getRate(@NotNull final PsiElement target);
+}
diff --git a/python/pydevSrc/com/jetbrains/python/console/pydev/AbstractConsoleCommunication.java b/python/pydevSrc/com/jetbrains/python/console/pydev/AbstractConsoleCommunication.java
index 70594f9..e8fa271 100644
--- a/python/pydevSrc/com/jetbrains/python/console/pydev/AbstractConsoleCommunication.java
+++ b/python/pydevSrc/com/jetbrains/python/console/pydev/AbstractConsoleCommunication.java
@@ -57,9 +57,9 @@
   }
 
   @Override
-  public void notifyCommandExecuted() {
+  public void notifyCommandExecuted(boolean more) {
     for (ConsoleCommunicationListener listener: communicationListeners) {
-      listener.commandExecuted();
+      listener.commandExecuted(more);
     }
   }
 
diff --git a/python/pydevSrc/com/jetbrains/python/console/pydev/ConsoleCommunication.java b/python/pydevSrc/com/jetbrains/python/console/pydev/ConsoleCommunication.java
index a114c2c..3017171 100644
--- a/python/pydevSrc/com/jetbrains/python/console/pydev/ConsoleCommunication.java
+++ b/python/pydevSrc/com/jetbrains/python/console/pydev/ConsoleCommunication.java
@@ -18,13 +18,30 @@
 
   boolean isExecuting();
 
-  void execInterpreter(String s, Function<InterpreterResponse, Object> callback);
+  void execInterpreter(ConsoleCodeFragment code, Function<InterpreterResponse, Object> callback);
 
   void interrupt();
 
   void addCommunicationListener(ConsoleCommunicationListener listener);
 
-  void notifyCommandExecuted();
+  void notifyCommandExecuted(boolean more);
   void notifyInputRequested();
 
+  class ConsoleCodeFragment {
+    private final String myText;
+    private final boolean myIsSingleLine;
+
+    public ConsoleCodeFragment(String text, boolean isSingleLine) {
+      myText = text;
+      myIsSingleLine = isSingleLine;
+    }
+
+    public String getText() {
+      return myText;
+    }
+
+    public boolean isSingleLine() {
+      return myIsSingleLine;
+    }
+  }
 }
diff --git a/python/pydevSrc/com/jetbrains/python/console/pydev/ConsoleCommunicationListener.java b/python/pydevSrc/com/jetbrains/python/console/pydev/ConsoleCommunicationListener.java
index 562f729..a9263b7 100644
--- a/python/pydevSrc/com/jetbrains/python/console/pydev/ConsoleCommunicationListener.java
+++ b/python/pydevSrc/com/jetbrains/python/console/pydev/ConsoleCommunicationListener.java
@@ -4,6 +4,6 @@
  * @author traff
  */
 public interface ConsoleCommunicationListener {
-  void commandExecuted();
+  void commandExecuted(boolean more);
   void inputRequested();
 }
diff --git a/python/pydevSrc/com/jetbrains/python/console/pydev/IScriptConsoleCommunication.java b/python/pydevSrc/com/jetbrains/python/console/pydev/IScriptConsoleCommunication.java
deleted file mode 100644
index 3c998c8..0000000
--- a/python/pydevSrc/com/jetbrains/python/console/pydev/IScriptConsoleCommunication.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- 
- *******************************************************************************/
-package com.jetbrains.python.console.pydev;
-
-import com.intellij.util.Function;
-
-/**
- * Interface for the console communication.
- *
- * This interface is meant to be the way to communicate with the shell.
- */
-public interface IScriptConsoleCommunication {
-
-    /**
-     * Executes a given command in the interpreter (push a line)
-     *
-     * @param command the command to be executed
-     * @return the response from the interpreter (contains the stdout, stderr, etc).
-     * @throws Exception
-     */
-    void execInterpreter(String command, Function<InterpreterResponse, Object> onResponseReceived);
-
-    /**
-     * Creates the completions to be applied in the interpreter.
-     *
-     * @param text the text with what should be completed (e.g.: xxx.bar.foo)
-     * @param offset the offset where the completion was requested in the console document
-     * @return a list of proposals that can be applied for the given text.
-     * @throws Exception
-     */
-    //public ICompletionProposal[] getCompletions(String text, int offset) throws Exception;
-
-    /**
-     * Gets the description to be shown on hover to the user
-     *
-     * @param text the text representing the completion to be applied
-     * @return the description to be shown to the user
-     * @throws Exception
-     */
-    String getDescription(String text) throws Exception;
-
-    /**
-     * Stops the communication with the server. Should ask the server to terminate at this point.
-     * @throws Exception
-     */
-    void close();
-}
\ No newline at end of file
diff --git a/python/resources/idea/PyCharmCoreApplicationInfo.xml b/python/resources/idea/PyCharmCoreApplicationInfo.xml
index ef906b0..0ac5772 100644
--- a/python/resources/idea/PyCharmCoreApplicationInfo.xml
+++ b/python/resources/idea/PyCharmCoreApplicationInfo.xml
@@ -1,6 +1,6 @@
 <component>
   <company name="JetBrains s.r.o." url="http://www.jetbrains.com/?fromIDE"/>
-  <version major="3" minor="0" eap="true"/>
+  <version major="3" minor="1" eap="true"/>
   <build number="__BUILD_NUMBER__" date="__BUILD_DATE__"/>
   <logo url="/pycharm_core_logo.png" textcolor="ffffff" progressColor="ffaa16" progressY="230" progressTailIcon="/community_progress_tail.png"/>
   <about url="/pycharm_core_about.png" logoX="300" logoY="265" logoW="75" logoH="30" foreground="ffffff" linkColor="fca11a"/>
diff --git a/python/rest/resources/META-INF/plugin.xml b/python/rest/resources/META-INF/plugin.xml
index 06cd1f4..76e5727 100644
--- a/python/rest/resources/META-INF/plugin.xml
+++ b/python/rest/resources/META-INF/plugin.xml
@@ -3,12 +3,16 @@
   <id>org.jetbrains.plugins.rest</id>
   <description>This plugin enables support for reStructuredText files (*.rst)</description>
   <vendor>JetBrains</vendor>
-  <version>132.SNAPSHOT</version>
-  <idea-version since-build="130.1" until-build="133.0"/>
+  <version>134.SNAPSHOT</version>
+  <idea-version since-build="130.1"/>
   <depends>com.intellij.modules.lang</depends>
 
   <xi:include href="/META-INF/rest.xml" xpointer="xpointer(/idea-plugin/*)"/>
-
+  <change-notes><![CDATA[
+    <ul>
+    <li>Added inspection for title & underline length math (PY-10998)</li>
+    </ul>
+]]></change-notes>
   <extensions defaultExtensionNs="com.intellij">
     <errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
   </extensions>
diff --git a/python/rest/src/com/jetbrains/rest/RestBundle.properties b/python/rest/src/com/jetbrains/rest/RestBundle.properties
index 24b98c7..192f443 100644
--- a/python/rest/src/com/jetbrains/rest/RestBundle.properties
+++ b/python/rest/src/com/jetbrains/rest/RestBundle.properties
@@ -9,6 +9,7 @@
 ### Annotators ###
 ANN.unknown.target=Unknown target name ''{0}''
 ANN.duplicate.target=Duplicate explicit target name ''{0}''
+ANN.title.length=Title length must match the underline
 ANN.unusable.anonymous.target=Anonymous hyperlink target has no reference
 ANN.inline.block=Blank line is required after a literal block
 
diff --git a/python/rest/src/com/jetbrains/rest/RestLanguage.java b/python/rest/src/com/jetbrains/rest/RestLanguage.java
index c451e37..df05659 100644
--- a/python/rest/src/com/jetbrains/rest/RestLanguage.java
+++ b/python/rest/src/com/jetbrains/rest/RestLanguage.java
@@ -17,10 +17,7 @@
 
 import com.intellij.lang.Language;
 import com.intellij.psi.templateLanguages.TemplateLanguage;
-import com.jetbrains.rest.validation.RestAnnotator;
-import com.jetbrains.rest.validation.RestHyperlinksAnnotator;
-import com.jetbrains.rest.validation.RestInlineBlockAnnotator;
-import com.jetbrains.rest.validation.RestReferenceTargetAnnotator;
+import com.jetbrains.rest.validation.*;
 
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArraySet;
@@ -48,6 +45,7 @@
     _annotators.add(RestHyperlinksAnnotator.class);
     _annotators.add(RestReferenceTargetAnnotator.class);
     _annotators.add(RestInlineBlockAnnotator.class);
+    _annotators.add(RestTitleAnnotator.class);
   }
 
   public Set<Class<? extends RestAnnotator>> getAnnotators() {
diff --git a/python/rest/src/com/jetbrains/rest/psi/RestTitle.java b/python/rest/src/com/jetbrains/rest/psi/RestTitle.java
index eb93cbe..05c2e66 100644
--- a/python/rest/src/com/jetbrains/rest/psi/RestTitle.java
+++ b/python/rest/src/com/jetbrains/rest/psi/RestTitle.java
@@ -16,6 +16,7 @@
 package com.jetbrains.rest.psi;
 
 import com.intellij.lang.ASTNode;
+import com.jetbrains.rest.validation.RestElementVisitor;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -37,15 +38,13 @@
 
   @Nullable
   public String getName() {
-    final String text = getNode().getText();
-    if (text.length() == 0) return null;
+    final String text = getNode().getText().trim();
+    if (text.length() < 2) return null;
     final char adorn = text.charAt(text.length()-2);
     final CharacterIterator it = new StringCharacterIterator(text);
     int finish = 0;
     for (char ch = it.last(); ch != CharacterIterator.DONE; ch = it.previous()) {
-      if (finish == 0)
-        finish++;
-      else if (ch != adorn) {
+      if (ch != adorn) {
         finish = it.getIndex();
         break;
       }
@@ -63,4 +62,25 @@
       return null;
     return text.substring(start, finish).trim();
   }
+
+  @Nullable
+  public String getUnderline() {
+    final String text = getNode().getText().trim();
+    if (text.length() < 2) return null;
+    final char adorn = text.charAt(text.length()-2);
+    final CharacterIterator it = new StringCharacterIterator(text);
+    int start = 0;
+    for (char ch = it.last(); ch != CharacterIterator.DONE; ch = it.previous()) {
+      if (ch != adorn) {
+        start = it.getIndex() + 1;
+        break;
+      }
+    }
+    return text.substring(start, text.length());
+  }
+
+  @Override
+  protected void acceptRestVisitor(RestElementVisitor visitor) {
+    visitor.visitTitle(this);
+  }
 }
diff --git a/python/rest/src/com/jetbrains/rest/validation/RestTitleAnnotator.java b/python/rest/src/com/jetbrains/rest/validation/RestTitleAnnotator.java
new file mode 100644
index 0000000..c906e31
--- /dev/null
+++ b/python/rest/src/com/jetbrains/rest/validation/RestTitleAnnotator.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.jetbrains.rest.validation;
+
+import com.jetbrains.rest.RestBundle;
+import com.jetbrains.rest.psi.RestTitle;
+
+public class RestTitleAnnotator extends RestAnnotator {
+  @Override
+  public void visitTitle(final RestTitle node) {
+    final String name = node.getName();
+    if (name == null) return;
+    int nameLen = name.length();
+    final String underline = node.getUnderline();
+    if (underline != null && nameLen != underline.length()) {
+      getHolder().createWarningAnnotation(node, RestBundle.message("ANN.title.length"));
+    }
+  }
+}
diff --git a/python/src/META-INF/python-core.xml b/python/src/META-INF/python-core.xml
index 6c02c7a..cf37b69 100644
--- a/python/src/META-INF/python-core.xml
+++ b/python/src/META-INF/python-core.xml
@@ -369,6 +369,8 @@
 
     <completion.contributor language="Python"
                             implementationClass="com.jetbrains.python.codeInsight.completion.PyClassNameCompletionContributor"/>
+    <completion.contributor language="Python"
+                            implementationClass="com.jetbrains.python.codeInsight.completion.PyBracketProtectingCompletionContributor"/>
     <weigher key="completion" implementationClass="com.jetbrains.python.codeInsight.completion.PythonCompletionWeigher" order="first"/>
     <completion.confidence language="Python" implementationClass="com.jetbrains.python.codeInsight.completion.PyCompletionConfidence"/>
     <typedHandler implementation="com.jetbrains.python.console.completion.PythonConsoleAutopopupBlockingHandler" id="pydevBlockAutoPopup"
@@ -511,6 +513,7 @@
 
   <extensionPoints>
     <extensionPoint qualifiedName="Pythonid.importResolver" interface="com.jetbrains.python.psi.impl.PyImportResolver"/>
+    <extensionPoint qualifiedName="Pythonid.resolveResultRater" interface="com.jetbrains.python.psi.impl.PyResolveResultRater"/>
     <extensionPoint qualifiedName="Pythonid.typeProvider" interface="com.jetbrains.python.psi.impl.PyTypeProvider"/>
     <extensionPoint qualifiedName="Pythonid.pySuperMethodsSearch" interface="com.intellij.util.QueryExecutor"/>
     <extensionPoint qualifiedName="Pythonid.pyClassInheritorsSearch" interface="com.intellij.util.QueryExecutor"/>
@@ -544,7 +547,6 @@
     <pySuperMethodsSearch implementation="com.jetbrains.python.psi.search.PySuperMethodsSearchExecutor"/>
     <pyClassInheritorsSearch implementation="com.jetbrains.python.psi.search.PyClassInheritorsSearchExecutor"/>
     <pyOverridingMethodsSearch implementation="com.jetbrains.python.psi.search.PyOverridingMethodsSearchExecutor"/>
-    <runnableScriptFilter implementation="com.jetbrains.python.testing.pytest.PyTestRunnableScriptFilter"/>
     <runnableScriptFilter implementation="com.jetbrains.python.testing.PythonUnitTestRunnableScriptFilter"/>
     <dumbAnnotator implementation="com.jetbrains.python.validation.DocStringAnnotator"/>
     <dumbAnnotator implementation="com.jetbrains.python.validation.PyDefinitionsAnnotator"/>
diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties
index 5ee3ef7..28289e0 100644
--- a/python/src/com/jetbrains/python/PyBundle.properties
+++ b/python/src/com/jetbrains/python/PyBundle.properties
@@ -637,6 +637,7 @@
 PARSE.expected.colon=':' expected
 PARSE.expected.rpar=')' expected
 PARSE.expected.lpar='(' expected
+PARSE.expected.rbrace='}' expected
 PARSE.expected.tick='`' (backtick) expected
 PARSE.expected.name=name expected
 PARSE.expected.colon.or.rbracket=':' or ']' expected
diff --git a/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java b/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java
index d68e6c6..9a7edad 100644
--- a/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java
+++ b/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java
@@ -23,6 +23,7 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.Arrays;
 import java.util.List;
 
 import static com.jetbrains.python.inspections.PyStringFormatParser.*;
@@ -31,15 +32,22 @@
  * @author vlan
  */
 public class PyInjectionUtil {
+  public static final List<Class<? extends PyExpression>> ELEMENTS_TO_INJECT_IN =
+    Arrays.asList(PyStringLiteralExpression.class, PyParenthesizedExpression.class, PyBinaryExpression.class, PyCallExpression.class);
+
   private PyInjectionUtil() {}
 
   /**
-   * Returns true if the element is the largest expression that represents a string literal, possibly with concatenation, parentheses,
-   * or formatting.
+   * Returns the largest expression in the specified context that represents a string literal suitable for language injection, possibly
+   * with concatenation, parentheses, or formatting.
    */
-  public static boolean isLargestStringLiteral(@NotNull PsiElement element) {
-    final PsiElement parent = element.getParent();
-    return isStringLiteralPart(element) && (parent == null || !isStringLiteralPart(parent));
+  @Nullable
+  public static PsiElement getLargestStringLiteral(@NotNull PsiElement context) {
+    PsiElement element = null;
+    for (PsiElement current = context; current != null && isStringLiteralPart(current, element); current = current.getParent()) {
+      element = current;
+    }
+    return element;
   }
 
   /**
@@ -47,27 +55,35 @@
    * string concatenations or formatting.
    */
   public static void registerStringLiteralInjection(@NotNull PsiElement element, @NotNull MultiHostRegistrar registrar) {
-    processStringLiteral(element, registrar, "", "", Formatting.NONE);
+    processStringLiteral(element, registrar, "", "", Formatting.PERCENT);
   }
 
-  private static boolean isStringLiteralPart(@NotNull PsiElement element) {
-    if (element instanceof PyStringLiteralExpression) {
+  private static boolean isStringLiteralPart(@NotNull PsiElement element, @Nullable PsiElement context) {
+    if (element == context) {
+      return true;
+    }
+    else if (element instanceof PyStringLiteralExpression) {
       return true;
     }
     else if (element instanceof PyParenthesizedExpression) {
       final PyExpression contained = ((PyParenthesizedExpression)element).getContainedExpression();
-      return contained != null && isStringLiteralPart(contained);
+      return contained != null && isStringLiteralPart(contained, context);
     }
     else if (element instanceof PyBinaryExpression) {
       final PyBinaryExpression expr = (PyBinaryExpression)element;
       final PyExpression left = expr.getLeftExpression();
       final PyExpression right = expr.getRightExpression();
-      return (expr.isOperator("+") && (isStringLiteralPart(left) || right != null && isStringLiteralPart(right))) ||
-              expr.isOperator("%") && isStringLiteralPart(left);
+      if (expr.isOperator("+")) {
+        return isStringLiteralPart(left, context) || right != null && isStringLiteralPart(right, context);
+      }
+      else if (expr.isOperator("%")) {
+        return right != context && isStringLiteralPart(left, context);
+      }
+      return false;
     }
     else if (element instanceof PyCallExpression) {
       final PyExpression qualifier = getFormatCallQualifier((PyCallExpression)element);
-      return qualifier != null && isStringLiteralPart(qualifier);
+      return qualifier != null && isStringLiteralPart(qualifier, context);
     }
     return false;
   }
@@ -100,9 +116,25 @@
             final FormatStringChunk chunk = chunks.get(i);
             if (chunk instanceof ConstantChunk) {
               final int nextIndex = i + 1;
-              final String chunkPrefix = i == 1 && chunks.get(0) instanceof SubstitutionChunk ? missingValue : "";
-              final String chunkSuffix = nextIndex < chunks.size() &&
-                                         chunks.get(nextIndex) instanceof SubstitutionChunk ? missingValue : "";
+              final String chunkPrefix;
+              if (i == 1 && chunks.get(0) instanceof SubstitutionChunk) {
+                chunkPrefix = missingValue;
+              }
+              else if (i == 0) {
+                chunkPrefix = prefix;
+              } else {
+                chunkPrefix = "";
+              }
+              final String chunkSuffix;
+              if (nextIndex < chunks.size() && chunks.get(nextIndex) instanceof SubstitutionChunk) {
+                chunkSuffix = missingValue;
+              }
+              else if (nextIndex == chunks.size()) {
+                chunkSuffix = suffix;
+              }
+              else {
+                chunkSuffix = "";
+              }
               final TextRange chunkRange = chunk.getTextRange().shiftRight(range.getStartOffset());
               registrar.addPlace(chunkPrefix, chunkSuffix, expr, chunkRange);
             }
@@ -123,9 +155,9 @@
       final PyBinaryExpression expr = (PyBinaryExpression)element;
       final PyExpression left = expr.getLeftExpression();
       final PyExpression right = expr.getRightExpression();
-      final boolean isLeftString = isStringLiteralPart(left);
+      final boolean isLeftString = isStringLiteralPart(left, null);
       if (expr.isOperator("+")) {
-        final boolean isRightString = right != null && isStringLiteralPart(right);
+        final boolean isRightString = right != null && isStringLiteralPart(right, null);
         if (isLeftString) {
           processStringLiteral(left, registrar, prefix, isRightString ? "" : missingValue, formatting);
         }
diff --git a/python/src/com/jetbrains/python/codeInsight/PyInjectorBase.java b/python/src/com/jetbrains/python/codeInsight/PyInjectorBase.java
new file mode 100644
index 0000000..98ae8c4
--- /dev/null
+++ b/python/src/com/jetbrains/python/codeInsight/PyInjectorBase.java
@@ -0,0 +1,43 @@
+package com.jetbrains.python.codeInsight;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.injection.MultiHostInjector;
+import com.intellij.lang.injection.MultiHostRegistrar;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author vlan
+ */
+public abstract class PyInjectorBase implements MultiHostInjector {
+  @Override
+  public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) {
+    registerInjection(registrar, context);
+  }
+
+  @NotNull
+  @Override
+  public List<? extends Class<? extends PsiElement>> elementsToInjectIn() {
+    return PyInjectionUtil.ELEMENTS_TO_INJECT_IN;
+  }
+
+  @Nullable
+  public abstract Language getInjectedLanguage(@NotNull PsiElement context);
+
+  protected boolean registerInjection(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) {
+    final Language language = getInjectedLanguage(context);
+    if (language != null) {
+      final PsiElement element = PyInjectionUtil.getLargestStringLiteral(context);
+      if (element != null) {
+        registrar.startInjecting(language);
+        PyInjectionUtil.registerStringLiteralInjection(element, registrar);
+        registrar.doneInjecting();
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PyBracketProtectingCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PyBracketProtectingCompletionContributor.java
new file mode 100644
index 0000000..766e5be
--- /dev/null
+++ b/python/src/com/jetbrains/python/codeInsight/completion/PyBracketProtectingCompletionContributor.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.jetbrains.python.codeInsight.completion;
+
+import com.intellij.codeInsight.completion.CompletionContributor;
+import com.intellij.codeInsight.completion.CompletionInitializationContext;
+import com.intellij.psi.PsiReference;
+import com.jetbrains.python.psi.impl.references.PyOperatorReference;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public class PyBracketProtectingCompletionContributor extends CompletionContributor {
+  @Override
+  public void beforeCompletion(@NotNull CompletionInitializationContext context) {
+    PsiReference ref = context.getFile().findReferenceAt(context.getSelectionEndOffset());
+    if (ref instanceof PyOperatorReference) {
+      context.setReplacementOffset(context.getIdentifierEndOffset());
+    }
+  }
+}
diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PyDocstringCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PyDocstringCompletionContributor.java
index 84d4b88..272adfa 100644
--- a/python/src/com/jetbrains/python/codeInsight/completion/PyDocstringCompletionContributor.java
+++ b/python/src/com/jetbrains/python/codeInsight/completion/PyDocstringCompletionContributor.java
@@ -16,6 +16,7 @@
 package com.jetbrains.python.codeInsight.completion;
 
 import com.intellij.codeInsight.completion.*;
+import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
 import com.intellij.codeInsight.lookup.LookupElementBuilder;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.module.ModuleUtilCore;
@@ -23,8 +24,6 @@
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.util.ProcessingContext;
-import com.jetbrains.python.PyTokenTypes;
-import com.jetbrains.python.documentation.PyDocumentationSettings;
 import com.jetbrains.python.psi.PyDocStringOwner;
 import com.jetbrains.python.psi.PyStringLiteralExpression;
 import com.jetbrains.python.refactoring.PyRefactoringUtil;
@@ -32,7 +31,9 @@
 
 import java.util.Collection;
 
+import static com.intellij.patterns.PlatformPatterns.psiComment;
 import static com.intellij.patterns.PlatformPatterns.psiElement;
+import static com.intellij.patterns.StandardPatterns.or;
 
 /**
  * User : ktisha
@@ -40,7 +41,7 @@
 public class PyDocstringCompletionContributor extends CompletionContributor {
   public PyDocstringCompletionContributor() {
     extend(CompletionType.BASIC,
-           psiElement().inside(PyStringLiteralExpression.class).withElementType(PyTokenTypes.DOCSTRING),
+           or(psiElement().inside(PyStringLiteralExpression.class), psiComment()),
            new IdentifierCompletionProvider());
   }
 
@@ -54,23 +55,22 @@
                                   ProcessingContext context,
                                   @NotNull CompletionResultSet result) {
       if (parameters.isAutoPopup()) return;
-      final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(parameters.getOriginalPosition(), PyDocStringOwner.class);
-      if (docStringOwner != null) {
-        final PsiFile file = docStringOwner.getContainingFile();
-        final Module module = ModuleUtilCore.findModuleForPsiElement(docStringOwner);
-        if (module != null) {
-          final PyDocumentationSettings settings = PyDocumentationSettings.getInstance(module);
-          if (!settings.isPlain(file)) return;
-          result = result.withPrefixMatcher(getPrefix(parameters.getOffset(), file));
-          final Collection<String> identifiers = PyRefactoringUtil.collectUsedNames(docStringOwner);
-          for (String identifier : identifiers)
-            result.addElement(LookupElementBuilder.create(identifier));
+      final PsiElement element = parameters.getOriginalPosition();
+      if (element == null) return;
+      final PsiFile file = element.getContainingFile();
+      if (file.findReferenceAt(parameters.getOffset()) != null) return;
+      final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(element, PyDocStringOwner.class);
+      final Module module = ModuleUtilCore.findModuleForPsiElement(element);
+      if (module != null) {
+        result = result.withPrefixMatcher(getPrefix(parameters.getOffset(), file));
+        final Collection<String> identifiers = PyRefactoringUtil.collectUsedNames(docStringOwner);
+        for (String identifier : identifiers)
+          result.addElement(LookupElementBuilder.create(identifier).withAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE));
 
 
-          final Collection<String> fileIdentifiers = PyRefactoringUtil.collectUsedNames(parameters.getOriginalFile());
-          for (String identifier : fileIdentifiers)
-            result.addElement(LookupElementBuilder.create(identifier));
-        }
+        final Collection<String> fileIdentifiers = PyRefactoringUtil.collectUsedNames(parameters.getOriginalFile());
+        for (String identifier : fileIdentifiers)
+          result.addElement(LookupElementBuilder.create(identifier).withAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE));
       }
     }
   }
diff --git a/python/src/com/jetbrains/python/codeInsight/regexp/PythonRegexpInjector.java b/python/src/com/jetbrains/python/codeInsight/regexp/PythonRegexpInjector.java
index 39c9aff..bb23c47 100644
--- a/python/src/com/jetbrains/python/codeInsight/regexp/PythonRegexpInjector.java
+++ b/python/src/com/jetbrains/python/codeInsight/regexp/PythonRegexpInjector.java
@@ -67,7 +67,7 @@
   @Override
   public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) {
     final PsiElement contextParent = context.getParent();
-    if (PyInjectionUtil.isLargestStringLiteral(context) && contextParent instanceof PyArgumentList) {
+    if (PyInjectionUtil.getLargestStringLiteral(context) == context && contextParent instanceof PyArgumentList) {
       final PyExpression[] args = ((PyArgumentList)contextParent).getArguments();
       int index = ArrayUtil.indexOf(args, context);
       PyCallExpression call = PsiTreeUtil.getParentOfType(context, PyCallExpression.class);
diff --git a/python/src/com/jetbrains/python/console/PyConsoleOptions.java b/python/src/com/jetbrains/python/console/PyConsoleOptions.java
index 6816b93..d02b670 100644
--- a/python/src/com/jetbrains/python/console/PyConsoleOptions.java
+++ b/python/src/com/jetbrains/python/console/PyConsoleOptions.java
@@ -19,8 +19,12 @@
 import com.intellij.openapi.components.*;
 import com.intellij.openapi.module.ModuleManager;
 import com.intellij.openapi.project.Project;
+import com.intellij.util.PathMappingSettings;
 import com.intellij.util.containers.ComparatorUtil;
+import com.intellij.util.xmlb.annotations.*;
 import com.jetbrains.python.run.AbstractPyCommonOptionsForm;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.Map;
 
@@ -80,6 +84,7 @@
     public boolean myShowSeparatorLine = true;
   }
 
+  @Tag("console-settings")
   public static class PyConsoleSettings {
     public String myCustomStartScript = "";
     public String mySdkHome = null;
@@ -90,14 +95,8 @@
     public String myWorkingDirectory = "";
     public boolean myAddContentRoots = true;
     public boolean myAddSourceRoots;
-
-    public String getCustomStartScript() {
-      return myCustomStartScript;
-    }
-
-    public String getSdkHome() {
-      return mySdkHome;
-    }
+    @NotNull
+    private PathMappingSettings myMappings = new PathMappingSettings();
 
     public void apply(AbstractPyCommonOptionsForm form) {
       mySdkHome = form.getSdkHome();
@@ -109,6 +108,7 @@
 
       myAddContentRoots = form.addContentRoots();
       myAddSourceRoots = form.addSourceRoots();
+      myMappings = form.getMappingSettings() == null ? new PathMappingSettings() : form.getMappingSettings();
     }
 
     public boolean isModified(AbstractPyCommonOptionsForm form) {
@@ -119,7 +119,8 @@
              myAddContentRoots != form.addContentRoots() ||
              myAddSourceRoots != form.addSourceRoots()
              || !ComparatorUtil.equalsNullable(myModuleName, form.getModule() == null ? null : form.getModule().getName())
-             || !myWorkingDirectory.equals(form.getWorkingDirectory());
+             || !myWorkingDirectory.equals(form.getWorkingDirectory())
+             || !myMappings.equals(form.getMappingSettings());
     }
 
     public void reset(Project project, AbstractPyCommonOptionsForm form) {
@@ -143,33 +144,103 @@
         myModuleName = form.getModule().getName();
       }
 
-      form.setWorkingDirectory(form.getWorkingDirectory());
+      form.setWorkingDirectory(myWorkingDirectory);
+
+      form.setMappingSettings(myMappings);
     }
 
+    @Attribute("custom-start-script")
+    public String getCustomStartScript() {
+      return myCustomStartScript;
+    }
+
+    @Attribute("sdk-home")
+    public String getSdkHome() {
+      return mySdkHome;
+    }
+
+    @Attribute("module-name")
     public String getModuleName() {
       return myModuleName;
     }
 
+    @Attribute("working-directory")
     public String getWorkingDirectory() {
       return myWorkingDirectory;
     }
 
+    @Attribute("is-module-sdk")
     public boolean isUseModuleSdk() {
       return myUseModuleSdk;
     }
 
+    @Tag("envs")
+    @Property(surroundWithTag = false)
+    @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, keyAttributeName = "key",
+                   entryTagName = "env", valueAttributeName = "value", surroundValueWithTag = false)
     public Map<String, String> getEnvs() {
       return myEnvs;
     }
 
+    @Attribute("add-content-roots")
     public boolean addContentRoots() {
       return myAddContentRoots;
     }
 
+    @Attribute("add-source-roots")
     public boolean addSourceRoots() {
       return myAddSourceRoots;
     }
 
+    @Attribute("interpreter-options")
+    public String getInterpreterOptions() {
+      return myInterpreterOptions;
+    }
+
+    @AbstractCollection(surroundWithTag = false)
+    public PathMappingSettings getMappings() {
+      return myMappings;
+    }
+
+    public void setCustomStartScript(String customStartScript) {
+      myCustomStartScript = customStartScript;
+    }
+
+    public void setSdkHome(String sdkHome) {
+      mySdkHome = sdkHome;
+    }
+
+    public void setInterpreterOptions(String interpreterOptions) {
+      myInterpreterOptions = interpreterOptions;
+    }
+
+    public void setUseModuleSdk(boolean useModuleSdk) {
+      myUseModuleSdk = useModuleSdk;
+    }
+
+    public void setModuleName(String moduleName) {
+      myModuleName = moduleName;
+    }
+
+    public void setEnvs(Map<String, String> envs) {
+      myEnvs = envs;
+    }
+
+    public void setWorkingDirectory(String workingDirectory) {
+      myWorkingDirectory = workingDirectory;
+    }
+
+    public void setAddContentRoots(boolean addContentRoots) {
+      myAddContentRoots = addContentRoots;
+    }
+
+    public void setAddSourceRoots(boolean addSourceRoots) {
+      myAddSourceRoots = addSourceRoots;
+    }
+
+    public void setMappings(@Nullable PathMappingSettings mappings) {
+      myMappings = mappings != null ? mappings : new PathMappingSettings();
+    }
   }
 }
 
diff --git a/python/src/com/jetbrains/python/console/PydevConsoleCommunication.java b/python/src/com/jetbrains/python/console/PydevConsoleCommunication.java
index b0ef1d3..6af6c13 100644
--- a/python/src/com/jetbrains/python/console/PydevConsoleCommunication.java
+++ b/python/src/com/jetbrains/python/console/PydevConsoleCommunication.java
@@ -53,10 +53,11 @@
  *
  * @author Fabio
  */
-public class PydevConsoleCommunication extends AbstractConsoleCommunication implements IScriptConsoleCommunication, XmlRpcHandler,
+public class PydevConsoleCommunication extends AbstractConsoleCommunication implements XmlRpcHandler,
                                                                                        PyFrameAccessor {
 
   private static final String EXEC_LINE = "execLine";
+  private static final String EXEC_MULTILINE = "execMultipleLines";
   private static final String GET_COMPLETIONS = "getCompletions";
   private static final String GET_DESCRIPTION = "getDescription";
   private static final String GET_FRAME = "getFrame";
@@ -64,6 +65,7 @@
   private static final String CHANGE_VARIABLE = "changeVariable";
   private static final String HANDSHAKE = "handshake";
   private static final String CLOSE = "close";
+
   /**
    * XML-RPC client for sending messages to the server.
    */
@@ -167,7 +169,7 @@
    */
   public Object execute(String method, Vector params) throws Exception {
     if ("NotifyFinished".equals(method)) {
-      return execNotifyFinished();
+      return execNotifyFinished((Boolean)params.get(0));
     }
     else if ("RequestInput".equals(method)) {
       return execRequestInput();
@@ -223,9 +225,9 @@
     return Boolean.FALSE;
   }
 
-  private Object execNotifyFinished() {
+  private Object execNotifyFinished(boolean more) {
     setExecuting(false);
-    notifyCommandExecuted();
+    notifyCommandExecuted(more);
     return true;
   }
 
@@ -261,12 +263,13 @@
   /**
    * Executes the needed command
    *
+   * @param command
    * @return a Pair with (null, more) or (error, false)
    * @throws XmlRpcException
    */
-  protected Pair<String, Boolean> exec(final String command) throws XmlRpcException {
+  protected Pair<String, Boolean> exec(final ConsoleCodeFragment command) throws XmlRpcException {
     setExecuting(true);
-    Object execute = myClient.execute(EXEC_LINE, new Object[]{command});
+    Object execute = myClient.execute(command.isSingleLine() ? EXEC_LINE : EXEC_MULTILINE, new Object[]{command.getText()});
 
     Object object;
     if (execute instanceof Vector) {
@@ -278,6 +281,15 @@
     else {
       object = execute;
     }
+    Pair<String, Boolean> result = parseResult(object);
+    if (result.second) {
+      setExecuting(false);
+    }
+
+    return result;
+  }
+
+  private Pair<String, Boolean> parseResult(Object object) {
     if (object instanceof Boolean) {
       return new Pair<String, Boolean>(null, (Boolean)object);
     }
@@ -314,10 +326,10 @@
    *
    * @param command the command to be executed in the client
    */
-  public void execInterpreter(final String command, final Function<InterpreterResponse, Object> onResponseReceived) {
+  public void execInterpreter(final ConsoleCodeFragment command, final Function<InterpreterResponse, Object> onResponseReceived) {
     nextResponse = null;
     if (waitingForInput) {
-      inputReceived = command;
+      inputReceived = command.getText();
       waitingForInput = false;
       //the thread that we started in the last exec is still alive if we were waiting for an input.
     }
diff --git a/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java b/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java
index 20e8655..3dd6187 100644
--- a/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java
+++ b/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java
@@ -32,6 +32,7 @@
 import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
 import com.intellij.psi.impl.source.codeStyle.IndentHelperImpl;
 import com.intellij.util.Function;
+import com.intellij.util.ui.UIUtil;
 import com.jetbrains.python.PythonFileType;
 import com.jetbrains.python.PythonLanguage;
 import com.jetbrains.python.console.pydev.ConsoleCommunication;
@@ -40,13 +41,10 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.Scanner;
-
 /**
  * @author traff
  */
 public class PydevConsoleExecuteActionHandler extends ConsoleExecuteActionHandler implements ConsoleCommunicationListener {
-
   private final LanguageConsoleView myConsoleView;
 
   private String myInMultilineStringState = null;
@@ -67,19 +65,20 @@
 
   @Override
   public void processLine(final String text) {
-    processLine(text, true);
+    processLine(text, false);
   }
 
-  public void processLine(final String text, boolean execAnyway) {
+  public void processLine(@NotNull final String text, boolean execAnyway) {
     int indentBefore = myCurrentIndentSize;
     if (text.isEmpty()) {
       processOneLine(text);
     }
     else {
-      Scanner s = new Scanner(text);
-      while (s.hasNextLine()) {
-        String line = s.nextLine();
-        processOneLine(line);
+      if (StringUtil.countNewLines(text.trim()) > 0) {
+        executeMultiLine(text);
+      }
+      else {
+        processOneLine(text);
       }
     }
     if (execAnyway && myCurrentIndentSize > 0 && indentBefore == 0) { //if code was indented and we need to exec anyway
@@ -87,6 +86,19 @@
     }
   }
 
+  private void executeMultiLine(@NotNull String text) {
+    if (myInputBuffer == null) {
+      myInputBuffer = new StringBuilder();
+    }
+
+    myInputBuffer.append(text);
+
+    final LanguageConsoleImpl console = myConsoleView.getConsole();
+    final Editor currentEditor = console.getConsoleEditor();
+
+    sendLineToConsole(new ConsoleCommunication.ConsoleCodeFragment(myInputBuffer.toString(), false), console, currentEditor);
+  }
+
   private void processOneLine(String line) {
     int indentSize = IndentHelperImpl.getIndent(getProject(), PythonFileType.INSTANCE, line, false);
     line = StringUtil.trimTrailing(line);
@@ -169,21 +181,27 @@
         indentEditor(currentEditor, indent);
         more(console, currentEditor);
 
+        myConsoleCommunication.notifyCommandExecuted(true);
         return;
       }
     }
 
 
+    sendLineToConsole(new ConsoleCommunication.ConsoleCodeFragment(myInputBuffer.toString(), true), console, currentEditor);
+  }
+
+  private void sendLineToConsole(@NotNull final ConsoleCommunication.ConsoleCodeFragment code,
+                                 @NotNull final LanguageConsoleImpl console,
+                                 @NotNull final Editor currentEditor) {
     if (myConsoleCommunication != null) {
       final boolean waitedForInputBefore = myConsoleCommunication.isWaitingForInput();
-      final String command = myInputBuffer.toString();
       if (myConsoleCommunication.isWaitingForInput()) {
         myInputBuffer.setLength(0);
       }
       else {
         executingPrompt(console);
       }
-      myConsoleCommunication.execInterpreter(command, new Function<InterpreterResponse, Object>() {
+      myConsoleCommunication.execInterpreter(code, new Function<InterpreterResponse, Object>() {
         public Object fun(final InterpreterResponse interpreterResponse) {
           // clear
           myInputBuffer = null;
@@ -192,9 +210,15 @@
             more(console, currentEditor);
             if (myCurrentIndentSize == 0) {
               // compute current indentation
-              setCurrentIndentSize(IndentHelperImpl.getIndent(getProject(), PythonFileType.INSTANCE, line, false) + getPythonIndent());
+              setCurrentIndentSize(
+                IndentHelperImpl.getIndent(getProject(), PythonFileType.INSTANCE, lastLine(code.getText()), false) + getPythonIndent());
               // In this case we can insert indent automatically
-              indentEditor(currentEditor, myCurrentIndentSize);
+              UIUtil.invokeLaterIfNeeded(new Runnable() {
+                @Override
+                public void run() {
+                  indentEditor(currentEditor, myCurrentIndentSize);
+                }
+              });
             }
           }
           else {
@@ -215,6 +239,11 @@
     }
   }
 
+  private static String lastLine(@NotNull String text) {
+    String[] lines = StringUtil.splitByLinesDontTrim(text);
+    return lines[lines.length - 1];
+  }
+
   private void ordinaryPrompt(LanguageConsoleImpl console, Editor currentEditor) {
     if (!myConsoleCommunication.isExecuting()) {
       if (!PyConsoleUtil.ORDINARY_PROMPT.equals(console.getPrompt())) {
@@ -243,10 +272,13 @@
   }
 
   @Override
-  public void commandExecuted() {
-    final LanguageConsoleImpl console = myConsoleView.getConsole();
-    final Editor currentEditor = console.getConsoleEditor();
-    ordinaryPrompt(console, currentEditor);
+  public void commandExecuted(boolean more) {
+    if (!more) {
+      final LanguageConsoleImpl console = myConsoleView.getConsole();
+      final Editor currentEditor = console.getConsoleEditor();
+
+      ordinaryPrompt(console, currentEditor);
+    }
   }
 
   @Override
@@ -335,7 +367,7 @@
   }
 
   @Override
-  public void runExecuteAction(LanguageConsoleImpl languageConsole) {
+  public void runExecuteAction(@NotNull LanguageConsoleImpl languageConsole) {
     if (isEnabled()) {
       if (!canExecuteNow()) {
         HintManager.getInstance().showErrorHint(languageConsole.getConsoleEditor(), getPrevCommandRunningMessage());
diff --git a/python/src/com/jetbrains/python/console/PythonConsoleView.java b/python/src/com/jetbrains/python/console/PythonConsoleView.java
index ddf62ed..27d964a 100644
--- a/python/src/com/jetbrains/python/console/PythonConsoleView.java
+++ b/python/src/com/jetbrains/python/console/PythonConsoleView.java
@@ -152,7 +152,9 @@
 
 
   private void doExecute(String code) {
-    executeInConsole(PyConsoleIndentUtil.normalize(code, myExecuteActionHandler.getCurrentIndentSize()));
+    String codeFragment = PyConsoleIndentUtil.normalize(code, myExecuteActionHandler.getCurrentIndentSize());
+    codeFragment += "\n";
+    executeInConsole(codeFragment);
   }
 
   public void executeInConsole(final String code) {
@@ -383,7 +385,7 @@
     final XStandaloneVariablesView view = new XStandaloneVariablesView(myProject, new PyDebuggerEditorsProvider(), stackFrame);
     consoleCommunication.addCommunicationListener(new ConsoleCommunicationListener() {
       @Override
-      public void commandExecuted() {
+      public void commandExecuted(boolean more) {
         view.rebuildView();
       }
 
diff --git a/python/src/com/jetbrains/python/console/PythonDebugConsoleCommunication.java b/python/src/com/jetbrains/python/console/PythonDebugConsoleCommunication.java
index 8f55aed..d24a2a8a 100644
--- a/python/src/com/jetbrains/python/console/PythonDebugConsoleCommunication.java
+++ b/python/src/com/jetbrains/python/console/PythonDebugConsoleCommunication.java
@@ -63,8 +63,8 @@
     return false;
   }
 
-  protected void exec(final String command, final ProcessDebugger.DebugCallback<Pair<String, Boolean>> callback) {
-    myDebugProcess.consoleExec(command, new ProcessDebugger.DebugCallback<String>() {
+  protected void exec(final ConsoleCodeFragment command, final ProcessDebugger.DebugCallback<Pair<String, Boolean>> callback) {
+    myDebugProcess.consoleExec(command.getText(), new ProcessDebugger.DebugCallback<String>() {
       @Override
       public void ok(String value) {
         callback.ok(parseExecResponseString(value));
@@ -77,9 +77,9 @@
     });
   }
 
-  public void execInterpreter(String s, final Function<InterpreterResponse, Object> callback) {
-    myExpression.append(s);
-    exec(myExpression.toString(), new ProcessDebugger.DebugCallback<Pair<String, Boolean>>() {
+  public void execInterpreter(ConsoleCodeFragment code, final Function<InterpreterResponse, Object> callback) {
+    myExpression.append(code.getText());
+    exec(new ConsoleCodeFragment(myExpression.toString(), false), new ProcessDebugger.DebugCallback<Pair<String, Boolean>>() {
       @Override
       public void ok(Pair<String, Boolean> executed) {
         boolean more = executed.second;
diff --git a/python/src/com/jetbrains/python/inspections/PyMethodMayBeStaticInspection.java b/python/src/com/jetbrains/python/inspections/PyMethodMayBeStaticInspection.java
index 2bc6424..71f2772 100644
--- a/python/src/com/jetbrains/python/inspections/PyMethodMayBeStaticInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyMethodMayBeStaticInspection.java
@@ -70,7 +70,9 @@
       if (!supers.isEmpty()) return;
       final Collection<PyFunction> overrides = PyOverridingMethodsSearch.search(node, true).findAll();
       if (!overrides.isEmpty()) return;
-      if (PyUtil.isDecoratedAsAbstract(node) || node.getModifier() != null) return;
+      final PyDecoratorList decoratorList = node.getDecoratorList();
+      if (decoratorList != null) return;
+      if (node.getModifier() != null) return;
       final Property property = containingClass.findPropertyByCallable(node);
       if (property != null) return;
 
diff --git a/python/src/com/jetbrains/python/parsing/ExpressionParsing.java b/python/src/com/jetbrains/python/parsing/ExpressionParsing.java
index 65c791a..790b155 100644
--- a/python/src/com/jetbrains/python/parsing/ExpressionParsing.java
+++ b/python/src/com/jetbrains/python/parsing/ExpressionParsing.java
@@ -236,7 +236,7 @@
           break;
         }
       }
-      myBuilder.advanceLexer();
+      checkMatches(PyTokenTypes.RBRACE, message("PARSE.expected.rbrace"));
       startMarker.done(PyElementTypes.DICT_LITERAL_EXPRESSION);
     }
   }
@@ -264,7 +264,7 @@
         break;
       }
     }
-    myBuilder.advanceLexer();
+    checkMatches(PyTokenTypes.RBRACE, message("PARSE.expected.rbrace"));
     startMarker.done(PyElementTypes.SET_LITERAL_EXPRESSION);
   }
 
diff --git a/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java
index 7f03dcd..7595fde 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java
@@ -21,7 +21,6 @@
 import com.intellij.lang.injection.InjectedLanguageManager;
 import com.intellij.navigation.ItemPresentation;
 import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
@@ -50,9 +49,21 @@
   public static final Pattern PATTERN_ESCAPE = Pattern
       .compile("\\\\(\n|\\\\|'|\"|a|b|f|n|r|t|v|([0-7]{1,3})|x([0-9a-fA-F]{1,2})" + "|N(\\{.*?\\})|u([0-9a-fA-F]{4})|U([0-9a-fA-F]{8}))");
          //        -> 1                        ->   2      <-->     3          <-     ->   4     <-->    5      <-   ->  6           <-<-
+
+  private enum EscapeRegexGroup {
+    WHOLE_MATCH,
+    ESCAPED_SUBSTRING,
+    OCTAL,
+    HEXADECIMAL,
+    UNICODE_NAMED,
+    UNICODE_16BIT,
+    UNICODE_32BIT
+  }
+
   private static final Map<String, String> escapeMap = initializeEscapeMap();
   private String stringValue;
   private List<TextRange> valueTextRanges;
+  @Nullable private List<Pair<TextRange, String>> myDecodedFragments;
   private final DefaultRegExpPropertiesProvider myPropertiesProvider;
 
   private static Map<String, String> initializeEscapeMap() {
@@ -85,6 +96,7 @@
     super.subtreeChanged();
     stringValue = null;
     valueTextRanges = null;
+    myDecodedFragments = null;
   }
 
   public List<TextRange> getStringValueTextRanges() {
@@ -143,20 +155,82 @@
     return text.length() > 0 && Character.toUpperCase(text.charAt(0)) == 'C';
   }
 
-  public void iterateCharacterRanges(TextRangeConsumer consumer) {
-    int elStart = getTextRange().getStartOffset();
-    for (ASTNode child : getStringNodes()) {
-      final String text = child.getText();
-      TextRange textRange = getNodeTextRange(text);
-      int offset = child.getTextRange().getStartOffset() - elStart + textRange.getStartOffset();
-      String undecoded = textRange.substring(text);
-      if (!iterateCharacterRanges(consumer, undecoded, offset, isRaw(text), isUnicode(text))) {
-        break;
+  @Override
+  @NotNull
+  public List<Pair<TextRange, String>> getDecodedFragments() {
+    if (myDecodedFragments == null) {
+      final List<Pair<TextRange, String>> result = new ArrayList<Pair<TextRange, String>>();
+      final int elementStart = getTextRange().getStartOffset();
+      for (ASTNode node : getStringNodes()) {
+        final String text = node.getText();
+        final TextRange textRange = getNodeTextRange(text);
+        final int offset = node.getTextRange().getStartOffset() - elementStart + textRange.getStartOffset();
+        final String encoded = textRange.substring(text);
+        result.addAll(getDecodedFragments(encoded, offset, isRaw(text), isUnicode(text)));
       }
+      myDecodedFragments = result;
     }
+    return myDecodedFragments;
   }
 
+  @NotNull
+  private static List<Pair<TextRange, String>> getDecodedFragments(@NotNull String encoded, int offset, boolean raw, boolean unicode) {
+    final List<Pair<TextRange, String>> result = new ArrayList<Pair<TextRange, String>>();
+    final Matcher escMatcher = PATTERN_ESCAPE.matcher(encoded);
+    int index = 0;
+    while (escMatcher.find(index)) {
+      if (index < escMatcher.start()) {
+        final TextRange range = TextRange.create(index, escMatcher.start());
+        final TextRange offsetRange = range.shiftRight(offset);
+        result.add(Pair.create(offsetRange, range.substring(encoded)));
+      }
 
+      final String octal = escapeRegexGroup(escMatcher, EscapeRegexGroup.OCTAL);
+      final String hex = escapeRegexGroup(escMatcher, EscapeRegexGroup.HEXADECIMAL);
+      // TODO: Implement unicode character name escapes: EscapeRegexGroup.UNICODE_NAMED
+      final String unicode16 = escapeRegexGroup(escMatcher, EscapeRegexGroup.UNICODE_16BIT);
+      final String unicode32 = escapeRegexGroup(escMatcher, EscapeRegexGroup.UNICODE_32BIT);
+
+      final boolean escapedUnicode = raw && unicode || !raw;
+
+      final String str;
+      if (!raw && octal != null) {
+        str = new String(new char[]{(char)Integer.parseInt(octal, 8)});
+      }
+      else if (!raw && hex != null) {
+        str = new String(new char[]{(char)Integer.parseInt(hex, 16)});
+      }
+      else if (escapedUnicode && unicode16 != null) {
+        str = unicode ? new String(new char[]{(char)Integer.parseInt(unicode16, 16)}) : unicode16;
+      }
+      else if (escapedUnicode && unicode32 != null) {
+        str = unicode ? new String(Character.toChars((int)Long.parseLong(unicode32, 16))) : unicode32;
+      }
+      else if (raw) {
+        str = escapeRegexGroup(escMatcher, EscapeRegexGroup.WHOLE_MATCH);
+      }
+      else {
+        final String toReplace = escapeRegexGroup(escMatcher, EscapeRegexGroup.ESCAPED_SUBSTRING);
+        str = escapeMap.get(toReplace);
+      }
+
+      if (str != null) {
+        final TextRange wholeMatch = TextRange.create(escMatcher.start(), escMatcher.end());
+        result.add(Pair.create(wholeMatch.shiftRight(offset), str));
+      }
+
+      index = escMatcher.end();
+    }
+    final TextRange range = TextRange.create(index, encoded.length());
+    final TextRange offRange = range.shiftRight(offset);
+    result.add(Pair.create(offRange, range.substring(encoded)));
+    return result;
+  }
+
+  @Nullable
+  private static String escapeRegexGroup(@NotNull Matcher matcher, EscapeRegexGroup group) {
+    return matcher.group(group.ordinal());
+  }
 
   public List<ASTNode> getStringNodes() {
     return Arrays.asList(getNode().getChildren(PyTokenTypes.STRING_NODES));
@@ -165,14 +239,11 @@
   public String getStringValue() {
     //ASTNode child = getNode().getFirstChildNode();
     //assert child != null;
-   if (stringValue == null) {
+    if (stringValue == null) {
       final StringBuilder out = new StringBuilder();
-      iterateCharacterRanges(new TextRangeConsumer() {
-        public boolean process(int startOffset, int endOffset, String value) {
-          out.append(value);
-          return true;
-        }
-      });
+      for (Pair<TextRange, String> fragment : getDecodedFragments()) {
+        out.append(fragment.getSecond());
+      }
       stringValue = out.toString();
     }
     return stringValue;
@@ -190,106 +261,6 @@
     return new TextRange(0, getTextLength());
   }
 
-  private static boolean iterateCharacterRanges(TextRangeConsumer consumer, String undecoded, int off, boolean raw, boolean unicode) {
-    if (raw) {
-      return iterateRawCharacterRanges(consumer, undecoded, off, unicode);
-    }
-    Matcher escMatcher = PATTERN_ESCAPE.matcher(undecoded);
-    int index = 0;
-    while (escMatcher.find(index)) {
-      for (int i = index; i < escMatcher.start(); i++) {
-        if (!consumer.process(off + i, off + i + 1, Character.toString(undecoded.charAt(i)))) {
-          return false;
-        }
-      }
-      String octal = escMatcher.group(2);
-      String hex = escMatcher.group(3);
-      String str = null;
-      if (octal != null) {
-        str = new String(new char[]{(char)Integer.parseInt(octal, 8)});
-
-      }
-      else if (hex != null) {
-        str = new String(new char[]{(char)Integer.parseInt(hex, 16)});
-
-      }
-      else {
-        String toReplace = escMatcher.group(1);
-        String replacement = escapeMap.get(toReplace);
-        if (replacement != null) {
-          str = replacement;
-        }
-      }
-      String unicodeName = escMatcher.group(4);
-      String unicode32 = escMatcher.group(6);
-
-      if (unicode32 != null) {
-        str = unicode ? new String(Character.toChars((int)Long.parseLong(unicode32, 16))) : unicode32;
-      }
-      if (unicodeName != null) {
-        //TOLATER: implement unicode character name escapes
-      }
-      String unicode16 = escMatcher.group(5);
-      if (unicode16 != null) {
-        str = unicode ? new String(new char[]{(char)Integer.parseInt(unicode16, 16)}) : unicode16;
-      }
-
-      if (str != null) {
-        int start = escMatcher.start();
-        int end = escMatcher.end();
-        if (!consumer.process(off + start, off + end, str)) {
-          return false;
-        }
-      }
-      index = escMatcher.end();
-    }
-    for (int i = index; i < undecoded.length(); i++) {
-      if (!consumer.process(off + i, off + i + 1, Character.toString(undecoded.charAt(i)))) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  private static boolean iterateRawCharacterRanges(TextRangeConsumer consumer, String undecoded, int off, boolean unicode) {
-    for (int i = 0; i < undecoded.length(); i++) {
-      char c = undecoded.charAt(i);
-      if (unicode && c == '\\' && i < undecoded.length()-1) {
-        char c2 = undecoded.charAt(i+1);
-        if (c2 == 'u' && i < undecoded.length()-5) {
-          try {
-            char u = (char) Integer.parseInt(undecoded.substring(i+2, i+6), 16);
-            if (!consumer.process(off+i, off+i+ 6, Character.toString(u))) {
-              return false;
-            }
-          }
-          catch (NumberFormatException ignore) { }
-          //noinspection AssignmentToForLoopParameter
-          i += 5;
-          continue;
-        }
-        if (c2 == 'U' && i < undecoded.length()-9) {
-          // note: Java has 16-bit chars, so this code will truncate characters which don't fit in 16 bits
-          try {
-            char u = (char) Long.parseLong(undecoded.substring(i+2, i+10), 16);
-            if (!consumer.process(off+i, off+i+10, Character.toString(u))) {
-              return false;
-            }
-          }
-          catch (NumberFormatException ignore) { }
-          //noinspection AssignmentToForLoopParameter
-          i += 9;
-          continue;
-        }
-      }
-      if (!consumer.process(off + i, off + i + 1, Character.toString(c))) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
   @Override
   public String toString() {
     return super.toString() + ": " + getStringValue();
@@ -368,57 +339,60 @@
 
     @Override
     public boolean decode(@NotNull final TextRange rangeInsideHost, @NotNull final StringBuilder outChars) {
-      final PyDocStringOwner
-        docStringOwner = PsiTreeUtil.getParentOfType(myHost, PyDocStringOwner.class);
-      if (docStringOwner != null && myHost.equals(docStringOwner.getDocStringExpression())) {
-        outChars.append(myHost.getText(), rangeInsideHost.getStartOffset(), rangeInsideHost.getEndOffset());
-      }
-      else {
-        myHost.iterateCharacterRanges(new TextRangeConsumer() {
-          public boolean process(int startOffset, int endOffset, String value) {
-            int xsectStart = Math.max(startOffset, rangeInsideHost.getStartOffset());
-            int xsectEnd = Math.min(endOffset, rangeInsideHost.getEndOffset());
-            if (xsectEnd > xsectStart) {
-              outChars.append(value);
-            }
-            return endOffset < rangeInsideHost.getEndOffset();
+      for (Pair<TextRange, String> fragment : myHost.getDecodedFragments()) {
+        final TextRange encodedTextRange = fragment.getFirst();
+        final TextRange intersection = encodedTextRange.intersection(rangeInsideHost);
+        if (intersection != null && !intersection.isEmpty()) {
+          final String value = fragment.getSecond();
+          final String intersectedValue;
+          if (value.length() == 1 || value.length() == intersection.getLength()) {
+            intersectedValue = value;
           }
-        });
+          else {
+            final int start = Math.max(0, rangeInsideHost.getStartOffset() - encodedTextRange.getStartOffset());
+            final int end = Math.min(value.length(), start + intersection.getLength());
+            intersectedValue = value.substring(start, end);
+          }
+          outChars.append(intersectedValue);
+        }
       }
       return true;
     }
 
     @Override
     public int getOffsetInHost(final int offsetInDecoded, @NotNull final TextRange rangeInsideHost) {
-      final Ref<Integer> resultRef = Ref.create(-1);
-      final Ref<Integer> indexRef = Ref.create(0);
-      final Ref<Integer> lastEndOffsetRef = Ref.create(-1);
-      myHost.iterateCharacterRanges(new TextRangeConsumer() {
-        @Override
-        public boolean process(int startOffset, int endOffset, String value) {
-          if (startOffset > rangeInsideHost.getEndOffset()) {
-            return false;
+      int offset = 0;
+      int endOffset = -1;
+      for (Pair<TextRange, String> fragment : myHost.getDecodedFragments()) {
+        final TextRange encodedTextRange = fragment.getFirst();
+        final TextRange intersection = encodedTextRange.intersection(rangeInsideHost);
+        if (intersection != null && !intersection.isEmpty()) {
+          final String value = fragment.getSecond();
+          final int valueLength = value.length();
+          final int intersectionLength = intersection.getLength();
+          if (valueLength == 0) {
+            return -1;
           }
-          lastEndOffsetRef.set(endOffset);
-          if (startOffset >= rangeInsideHost.getStartOffset()) {
-            final int i = indexRef.get();
-            if (i == offsetInDecoded) {
-              resultRef.set(startOffset);
-              return false;
+          else if (valueLength == 1) {
+            if (offset == offsetInDecoded) {
+              return intersection.getStartOffset();
             }
-            indexRef.set(i + 1);
+            offset++;
           }
-          return true;
+          else {
+            if (offset + intersectionLength >= offsetInDecoded) {
+              final int delta = offsetInDecoded - offset;
+              return intersection.getStartOffset() + delta;
+            }
+            offset += intersectionLength;
+          }
+          endOffset = intersection.getEndOffset();
         }
-      });
-      final int result = resultRef.get();
-      if (result != -1) {
-        return result;
       }
-      // We should handle the position of a character at the end of rangeInsideHost, because LeafPatcher expects it to be valid
-      final int lastEndOffset = lastEndOffsetRef.get();
-      if (indexRef.get() == offsetInDecoded && lastEndOffset == rangeInsideHost.getEndOffset()) {
-        return lastEndOffset;
+      // XXX: According to the real use of getOffsetInHost() it should return the correct host offset for the offset in decoded at the
+      // end of the range inside host, not -1
+      if (offset == offsetInDecoded) {
+        return endOffset;
       }
       return -1;
     }
@@ -431,23 +405,7 @@
 
   @Override
   public int valueOffsetToTextOffset(int valueOffset) {
-    final Ref<Integer> offsetInDecodedRef = new Ref<Integer>(valueOffset);
-    final Ref<Integer> result = new Ref<Integer>(-1);
-    iterateCharacterRanges(new TextRangeConsumer() {
-      public boolean process(int startOffset, int endOffset, String value) {
-        if (value.length() > offsetInDecodedRef.get()) {
-          result.set(startOffset + offsetInDecodedRef.get());
-          return false;
-        }
-        offsetInDecodedRef.set(offsetInDecodedRef.get() - value.length());
-        if (offsetInDecodedRef.get() == 0) {
-          result.set(endOffset);
-          return false;
-        }
-        return true;
-      }
-    });
-    return result.get();
+    return createLiteralTextEscaper().getOffsetInHost(valueOffset, getStringValueTextRange());
   }
 
   public boolean characterNeedsEscaping(char c) {
diff --git a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java
index 57fe1a6..6a80851 100644
--- a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java
+++ b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java
@@ -15,6 +15,7 @@
  */
 package com.jetbrains.python.psi.resolve;
 
+import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.module.ModuleUtilCore;
 import com.intellij.openapi.projectRoots.Sdk;
@@ -366,6 +367,9 @@
           if (vFile != null && vFile.getLength() > 0) {
             rate += 100;
           }
+          for (PyResolveResultRater rater : Extensions.getExtensions(PyResolveResultRater.EP_NAME)) {
+            rate += rater.getRate(target);
+          }
         }
         ret.poke(target, rate);
       }
diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java
index f5ba918..9b11d15 100644
--- a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java
+++ b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java
@@ -25,16 +25,15 @@
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtilBase;
 import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.psi.util.QualifiedName;
 import com.jetbrains.python.PyNames;
 import com.jetbrains.python.PythonFileType;
 import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
 import com.jetbrains.python.codeInsight.imports.AddImportHelper;
-import com.jetbrains.python.documentation.DocStringTypeReference;
 import com.jetbrains.python.psi.*;
 import com.jetbrains.python.psi.impl.PyBuiltinCache;
 import com.jetbrains.python.psi.impl.PyImportedModule;
 import com.jetbrains.python.psi.impl.PyPsiUtils;
-import com.intellij.psi.util.QualifiedName;
 import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -190,7 +189,7 @@
       public void visitPyStringLiteralExpression(PyStringLiteralExpression node) {
         super.visitPyStringLiteralExpression(node);
         for (PsiReference ref : node.getReferences()) {
-          if (ref instanceof DocStringTypeReference && ref.isReferenceTo(oldElement)) {
+          if (ref.isReferenceTo(oldElement)) {
             ref.bindToElement(newElement);
           }
         }
diff --git a/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionProcessor.java b/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionProcessor.java
index fe4da8e..5c22514 100644
--- a/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionProcessor.java
+++ b/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionProcessor.java
@@ -23,6 +23,7 @@
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.psi.util.QualifiedName;
 import com.intellij.refactoring.BaseRefactoringProcessor;
 import com.intellij.refactoring.ui.UsageViewDescriptorAdapter;
 import com.intellij.refactoring.util.CommonRefactoringUtil;
@@ -33,9 +34,7 @@
 import com.jetbrains.python.PyNames;
 import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
 import com.jetbrains.python.codeInsight.imports.PyImportOptimizer;
-import com.jetbrains.python.documentation.DocStringTypeReference;
 import com.jetbrains.python.psi.*;
-import com.intellij.psi.util.QualifiedName;
 import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
 import com.jetbrains.python.refactoring.PyRefactoringUtil;
 import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil;
@@ -193,7 +192,7 @@
     }
     if (usage instanceof PyStringLiteralExpression) {
       for (PsiReference ref : usage.getReferences()) {
-        if (ref instanceof DocStringTypeReference && ref.isReferenceTo(oldElement)) {
+        if (ref.isReferenceTo(oldElement)) {
           ref.bindToElement(newElement);
         }
       }
diff --git a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryExceptSurrounder.java b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryExceptSurrounder.java
index 5cdaba2..25a9f26 100644
--- a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryExceptSurrounder.java
+++ b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryExceptSurrounder.java
@@ -22,7 +22,6 @@
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
-import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.jetbrains.python.PyBundle;
@@ -53,9 +52,10 @@
 
     final PsiFile psiFile = parent.getContainingFile();
     final Document document = psiFile.getViewProvider().getDocument();
-    final RangeMarker rangeMarker = document.createRangeMarker(tryStatement.getTextRange());
+    final TextRange range = tryStatement.getTextRange();
+    assert document != null;
+    final RangeMarker rangeMarker = document.createRangeMarker(range);
 
-    CodeStyleManager.getInstance(project).reformat(psiFile);
     final PsiElement element = psiFile.findElementAt(rangeMarker.getStartOffset());
     tryStatement = PsiTreeUtil.getParentOfType(element, PyTryExceptStatement.class);
     if (tryStatement != null) {
@@ -70,7 +70,9 @@
 
   protected TextRange getResultRange(PyTryExceptStatement tryStatement) {
     final PyExceptPart part = tryStatement.getExceptParts()[0];
-    return part.getStatementList().getTextRange();
+    final PyStatementList list = part.getStatementList();
+    assert list != null;
+    return list.getTextRange();
   }
 
   public String getTemplateDescription() {
diff --git a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryFinallySurrounder.java b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryFinallySurrounder.java
index 54e2c27..d457e32 100644
--- a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryFinallySurrounder.java
+++ b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryFinallySurrounder.java
@@ -17,6 +17,8 @@
 
 import com.intellij.codeInsight.CodeInsightBundle;
 import com.intellij.openapi.util.TextRange;
+import com.jetbrains.python.psi.PyFinallyPart;
+import com.jetbrains.python.psi.PyStatementList;
 import com.jetbrains.python.psi.PyTryExceptStatement;
 
 /**
@@ -37,6 +39,10 @@
 
   @Override
   protected TextRange getResultRange(PyTryExceptStatement tryStatement) {
-    return tryStatement.getFinallyPart().getStatementList().getTextRange();
+    final PyFinallyPart finallyPart = tryStatement.getFinallyPart();
+    assert finallyPart != null;
+    final PyStatementList statementList = finallyPart.getStatementList();
+    assert statementList != null;
+    return statementList.getTextRange();
   }
 }
diff --git a/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java b/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java
index 5fc0bc8..ba272c6 100644
--- a/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java
+++ b/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java
@@ -23,7 +23,6 @@
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.ui.Messages;
 import com.intellij.util.PathMappingSettings;
 import com.jetbrains.python.remote.PyRemoteSdkData;
 import com.jetbrains.python.remote.PythonRemoteInterpreterManager;
@@ -43,21 +42,15 @@
     if (manager != null) {
       ProcessHandler processHandler;
 
-      while (true) {
-        try {
-          processHandler = doStartRemoteProcess(sdk, commandLine, manager, project, mappingSettings);
-          break;
+      try {
+        processHandler = doStartRemoteProcess(sdk, commandLine, manager, project, mappingSettings);
+      }
+      catch (ExecutionException e) {
+        final Application application = ApplicationManager.getApplication();
+        if (application != null && (application.isUnitTestMode() || application.isHeadlessEnvironment())) {
+          throw new RuntimeException(e);
         }
-        catch (ExecutionException e) {
-          final Application application = ApplicationManager.getApplication();
-          if (application != null && (application.isUnitTestMode() || application.isHeadlessEnvironment())) {
-            throw new RuntimeException(e);
-          }
-          if (Messages.showYesNoDialog(e.getMessage() + "\nTry again?", "Can't Run Remote Interpreter", Messages.getErrorIcon()) ==
-              Messages.NO) {
-            throw new ExecutionException("Can't run remote python interpreter: " + e.getMessage(), e);
-          }
-        }
+        throw new ExecutionException("Can't run remote python interpreter: " + e.getMessage(), e);
       }
       ProcessTerminatedListener.attach(processHandler);
       return processHandler;
diff --git a/python/src/com/jetbrains/python/spellchecker/PythonSpellcheckerStrategy.java b/python/src/com/jetbrains/python/spellchecker/PythonSpellcheckerStrategy.java
index 4a0a59d..b24e53c 100644
--- a/python/src/com/jetbrains/python/spellchecker/PythonSpellcheckerStrategy.java
+++ b/python/src/com/jetbrains/python/spellchecker/PythonSpellcheckerStrategy.java
@@ -15,6 +15,7 @@
  */
 package com.jetbrains.python.spellchecker;
 
+import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.PsiElement;
 import com.intellij.spellchecker.inspections.PlainTextSplitter;
@@ -26,7 +27,6 @@
 import com.jetbrains.python.inspections.PyStringFormatParser;
 import com.jetbrains.python.psi.PyBinaryExpression;
 import com.jetbrains.python.psi.PyStringLiteralExpression;
-import com.jetbrains.python.psi.impl.PyStringLiteralExpressionImpl;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
@@ -41,9 +41,11 @@
       Splitter splitter = PlainTextSplitter.getInstance();
       String text = element.getText();
       if (text.indexOf('\\') >= 0) {
-        MyTextRangeConsumer textRangeConsumer = new MyTextRangeConsumer(element, consumer);
-        ((PyStringLiteralExpressionImpl) element).iterateCharacterRanges(textRangeConsumer);
-        textRangeConsumer.processCurrentToken();   // process last token
+        for (Pair<TextRange, String> fragment : element.getDecodedFragments()) {
+          final String value = fragment.getSecond();
+          consumer.consumeToken(element, value, false, fragment.getFirst().getStartOffset(), TextRange.allOf(value),
+                                PlainTextSplitter.getInstance());
+        }
       }
       else if (text.startsWith("u") || text.startsWith("U") || text.startsWith("r") || text.startsWith("R") ||
           text.startsWith("b") || text.startsWith("B")) {
@@ -57,40 +59,6 @@
         consumer.consumeToken(element, splitter);
       }
     }
-
-    private static class MyTextRangeConsumer implements PyStringLiteralExpressionImpl.TextRangeConsumer {
-      private final StringBuilder myCurrentToken = new StringBuilder();
-      private final PyStringLiteralExpression myElement;
-      private final TokenConsumer myTokenConsumer;
-      private int myTokenStart;
-
-      public MyTextRangeConsumer(PyStringLiteralExpression element, TokenConsumer tokenConsumer) {
-        myElement = element;
-        myTokenConsumer = tokenConsumer;
-      }
-
-      @Override
-      public boolean process(int startOffset, int endOffset, String value) {
-        if (endOffset == startOffset + 1) {
-          if (myCurrentToken.length() == 0) {
-            myTokenStart = startOffset;
-          }
-          myCurrentToken.append(value);
-        }
-        else {
-          if (myCurrentToken.length() > 0) {
-            processCurrentToken();
-            myCurrentToken.setLength(0);
-          }
-        }
-        return true;
-      }
-
-      private void processCurrentToken() {
-        String token = myCurrentToken.toString();
-        myTokenConsumer.consumeToken(myElement, token, false, myTokenStart, TextRange.allOf(token), PlainTextSplitter.getInstance());
-      }
-    }
   }
 
   private static class FormatStringTokenizer extends Tokenizer<PyStringLiteralExpression> {
diff --git a/python/src/com/jetbrains/python/testing/PythonTestCommandLineStateBase.java b/python/src/com/jetbrains/python/testing/PythonTestCommandLineStateBase.java
index ef16a65..39e4e96 100644
--- a/python/src/com/jetbrains/python/testing/PythonTestCommandLineStateBase.java
+++ b/python/src/com/jetbrains/python/testing/PythonTestCommandLineStateBase.java
@@ -106,9 +106,10 @@
     return cmd;
   }
 
-  private void setWorkingDirectory(@NotNull final GeneralCommandLine cmd) {
-    if (!StringUtil.isEmptyOrSpaces(myConfiguration.getWorkingDirectory())) {
-      cmd.setWorkDirectory(myConfiguration.getWorkingDirectory());
+  protected void setWorkingDirectory(@NotNull final GeneralCommandLine cmd) {
+    final String workingDirectory = myConfiguration.getWorkingDirectory();
+    if (!StringUtil.isEmptyOrSpaces(workingDirectory)) {
+      cmd.setWorkDirectory(workingDirectory);
     }
     else if (myConfiguration instanceof AbstractPythonTestRunConfiguration) {
       final String folderName = ((AbstractPythonTestRunConfiguration)myConfiguration).getFolderName();
diff --git a/python/src/com/jetbrains/python/testing/PythonTestConfigurationProducer.java b/python/src/com/jetbrains/python/testing/PythonTestConfigurationProducer.java
index 3875cd3..8c28e08 100644
--- a/python/src/com/jetbrains/python/testing/PythonTestConfigurationProducer.java
+++ b/python/src/com/jetbrains/python/testing/PythonTestConfigurationProducer.java
@@ -18,6 +18,7 @@
 import com.google.common.collect.Sets;
 import com.intellij.execution.Location;
 import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.actions.ConfigurationFromContext;
 import com.intellij.execution.actions.RunConfigurationProducer;
 import com.intellij.execution.configurations.ConfigurationFactory;
 import com.intellij.facet.Facet;
@@ -39,6 +40,7 @@
 import com.jetbrains.python.PythonModuleTypeBase;
 import com.jetbrains.python.facet.PythonFacetSettings;
 import com.jetbrains.python.psi.*;
+import com.jetbrains.python.run.PythonRunConfigurationProducer;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -254,4 +256,8 @@
     return PythonUnitTestUtil.getTestCaseClassesFromFile(pyFile);
   }
 
+  @Override
+  public boolean isPreferredConfiguration(ConfigurationFromContext self, ConfigurationFromContext other) {
+    return other.isProducedBy(PythonTestConfigurationProducer.class) || other.isProducedBy(PythonRunConfigurationProducer.class);
+  }
 }
\ No newline at end of file
diff --git a/python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java b/python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java
index d0b4ea1..9394143 100644
--- a/python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java
+++ b/python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java
@@ -93,7 +93,7 @@
       }
     }
     for (PyFunction cls : file.getTopLevelFunctions()) {
-      if (isTestCaseFunction(cls)) {
+      if (isTestCaseFunction(cls, false)) {
         result.add(cls);
       }
     }
@@ -115,9 +115,9 @@
     }
     if (checkAssert) {
       boolean hasAssert = hasAssertOrYield(function.getStatementList());
-      if (!hasAssert) return false;
+      if (hasAssert) return true;
     }
-    return true;
+    return false;
   }
 
   private static boolean hasAssertOrYield(PyStatementList list) {
diff --git a/python/src/com/jetbrains/python/testing/doctest/PythonDocTestConfigurationProducer.java b/python/src/com/jetbrains/python/testing/doctest/PythonDocTestConfigurationProducer.java
index cfa2be7..e3eef29 100644
--- a/python/src/com/jetbrains/python/testing/doctest/PythonDocTestConfigurationProducer.java
+++ b/python/src/com/jetbrains/python/testing/doctest/PythonDocTestConfigurationProducer.java
@@ -21,6 +21,8 @@
 
 import com.intellij.execution.Location;
 import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.PsiRecursiveElementVisitor;
@@ -85,4 +87,10 @@
       }
     }
   }
+
+  @Override
+  protected boolean isTestFolder(@NotNull VirtualFile virtualFile, @NotNull Project project) {
+    return false;
+  }
+
 }
\ No newline at end of file
diff --git a/python/src/com/jetbrains/python/testing/pytest/PyTestRunnableScriptFilter.java b/python/src/com/jetbrains/python/testing/pytest/PyTestRunnableScriptFilter.java
deleted file mode 100644
index 036663b..0000000
--- a/python/src/com/jetbrains/python/testing/pytest/PyTestRunnableScriptFilter.java
+++ /dev/null
@@ -1,83 +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.jetbrains.python.testing.pytest;
-
-import com.intellij.execution.Location;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.psi.PsiFile;
-import com.jetbrains.python.psi.PyClass;
-import com.jetbrains.python.psi.PyFile;
-import com.jetbrains.python.psi.PyFunction;
-import com.jetbrains.python.psi.PyRecursiveElementVisitor;
-import com.jetbrains.python.run.RunnableScriptFilter;
-import com.jetbrains.python.sdk.PythonSdkType;
-import com.jetbrains.python.testing.PythonTestConfigurationsModel;
-import com.jetbrains.python.testing.TestRunnerService;
-import com.jetbrains.python.testing.VFSTestFrameworkListener;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author yole
- */
-public class PyTestRunnableScriptFilter implements RunnableScriptFilter {
-  public boolean isRunnableScript(PsiFile script, @NotNull Module module, Location location) {
-    return isPyTestInstalled(module) && isPyTestScript(script) &&
-      TestRunnerService.getInstance(module).getProjectConfiguration().
-        equals(PythonTestConfigurationsModel.PY_TEST_NAME);
-  }
-
-  private static boolean isPyTestInstalled(Module module) {
-    // TODO[yole] add caching to avoid disk I/O in findPyTestRunner()?
-    final Sdk sdk = PythonSdkType.findPythonSdk(module);
-    return sdk != null && VFSTestFrameworkListener.getInstance().isPyTestInstalled(sdk);
-  }
-
-  public static boolean isPyTestScript(PsiFile script) {
-    if (!(script instanceof PyFile)) {
-      return false;
-    }
-    PyTestVisitor testVisitor = new PyTestVisitor();
-    script.accept(testVisitor);
-    return testVisitor.isTestsFound();
-  }
-
-  private static class PyTestVisitor extends PyRecursiveElementVisitor {
-    private boolean myTestsFound = false;
-
-    public boolean isTestsFound() {
-      return myTestsFound;
-    }
-
-    @Override
-    public void visitPyFunction(PyFunction node) {
-      super.visitPyFunction(node);
-      String name = node.getName();
-      if (name != null && name.startsWith("test")) {
-        myTestsFound = true;
-      }
-    }
-
-    @Override
-    public void visitPyClass(PyClass node) {
-      super.visitPyClass(node);
-      String name = node.getName();
-      if (name != null && name.startsWith("Test")) {
-        myTestsFound = true;
-      }
-    }
-  }
-}
diff --git a/python/testData/completion/epydocParamTag.py b/python/testData/completion/epydocParamTag.py
index 6323111..e74df8d 100644
--- a/python/testData/completion/epydocParamTag.py
+++ b/python/testData/completion/epydocParamTag.py
@@ -1,2 +1,2 @@
 def foo(bar):
-    """ @param <caret> """
\ No newline at end of file
+    """ @param b<caret> """
\ No newline at end of file
diff --git a/python/testData/completion/identifiersInPlainDocstring.after.py b/python/testData/completion/identifiersInPlainDocstring.after.py
deleted file mode 100644
index 440570b..0000000
--- a/python/testData/completion/identifiersInPlainDocstring.after.py
+++ /dev/null
@@ -1,2 +0,0 @@
-def foo(bar):
-    """ Variable bar """
\ No newline at end of file
diff --git a/python/testData/inspections/PyMethodMayBeStaticInspection/decorated.py b/python/testData/inspections/PyMethodMayBeStaticInspection/decorated.py
new file mode 100644
index 0000000..c16da1e
--- /dev/null
+++ b/python/testData/inspections/PyMethodMayBeStaticInspection/decorated.py
@@ -0,0 +1,15 @@
+def bar(f):
+    def wrapper(self, *args, **kwargs):
+        print('running {cls}.{method}'.format(cls=type(self).__name__,
+                                              method=f.__name__))
+        return f(self, *args, **kwargs)
+    return wrapper
+
+
+class C(object):
+    @bar
+    def foo(self):  # False positive: self is used by @bar
+        return 'foo'
+
+
+C().foo()
\ No newline at end of file
diff --git a/python/testData/inspections/spelling/ignoreEscapeSequence.py b/python/testData/inspections/spelling/ignoreEscapeSequence.py
index 3bd9965..95e8df4 100644
--- a/python/testData/inspections/spelling/ignoreEscapeSequence.py
+++ b/python/testData/inspections/spelling/ignoreEscapeSequence.py
@@ -1 +1,2 @@
-print "foo\nsomething"
\ No newline at end of file
+print "foo\nsomething"
+print """foo\n<TYPO descr="Typo: In word 'brbrbr'">brbrbr</TYPO>"""
diff --git a/python/testData/psi/NotClosedBraceDict.py b/python/testData/psi/NotClosedBraceDict.py
new file mode 100644
index 0000000..9a72624
--- /dev/null
+++ b/python/testData/psi/NotClosedBraceDict.py
@@ -0,0 +1,3 @@
+a = {
+        'b': 'c',
+    ]
\ No newline at end of file
diff --git a/python/testData/psi/NotClosedBraceDict.txt b/python/testData/psi/NotClosedBraceDict.txt
new file mode 100644
index 0000000..1222ea3
--- /dev/null
+++ b/python/testData/psi/NotClosedBraceDict.txt
@@ -0,0 +1,24 @@
+PyFile:NotClosedBraceDict.py
+  PyAssignmentStatement
+    PyTargetExpression: a
+      PsiElement(Py:IDENTIFIER)('a')
+    PsiWhiteSpace(' ')
+    PsiElement(Py:EQ)('=')
+    PsiWhiteSpace(' ')
+    PyDictLiteralExpression
+      PsiElement(Py:LBRACE)('{')
+      PsiWhiteSpace('\n        ')
+      PyKeyValueExpression
+        PyStringLiteralExpression: b
+          PsiElement(Py:SINGLE_QUOTED_STRING)(''b'')
+        PsiElement(Py:COLON)(':')
+        PsiWhiteSpace(' ')
+        PyStringLiteralExpression: c
+          PsiElement(Py:SINGLE_QUOTED_STRING)(''c'')
+      PsiElement(Py:COMMA)(',')
+      PsiErrorElement:'}' expected
+        <empty list>
+  PsiWhiteSpace('\n    ')
+  PsiElement(Py:RBRACKET)(']')
+  PsiErrorElement:Statement expected, found Py:RBRACKET
+    <empty list>
\ No newline at end of file
diff --git a/python/testData/psi/NotClosedBraceSet.py b/python/testData/psi/NotClosedBraceSet.py
new file mode 100644
index 0000000..71817f2
--- /dev/null
+++ b/python/testData/psi/NotClosedBraceSet.py
@@ -0,0 +1 @@
+a = {'b',]
\ No newline at end of file
diff --git a/python/testData/psi/NotClosedBraceSet.txt b/python/testData/psi/NotClosedBraceSet.txt
new file mode 100644
index 0000000..95b97f0
--- /dev/null
+++ b/python/testData/psi/NotClosedBraceSet.txt
@@ -0,0 +1,17 @@
+PyFile:NotClosedBraceSet.py
+  PyAssignmentStatement
+    PyTargetExpression: a
+      PsiElement(Py:IDENTIFIER)('a')
+    PsiWhiteSpace(' ')
+    PsiElement(Py:EQ)('=')
+    PsiWhiteSpace(' ')
+    PySetLiteralExpression
+      PsiElement(Py:LBRACE)('{')
+      PyStringLiteralExpression: b
+        PsiElement(Py:SINGLE_QUOTED_STRING)(''b'')
+      PsiElement(Py:COMMA)(',')
+      PsiErrorElement:'}' expected
+        <empty list>
+  PsiElement(Py:RBRACKET)(']')
+  PsiErrorElement:Statement expected, found Py:RBRACKET
+    <empty list>
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyMakeMethodStaticQuickFixTest/decoWithParams.py b/python/testData/quickFixes/PyMakeMethodStaticQuickFixTest/decoWithParams.py
deleted file mode 100644
index 7cdd655..0000000
--- a/python/testData/quickFixes/PyMakeMethodStaticQuickFixTest/decoWithParams.py
+++ /dev/null
@@ -1,10 +0,0 @@
-__author__ = 'ktisha'
-
-def foo(x):
-  return x
-
-class A():
-
-    @accepts(int, int)
-    def my_<caret>method(self):
-        print "Smth"
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyMakeMethodStaticQuickFixTest/decoWithParams_after.py b/python/testData/quickFixes/PyMakeMethodStaticQuickFixTest/decoWithParams_after.py
deleted file mode 100644
index 21293a9..0000000
--- a/python/testData/quickFixes/PyMakeMethodStaticQuickFixTest/decoWithParams_after.py
+++ /dev/null
@@ -1,11 +0,0 @@
-__author__ = 'ktisha'
-
-def foo(x):
-  return x
-
-class A():
-
-    @staticmethod
-    @accepts(int, int)
-    def my_<caret>method():
-        print "Smth"
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyMakeMethodStaticQuickFixTest/functionWithDeco.py b/python/testData/quickFixes/PyMakeMethodStaticQuickFixTest/functionWithDeco.py
deleted file mode 100644
index dded2b0..0000000
--- a/python/testData/quickFixes/PyMakeMethodStaticQuickFixTest/functionWithDeco.py
+++ /dev/null
@@ -1,10 +0,0 @@
-__author__ = 'ktisha'
-
-def foo(x):
-  return x
-
-class A():
-
-    @my_deco
-    def my_<caret>method(self):
-        print "Smth"
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyMakeMethodStaticQuickFixTest/functionWithDeco_after.py b/python/testData/quickFixes/PyMakeMethodStaticQuickFixTest/functionWithDeco_after.py
deleted file mode 100644
index 36607a4..0000000
--- a/python/testData/quickFixes/PyMakeMethodStaticQuickFixTest/functionWithDeco_after.py
+++ /dev/null
@@ -1,11 +0,0 @@
-__author__ = 'ktisha'
-
-def foo(x):
-  return x
-
-class A():
-
-    @staticmethod
-    @my_deco
-    def my_method():
-        print "Smth"
\ No newline at end of file
diff --git a/python/testData/surround/SurroundWithTryExcept.py b/python/testData/surround/SurroundWithTryExcept.py
index faee07e..ee6e2cb 100644
--- a/python/testData/surround/SurroundWithTryExcept.py
+++ b/python/testData/surround/SurroundWithTryExcept.py
@@ -1,2 +1,2 @@
 def foo():
-    <selection>print "hello"</selection>    
\ No newline at end of file
+    pr<caret>int "hello"
\ No newline at end of file
diff --git a/python/testData/surround/SurroundWithTryExcept_after.py b/python/testData/surround/SurroundWithTryExcept_after.py
index 54b20bc..ae244ff 100644
--- a/python/testData/surround/SurroundWithTryExcept_after.py
+++ b/python/testData/surround/SurroundWithTryExcept_after.py
@@ -2,4 +2,4 @@
     try:
         print "hello"
     except:
-        <selection>pass</selection>    
\ No newline at end of file
+        <selection>pass</selection>
diff --git a/python/testSrc/com/jetbrains/python/PyStringLiteralTest.java b/python/testSrc/com/jetbrains/python/PyStringLiteralTest.java
index 7f5b08a..3933584 100644
--- a/python/testSrc/com/jetbrains/python/PyStringLiteralTest.java
+++ b/python/testSrc/com/jetbrains/python/PyStringLiteralTest.java
@@ -15,6 +15,7 @@
  */
 package com.jetbrains.python;
 
+import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.LiteralTextEscaper;
 import com.intellij.psi.PsiFile;
@@ -64,19 +65,54 @@
     assertEquals(-1, escaper.getOffsetInHost(4, fooOnly));
   }
 
-  public void testIterateCharacterRanges() {
-    final PyStringLiteralExpression expr = createLiteralFromText("'\\nfoo'  'bar'");
+  public void testEscaperOffsetInSingleCharString() {
+    final PyStringLiteralExpression expr = createLiteralFromText("'c'");
     assertNotNull(expr);
-    final List<String> characters = new ArrayList<String>();
-    expr.iterateCharacterRanges(new PyStringLiteralExpression.TextRangeConsumer() {
-      @Override
-      public boolean process(int startOffset, int endOffset, String value) {
-        characters.add(value);
-        return true;
-      }
-    });
-    final List<String> expected = Arrays.asList("\n", "f", "o", "o", "b", "a", "r");
-    assertSameElements(characters, expected);
+    final LiteralTextEscaper<? extends PsiLanguageInjectionHost> escaper = expr.createLiteralTextEscaper();
+    final TextRange range = TextRange.create(1, 2);
+    assertEquals(1, escaper.getOffsetInHost(0, range));
+    assertEquals(2, escaper.getOffsetInHost(1, range));
+    assertEquals(-1, escaper.getOffsetInHost(2, range));
+  }
+
+  public void testEscaperOffsetInSingleEscapedCharString() {
+    final PyStringLiteralExpression expr = createLiteralFromText("'\\n'");
+    assertNotNull(expr);
+    final LiteralTextEscaper<? extends PsiLanguageInjectionHost> escaper = expr.createLiteralTextEscaper();
+    final TextRange range = TextRange.create(1, 3);
+    assertEquals(1, escaper.getOffsetInHost(0, range));
+    assertEquals(3, escaper.getOffsetInHost(1, range));
+    assertEquals(-1, escaper.getOffsetInHost(2, range));
+  }
+
+  public void testIterateCharacterRanges() {
+    assertSameElements(getCharacterRanges("'\\nfoo'  'bar'"),
+                       Arrays.asList("\n", "foo", "bar"));
+  }
+
+  public void testIterateEscapedBackslash() {
+    assertSameElements(getCharacterRanges("'''\n" +
+                                          "foo.\\\\\n" +
+                                          "bar\n" +
+                                          "'''\n"),
+                       Arrays.asList("\nfoo.", "\\", "\nbar\n"));
+  }
+
+  public void testEscaperOffsetInEscapedBackslash() {
+    final PyStringLiteralExpression expr = createLiteralFromText("'XXX foo.\\\\bar YYY'");
+    assertNotNull(expr);
+    final LiteralTextEscaper<? extends PsiLanguageInjectionHost> escaper = expr.createLiteralTextEscaper();
+    final TextRange range = TextRange.create(5, 14);
+    assertEquals(5, escaper.getOffsetInHost(0, range));
+    assertEquals(6, escaper.getOffsetInHost(1, range));
+    assertEquals(7, escaper.getOffsetInHost(2, range));
+    assertEquals(8, escaper.getOffsetInHost(3, range));
+    assertEquals(9, escaper.getOffsetInHost(4, range));
+    assertEquals(11, escaper.getOffsetInHost(5, range));
+    assertEquals(12, escaper.getOffsetInHost(6, range));
+    assertEquals(13, escaper.getOffsetInHost(7, range));
+    assertEquals(14, escaper.getOffsetInHost(8, range));
+    assertEquals(-1, escaper.getOffsetInHost(9, range));
   }
 
   private static String decodeRange(PyStringLiteralExpression expr, TextRange range) {
@@ -100,4 +136,14 @@
     assertEquals("b\\n", createLiteralFromText("ur'\\u0062\\n'").getStringValue());
     assertEquals("\\8", createLiteralFromText("'\\8'").getStringValue());
   }
+
+  private List<String> getCharacterRanges(String text) {
+    final PyStringLiteralExpression expr = createLiteralFromText(text);
+    assertNotNull(expr);
+    final List<String> characters = new ArrayList<String>();
+    for (Pair<TextRange, String> fragment : expr.getDecodedFragments()) {
+      characters.add(fragment.getSecond());
+    }
+    return characters;
+  }
 }
diff --git a/python/testSrc/com/jetbrains/python/PySurroundWithTest.java b/python/testSrc/com/jetbrains/python/PySurroundWithTest.java
index b2a1292..5f49581 100644
--- a/python/testSrc/com/jetbrains/python/PySurroundWithTest.java
+++ b/python/testSrc/com/jetbrains/python/PySurroundWithTest.java
@@ -35,7 +35,7 @@
     doTest(new PyWithWhileSurrounder());
   }
 
-  public void _testSurroundWithTryExcept() throws Exception {
+  public void testSurroundWithTryExcept() throws Exception {
     doTest(new PyWithTryExceptSurrounder());
   }
 
diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java
index 4f93cca..da7888e 100644
--- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java
+++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java
@@ -15,9 +15,12 @@
  */
 package com.jetbrains.python;
 
+import com.google.common.collect.Lists;
 import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
+import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
 import com.intellij.codeInsight.lookup.Lookup;
 import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementBuilder;
 import com.jetbrains.python.documentation.DocStringFormat;
 import com.jetbrains.python.documentation.PyDocumentationSettings;
 import com.jetbrains.python.fixtures.PyTestCase;
@@ -387,8 +390,10 @@
     final PyDocumentationSettings settings = PyDocumentationSettings.getInstance(myFixture.getModule());
     settings.setFormat(DocStringFormat.PLAIN);
     myFixture.configureByFile("completion/identifiersInPlainDocstring.py");
-    myFixture.completeBasic();
-    myFixture.checkResultByFile("completion/identifiersInPlainDocstring.after.py");
+    final LookupElement[] elements = myFixture.completeBasic();
+    assertNotNull(elements);
+    assertContainsElements(Lists.newArrayList(elements),
+                           LookupElementBuilder.create("bar").withAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE));
   }
 
   public void testPep328Completion() {  // PY-3409
diff --git a/python/testSrc/com/jetbrains/python/PythonParsingTest.java b/python/testSrc/com/jetbrains/python/PythonParsingTest.java
index 669ac3d..9f612a2 100644
--- a/python/testSrc/com/jetbrains/python/PythonParsingTest.java
+++ b/python/testSrc/com/jetbrains/python/PythonParsingTest.java
@@ -430,6 +430,14 @@
     doTest();
   }
 
+  public void testNotClosedBraceDict() {
+    doTest();
+  }
+
+  public void testNotClosedBraceSet() {
+    doTest(LanguageLevel.PYTHON33);
+  }
+
   public void doTest(LanguageLevel languageLevel) {
     LanguageLevel prev = myLanguageLevel;
     myLanguageLevel = languageLevel;
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyMethodMayBeStaticInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyMethodMayBeStaticInspectionTest.java
index ea40830..885f043 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyMethodMayBeStaticInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyMethodMayBeStaticInspectionTest.java
@@ -15,6 +15,7 @@
  */
 package com.jetbrains.python.inspections;
 
+import com.intellij.testFramework.TestDataPath;
 import com.jetbrains.python.PythonTestUtil;
 import com.jetbrains.python.fixtures.PyTestCase;
 
@@ -23,6 +24,7 @@
 /**
  * User: ktisha
  */
+@TestDataPath("$CONTENT_ROOT/../testData/inspections/PyMethodMayBeStaticInspection/")
 public class PyMethodMayBeStaticInspectionTest extends PyTestCase {
 
   public void testTruePositive() {
@@ -65,6 +67,10 @@
     doTest();
   }
 
+  public void testDecorated() {
+    doTest();
+  }
+
   public void testOverwrittenMethod() {
     doTest();
   }
diff --git a/python/testSrc/com/jetbrains/python/quickFixes/PyMakeMethodStaticQuickFixTest.java b/python/testSrc/com/jetbrains/python/quickFixes/PyMakeMethodStaticQuickFixTest.java
index 310c211..835e6ed 100644
--- a/python/testSrc/com/jetbrains/python/quickFixes/PyMakeMethodStaticQuickFixTest.java
+++ b/python/testSrc/com/jetbrains/python/quickFixes/PyMakeMethodStaticQuickFixTest.java
@@ -36,14 +36,6 @@
     doQuickFixTest(PyMethodMayBeStaticInspection.class, PyBundle.message("QFIX.NAME.make.static"));
   }
 
-  public void testFunctionWithDeco() {
-    doQuickFixTest(PyMethodMayBeStaticInspection.class, PyBundle.message("QFIX.NAME.make.static"));
-  }
-
-  public void testDecoWithParams() {
-    doQuickFixTest(PyMethodMayBeStaticInspection.class, PyBundle.message("QFIX.NAME.make.static"));
-  }
-
   public void testNoSelf() {
     doQuickFixTest(PyMethodMayBeStaticInspection.class, PyBundle.message("QFIX.NAME.make.static"));
   }