Snapshot idea/138.1980 from git://git.jetbrains.org/idea/community.git

Change-Id: Ib567c9c152d770212a7a3db20fbf591c210920bd
diff --git a/python/edu/learn-python/gen/icons/StudyIcons.java b/python/edu/learn-python/gen/icons/StudyIcons.java
index 2840910..04ae98d 100644
--- a/python/edu/learn-python/gen/icons/StudyIcons.java
+++ b/python/edu/learn-python/gen/icons/StudyIcons.java
@@ -13,17 +13,15 @@
     return IconLoader.getIcon(path, StudyIcons.class);
   }
 
-  public static final Icon Add = load("/icons/com/jetbrains/python/edu/add.png"); // 16x16
-  public static final Icon Checked = load("/icons/com/jetbrains/python/edu/checked.png"); // 32x32
-  public static final Icon Failed = load("/icons/com/jetbrains/python/edu/failed.png"); // 32x32
-  public static final Icon Next = load("/icons/com/jetbrains/python/edu/next.png"); // 24x24
-  public static final Icon Playground = load("/icons/com/jetbrains/python/edu/playground.png"); // 32x28
-  public static final Icon Prev = load("/icons/com/jetbrains/python/edu/prev.png"); // 24x24
-  public static final Icon Refresh = load("/icons/com/jetbrains/python/edu/refresh.png"); // 16x16
-  public static final Icon Refresh24 = load("/icons/com/jetbrains/python/edu/refresh24.png"); // 24x24
-  public static final Icon Resolve = load("/icons/com/jetbrains/python/edu/resolve.png"); // 24x24
-  public static final Icon Run = load("/icons/com/jetbrains/python/edu/Run.png"); // 24x24
+  public static final Icon EducationalProjectType = load("/icons/com/jetbrains/python/edu/EducationalProjectType.png"); // 32x32
+  public static final Icon Lesson = load("/icons/com/jetbrains/python/edu/Lesson.png"); // 16x16
+  public static final Icon LessonCompl = load("/icons/com/jetbrains/python/edu/LessonCompl.png"); // 16x16
+  public static final Icon Playground = load("/icons/com/jetbrains/python/edu/Playground.png"); // 16x16
+  public static final Icon Prev = load("/icons/com/jetbrains/python/edu/prev.png"); // 16x16
+  public static final Icon Resolve = load("/icons/com/jetbrains/python/edu/resolve.png"); // 16x16
   public static final Icon ShowHint = load("/icons/com/jetbrains/python/edu/showHint.png"); // 24x24
-  public static final Icon Unchecked = load("/icons/com/jetbrains/python/edu/unchecked.png"); // 32x32
+  public static final Icon Task = load("/icons/com/jetbrains/python/edu/Task.png"); // 16x16
+  public static final Icon TaskCompl = load("/icons/com/jetbrains/python/edu/TaskCompl.png"); // 16x16
+  public static final Icon TaskProbl = load("/icons/com/jetbrains/python/edu/TaskProbl.png"); // 16x16
   public static final Icon WatchInput = load("/icons/com/jetbrains/python/edu/WatchInput.png"); // 24x24
 }
diff --git a/python/edu/learn-python/learn-python.iml b/python/edu/learn-python/learn-python.iml
index bd539d1..613d675 100644
--- a/python/edu/learn-python/learn-python.iml
+++ b/python/edu/learn-python/learn-python.iml
@@ -15,6 +15,7 @@
     <orderEntry type="module" module-name="lang-impl" />
     <orderEntry type="library" name="gson" level="project" />
     <orderEntry type="library" name="JUnit4" level="project" />
+    <orderEntry type="module" module-name="python-ide-community" />
   </component>
 </module>
 
diff --git a/python/edu/learn-python/resources/META-INF/plugin.xml b/python/edu/learn-python/resources/META-INF/plugin.xml
index ec828eb..8e8bddc 100644
--- a/python/edu/learn-python/resources/META-INF/plugin.xml
+++ b/python/edu/learn-python/resources/META-INF/plugin.xml
@@ -50,7 +50,7 @@
     <action id="NextTaskAction" class="com.jetbrains.python.edu.actions.StudyNextStudyTaskAction" text="NextTaskAction" description="Next Task"/>
     <action id="PreviousTaskAction" class="com.jetbrains.python.edu.actions.StudyPreviousStudyTaskAction" text="PreviousTaskAction"
             description="Previous Task"/>
-    <action id="RefreshTaskAction" class="com.jetbrains.python.edu.actions.StudyRefreshTaskAction" text="RefreshTaskAction"
+    <action id="RefreshTaskAction" class="com.jetbrains.python.edu.actions.StudyRefreshTaskFileAction" text="RefreshTaskAction"
             description="Refresh current task"/>
     <action id="WatchInputAction" class="com.jetbrains.python.edu.actions.StudyEditInputAction" text="WatchInputAction"
             description="watch input"/>
@@ -59,6 +59,11 @@
             description="show hint">
       <add-to-group group-id="MainToolBar" anchor="last"/>
     </action>
+
+    <action id="WelcomeScreen.LearnPython" class="com.jetbrains.python.edu.actions.StudyNewProject" icon="StudyIcons.EducationalProjectType">
+      <add-to-group group-id="WelcomeScreen.QuickStart" anchor="first"/>
+    </action>
+
   </actions>
 
   <extensions defaultExtensionNs="com.intellij">
@@ -70,4 +75,7 @@
     <applicationService serviceInterface="com.intellij.openapi.fileEditor.impl.EditorEmptyTextPainter"
         serviceImplementation="com.jetbrains.python.edu.StudyInstructionPainter" overrides="true"/>
   </extensions>
+  <extensions defaultExtensionNs="Pythonid">
+    <visitorFilter language="Python" implementationClass="com.jetbrains.python.edu.highlighting.StudyVisitorFilter"/>
+  </extensions>
 </idea-plugin>
\ No newline at end of file
diff --git a/python/edu/learn-python/resources/courses/introduction_course.zip b/python/edu/learn-python/resources/courses/introduction_course.zip
index f3b24f2..c39695e 100644
--- a/python/edu/learn-python/resources/courses/introduction_course.zip
+++ b/python/edu/learn-python/resources/courses/introduction_course.zip
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType.png
new file mode 100644
index 0000000..6340e89
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType_dark.png
new file mode 100644
index 0000000..d9ec6dc
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson.png
new file mode 100644
index 0000000..9cc8a4f
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson@2x.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson@2x.png
new file mode 100644
index 0000000..2b0c0b8
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson@2x.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonComp@2x.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonComp@2x.png
new file mode 100644
index 0000000..e18c639
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonComp@2x.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonCompl.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonCompl.png
new file mode 100644
index 0000000..bacc7de
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonCompl.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground.png
new file mode 100644
index 0000000..1086710
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground@2x.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground@2x.png
new file mode 100644
index 0000000..58665fa
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground@2x.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Run.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Run.png
deleted file mode 100644
index 27a6e36..0000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Run.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task.png
new file mode 100644
index 0000000..b678c64
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x.png
new file mode 100644
index 0000000..4abb95c
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x_dark.png
new file mode 100644
index 0000000..78af691
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl.png
new file mode 100644
index 0000000..a7f8f77
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x.png
new file mode 100644
index 0000000..d657aa6
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x_dark.png
new file mode 100644
index 0000000..f5f29ee
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl_dark.png
new file mode 100644
index 0000000..481e9cd
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl.png
new file mode 100644
index 0000000..6173d64
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x.png
new file mode 100644
index 0000000..44aba9d
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x_dark.png
new file mode 100644
index 0000000..f74c9de
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl_dark.png
new file mode 100644
index 0000000..0133a7f
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task_dark.png
new file mode 100644
index 0000000..2ff286d
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/add.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/add.png
deleted file mode 100644
index 9494f2d..0000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/add.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/checked.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/checked.png
deleted file mode 100644
index 4105a01..0000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/checked.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/failed.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/failed.png
deleted file mode 100644
index e2aaa55..0000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/failed.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/icon.jpg b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/icon.jpg
deleted file mode 100644
index 3a9716e..0000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/icon.jpg
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/next.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/next.png
deleted file mode 100644
index dd1a5d9..0000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/next.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/playground.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/playground.png
deleted file mode 100644
index d12a751..0000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/playground.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/prev.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/prev.png
index 0656f81..fc51cb5 100644
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/prev.png
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/prev.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh.png
deleted file mode 100644
index d595f6b..0000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh24.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh24.png
deleted file mode 100644
index 218f075..0000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh24.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve.png
index 7ef960b..78290f9 100644
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve.png
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve_dark.png
index 99aaa1d..b988adc 100644
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve_dark.png
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/unchecked.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/unchecked.png
deleted file mode 100644
index 2145982..0000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/unchecked.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java
index d4831d9..59bd8bc 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java
@@ -53,7 +53,7 @@
   @NotNull
   @Override
   public String getName() {
-    return "Study project";
+    return "Learn Python";
   }
 
 
@@ -137,7 +137,7 @@
   @Nullable
   @Override
   public Icon getLogo() {
-    return StudyIcons.Playground;
+    return StudyIcons.EducationalProjectType;
   }
 
 
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java
index 9fdcf70..6ce1d09 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java
@@ -52,6 +52,9 @@
       if (myTaskWindow != null) {
         int newLength = myTaskWindow.getLength() + change;
         myTaskWindow.setLength(newLength <= 0 ? 0 : newLength);
+        if (e.getNewFragment().equals("\n")) {
+          myTaskWindow.setLength(myTaskWindow.getLength() + 1);
+        }
       }
       int newEnd = offset + event.getNewLength();
       int newLine = document.getLineNumber(newEnd);
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java
index 4f34bfb..96a44b2 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java
@@ -8,7 +8,6 @@
 import com.intellij.util.PairFunction;
 import com.intellij.util.ui.GraphicsUtil;
 import com.intellij.util.ui.UIUtil;
-import com.jetbrains.python.edu.ui.StudyCondition;
 
 import java.awt.*;
 
@@ -19,10 +18,6 @@
 public class StudyInstructionPainter extends EditorEmptyTextPainter {
   @Override
   public void paintEmptyText(final EditorsSplitters splitters, Graphics g) {
-    if (!StudyCondition.VALUE) {
-      super.paintEmptyText(splitters, g);
-      return;
-    }
     boolean isDarkBackground = UIUtil.isUnderDarcula();
     UIUtil.applyRenderingHints(g);
     GraphicsUtil.setupAntialiasing(g, true, false);
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyState.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyState.java
new file mode 100644
index 0000000..96dc3d9
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyState.java
@@ -0,0 +1,52 @@
+package com.jetbrains.python.edu;
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.jetbrains.python.edu.course.Task;
+import com.jetbrains.python.edu.course.TaskFile;
+import com.jetbrains.python.edu.editor.StudyEditor;
+
+public class StudyState {
+  private final StudyEditor myStudyEditor;
+  private final Editor myEditor;
+  private final TaskFile myTaskFile;
+  private final VirtualFile myVirtualFile;
+  private final Task myTask;
+  private final VirtualFile myTaskDir;
+
+  public StudyState(final StudyEditor studyEditor) {
+    myStudyEditor = studyEditor;
+    myEditor = studyEditor != null ? studyEditor.getEditor() : null;
+    myTaskFile = studyEditor != null ? studyEditor.getTaskFile() : null;
+    myVirtualFile = myEditor != null ? FileDocumentManager.getInstance().getFile(myEditor.getDocument()) : null;
+    myTaskDir = myVirtualFile != null ? myVirtualFile.getParent() : null;
+    myTask = myTaskFile != null ? myTaskFile.getTask() : null;
+  }
+
+  public Editor getEditor() {
+    return myEditor;
+  }
+
+  public TaskFile getTaskFile() {
+    return myTaskFile;
+  }
+
+  public VirtualFile getVirtualFile() {
+    return myVirtualFile;
+  }
+
+  public Task getTask() {
+    return myTask;
+  }
+
+  public VirtualFile getTaskDir() {
+    return myTaskDir;
+  }
+
+  public boolean isValid() {
+    return myStudyEditor != null && myEditor != null &&
+           myTaskFile != null && myVirtualFile != null &&
+           myTask != null && myTaskDir != null;
+  }
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java
index 213c1f7..3013fbc 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java
@@ -109,21 +109,29 @@
               StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() {
                 @Override
                 public void run() {
-                  ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PROJECT_VIEW).show(null);
-                  FileEditor[] editors = FileEditorManager.getInstance(myProject).getSelectedEditors();
-                  if (editors.length > 0) {
-                    JComponent focusedComponent = editors[0].getPreferredFocusedComponent();
-                    if (focusedComponent != null) {
-                      IdeFocusManager.getInstance(myProject).requestFocus(focusedComponent, true);
+                  ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PROJECT_VIEW).show(new Runnable() {
+                    @Override
+                    public void run() {
+                      FileEditor[] editors = FileEditorManager.getInstance(myProject).getSelectedEditors();
+                      if (editors.length > 0) {
+                        final JComponent focusedComponent = editors[0].getPreferredFocusedComponent();
+                        if (focusedComponent != null) {
+                          ApplicationManager.getApplication().invokeLater(new Runnable() {
+                            @Override
+                            public void run() {
+                              IdeFocusManager.getInstance(myProject).requestFocus(focusedComponent, true);
+                            }
+                          });
+                        }
+                      }
                     }
-                  }
+                  });
                 }
               });
               UISettings.getInstance().HIDE_TOOL_STRIPES = false;
               UISettings.getInstance().fireUISettingsChanged();
               ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject);
               String toolWindowId = StudyToolWindowFactory.STUDY_TOOL_WINDOW;
-              //TODO:decide smth with tool window position
               try {
                 Method method = toolWindowManager.getClass().getDeclaredMethod("registerToolWindow", String.class,
                                                                                JComponent.class,
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTestRunner.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTestRunner.java
new file mode 100644
index 0000000..b0cd5ba
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTestRunner.java
@@ -0,0 +1,76 @@
+package com.jetbrains.python.edu;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.jetbrains.python.edu.course.Course;
+import com.jetbrains.python.edu.course.Task;
+import com.jetbrains.python.sdk.PythonSdkType;
+
+import java.io.*;
+import java.util.Map;
+
+public class StudyTestRunner {
+  public static final String TEST_OK = "#study_plugin test OK";
+  private static final String TEST_FAILED = "#study_plugin FAILED + ";
+  private static final String PYTHONPATH = "PYTHONPATH";
+  private static final Logger LOG = Logger.getInstance(StudyTestRunner.class);
+  private final Task myTask;
+  private final VirtualFile myTaskDir;
+
+  public StudyTestRunner(Task task, VirtualFile taskDir) {
+    myTask = task;
+    myTaskDir = taskDir;
+  }
+
+  public Process launchTests(Project project, String executablePath) throws ExecutionException {
+    Sdk sdk = PythonSdkType.findPythonSdk(ModuleManager.getInstance(project).getModules()[0]);
+    File testRunner = new File(myTaskDir.getPath(), myTask.getTestFile());
+    GeneralCommandLine commandLine = new GeneralCommandLine();
+    commandLine.setWorkDirectory(myTaskDir.getPath());
+    final Map<String, String> env = commandLine.getEnvironment();
+    final VirtualFile courseDir = project.getBaseDir();
+    if (courseDir != null) {
+      env.put(PYTHONPATH, courseDir.getPath());
+    }
+    if (sdk != null) {
+      String pythonPath = sdk.getHomePath();
+      if (pythonPath != null) {
+        commandLine.setExePath(pythonPath);
+        commandLine.addParameter(testRunner.getPath());
+        final Course course = StudyTaskManager.getInstance(project).getCourse();
+        assert course != null;
+        commandLine.addParameter(new File(course.getResourcePath()).getParent());
+        commandLine.addParameter(FileUtil.toSystemDependentName(executablePath));
+        return commandLine.createProcess();
+      }
+    }
+    return null;
+  }
+
+
+  public String getPassedTests(Process p) {
+    InputStream testOutput = p.getInputStream();
+    BufferedReader testOutputReader = new BufferedReader(new InputStreamReader(testOutput));
+    String line;
+    try {
+      while ((line = testOutputReader.readLine()) != null) {
+        if (line.contains(TEST_FAILED)) {
+          return line.substring(TEST_FAILED.length(), line.length());
+        }
+      }
+    }
+    catch (IOException e) {
+      LOG.error(e);
+    }
+    finally {
+      StudyUtils.closeSilently(testOutputReader);
+    }
+    return TEST_OK;
+  }
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyUtils.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyUtils.java
index d3ac1da..5d9bb13 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyUtils.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyUtils.java
@@ -3,6 +3,7 @@
 import com.intellij.ide.SaveAndSyncHandlerImpl;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -10,12 +11,12 @@
 import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.VirtualFileManager;
 import com.intellij.openapi.wm.ToolWindowManager;
 import com.intellij.util.ui.UIUtil;
-import com.jetbrains.python.edu.course.TaskFile;
-import com.jetbrains.python.edu.course.TaskWindow;
+import com.jetbrains.python.edu.course.*;
 import com.jetbrains.python.edu.editor.StudyEditor;
 import com.jetbrains.python.edu.ui.StudyToolWindowFactory;
 import org.jetbrains.annotations.NotNull;
@@ -70,7 +71,7 @@
       return wrapHTML ? UIUtil.toHtml(taskText.toString()) : taskText.toString();
     }
     catch (IOException e) {
-      LOG.error("Failed to get file text from file " + fileName, e);
+      LOG.info("Failed to get file text from file " + fileName, e);
     }
     finally {
       closeSilently(reader);
@@ -119,14 +120,18 @@
   }
 
   @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
-  public static VirtualFile flushWindows(Document document, TaskFile taskFile, VirtualFile file) {
+  public static VirtualFile flushWindows(TaskFile taskFile, VirtualFile file) {
     VirtualFile taskDir = file.getParent();
     VirtualFile fileWindows = null;
+    final Document document = FileDocumentManager.getInstance().getDocument(file);
+    if (document == null) {
+      LOG.debug("Couldn't flush windows");
+      return null;
+    }
     if (taskDir != null) {
       String name = file.getNameWithoutExtension() + "_windows";
       PrintWriter printWriter = null;
       try {
-
         fileWindows = taskDir.createChildData(taskFile, name);
         printWriter = new PrintWriter(new FileOutputStream(fileWindows.getPath()));
         for (TaskWindow taskWindow : taskFile.getTaskWindows()) {
@@ -137,6 +142,12 @@
           String windowDescription = document.getText(new TextRange(start, start + taskWindow.getLength()));
           printWriter.println("#study_plugin_window = " + windowDescription);
         }
+        ApplicationManager.getApplication().runWriteAction(new Runnable() {
+          @Override
+          public void run() {
+            FileDocumentManager.getInstance().saveDocument(document);
+          }
+        });
       }
       catch (IOException e) {
        LOG.error(e);
@@ -148,4 +159,27 @@
     }
     return fileWindows;
   }
+
+  public static void deleteFile(VirtualFile file) {
+    try {
+      file.delete(StudyUtils.class);
+    }
+    catch (IOException e) {
+      LOG.error(e);
+    }
+  }
+
+  public static File copyResourceFile(String sourceName, String copyName, Project project, Task task)
+    throws IOException {
+    StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
+    Course course = taskManager.getCourse();
+    int taskNum = task.getIndex() + 1;
+    int lessonNum = task.getLesson().getIndex() + 1;
+    assert course != null;
+    String pathToResource =
+      FileUtil.join(new File(course.getResourcePath()).getParent(), Lesson.LESSON_DIR + lessonNum, Task.TASK_DIR + taskNum);
+    File resourceFile = new File(pathToResource, copyName);
+    FileUtil.copy(new File(pathToResource, sourceName), resourceFile);
+    return resourceFile;
+  }
 }
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java
index f8e10c9..5d02f71 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java
@@ -1,7 +1,6 @@
 package com.jetbrains.python.edu.actions;
 
 import com.intellij.execution.ExecutionException;
-import com.intellij.execution.configurations.GeneralCommandLine;
 import com.intellij.ide.projectView.ProjectView;
 import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -13,93 +12,81 @@
 import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.fileEditor.FileEditor;
 import com.intellij.openapi.fileEditor.FileEditorManager;
-import com.intellij.openapi.module.ModuleManager;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.ui.MessageType;
 import com.intellij.openapi.ui.popup.Balloon;
 import com.intellij.openapi.ui.popup.BalloonBuilder;
 import com.intellij.openapi.ui.popup.JBPopupFactory;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.JBColor;
+import com.intellij.openapi.wm.IdeFocusManager;
 import com.jetbrains.python.edu.StudyDocumentListener;
-import com.jetbrains.python.edu.StudyTaskManager;
+import com.jetbrains.python.edu.StudyState;
+import com.jetbrains.python.edu.StudyTestRunner;
 import com.jetbrains.python.edu.StudyUtils;
-import com.jetbrains.python.edu.course.*;
+import com.jetbrains.python.edu.course.StudyStatus;
+import com.jetbrains.python.edu.course.Task;
+import com.jetbrains.python.edu.course.TaskFile;
+import com.jetbrains.python.edu.course.TaskWindow;
 import com.jetbrains.python.edu.editor.StudyEditor;
-import com.jetbrains.python.sdk.PythonSdkType;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
 import java.awt.*;
-import java.io.*;
-import java.util.*;
-import java.util.List;
+import java.io.IOException;
+import java.util.Map;
 
 public class StudyCheckAction extends DumbAwareAction {
 
   private static final Logger LOG = Logger.getInstance(StudyCheckAction.class.getName());
-  public static final String PYTHONPATH = "PYTHONPATH";
+  private static final String ANSWERS_POSTFIX = "_answers.py";
 
-  static class StudyTestRunner {
-    public static final String TEST_OK = "#study_plugin test OK";
-    private static final String TEST_FAILED = "#study_plugin FAILED + ";
-    private final Task myTask;
-    private final VirtualFile myTaskDir;
 
-    StudyTestRunner(Task task, VirtualFile taskDir) {
-      myTask = task;
-      myTaskDir = taskDir;
-    }
-
-    Process launchTests(Project project, String executablePath) throws ExecutionException {
-      Sdk sdk = PythonSdkType.findPythonSdk(ModuleManager.getInstance(project).getModules()[0]);
-      File testRunner = new File(myTaskDir.getPath(), myTask.getTestFile());
-      GeneralCommandLine commandLine = new GeneralCommandLine();
-      commandLine.setWorkDirectory(myTaskDir.getPath());
-      final Map<String, String> env = commandLine.getEnvironment();
-      final VirtualFile courseDir = project.getBaseDir();
-      if (courseDir != null)
-        env.put(PYTHONPATH, courseDir.getPath());
-      if (sdk != null) {
-        String pythonPath = sdk.getHomePath();
-        if (pythonPath != null) {
-          commandLine.setExePath(pythonPath);
-          commandLine.addParameter(testRunner.getPath());
-          final Course course = StudyTaskManager.getInstance(project).getCourse();
-          assert course != null;
-          commandLine.addParameter(new File(course.getResourcePath()).getParent());
-          commandLine.addParameter(FileUtil.toSystemDependentName(executablePath));
-          return commandLine.createProcess();
-        }
+  private static void flushWindows(@NotNull final Task task, @NotNull final VirtualFile taskDir) {
+    for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
+      String name = entry.getKey();
+      TaskFile taskFile = entry.getValue();
+      VirtualFile virtualFile = taskDir.findChild(name);
+      if (virtualFile == null) {
+        continue;
       }
-      return null;
-    }
-
-
-    String getPassedTests(Process p) {
-      InputStream testOutput = p.getInputStream();
-      BufferedReader testOutputReader = new BufferedReader(new InputStreamReader(testOutput));
-      String line;
-      try {
-        while ((line = testOutputReader.readLine()) != null) {
-          if (line.contains(TEST_FAILED)) {
-             return line.substring(TEST_FAILED.length(), line.length());
-          }
-        }
-      }
-      catch (IOException e) {
-        LOG.error(e);
-      }
-      finally {
-        StudyUtils.closeSilently(testOutputReader);
-      }
-      return TEST_OK;
+      StudyUtils.flushWindows(taskFile, virtualFile);
     }
   }
 
+  private static void deleteWindowDescriptions(@NotNull final Task task, @NotNull final VirtualFile taskDir) {
+    for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
+      String name = entry.getKey();
+      VirtualFile virtualFile = taskDir.findChild(name);
+      if (virtualFile == null) {
+        continue;
+      }
+      String windowsFileName = virtualFile.getNameWithoutExtension() + "_windows";
+      VirtualFile windowsFile = taskDir.findChild(windowsFileName);
+      if (windowsFile != null) {
+        StudyUtils.deleteFile(windowsFile);
+      }
+    }
+  }
+
+  private static void drawAllTaskWindows(@NotNull final Project project, @NotNull final Task task, @NotNull final VirtualFile taskDir) {
+    for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
+      String name = entry.getKey();
+      TaskFile taskFile = entry.getValue();
+      VirtualFile virtualFile = taskDir.findChild(name);
+      if (virtualFile == null) {
+        continue;
+      }
+      FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(virtualFile);
+      if (fileEditor instanceof StudyEditor) {
+        StudyEditor studyEditor = (StudyEditor)fileEditor;
+        taskFile.drawAllWindows(studyEditor.getEditor());
+      }
+    }
+  }
+
+
   public void check(@NotNull final Project project) {
     ApplicationManager.getApplication().runWriteAction(new Runnable() {
       @Override
@@ -107,188 +94,138 @@
         CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
           @Override
           public void run() {
-        final Editor selectedEditor = StudyEditor.getSelectedEditor(project);
-        if (selectedEditor != null) {
-          final FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
-          final VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
-          if (openedFile != null) {
-            StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
-            final TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
-            List<VirtualFile> filesToDelete = new ArrayList<VirtualFile>();
-            if (selectedTaskFile != null) {
-              final VirtualFile taskDir = openedFile.getParent();
-              Task currentTask = selectedTaskFile.getTask();
-              StudyStatus oldStatus = currentTask.getStatus();
-              Map<String, TaskFile> taskFiles = selectedTaskFile.getTask().getTaskFiles();
+            final StudyEditor selectedEditor = StudyEditor.getSelectedStudyEditor(project);
+            final StudyState studyState = new StudyState(selectedEditor);
+            if (!studyState.isValid()) {
+              LOG.error("StudyCheckAction was invokes outside study editor");
+              return;
+            }
+            Task task = studyState.getTask();
+            StudyStatus oldStatus = task.getStatus();
+            Map<String, TaskFile> taskFiles = task.getTaskFiles();
+            VirtualFile taskDir = studyState.getTaskDir();
+            flushWindows(task, taskDir);
+            StudyRunAction runAction = (StudyRunAction)ActionManager.getInstance().getAction(StudyRunAction.ACTION_ID);
+            if (runAction != null && taskFiles.size() == 1) {
+              runAction.run(project);
+            }
+            ApplicationManager.getApplication().invokeLater(new Runnable() {
+              @Override
+              public void run() {
+                IdeFocusManager.getInstance(project).requestFocus(studyState.getEditor().getComponent(), true);
+              }
+            });
+            final StudyTestRunner testRunner = new StudyTestRunner(task, taskDir);
+            Process testProcess = null;
+            try {
+              testProcess = testRunner.launchTests(project, studyState.getVirtualFile().getPath());
+            }
+            catch (ExecutionException e) {
+              LOG.error(e);
+            }
+            if (testProcess == null) {
+              return;
+            }
+            String failedMessage = testRunner.getPassedTests(testProcess);
+            if (failedMessage.equals(StudyTestRunner.TEST_OK)) {
+              task.setStatus(StudyStatus.Solved, oldStatus);
+              createTestResultPopUp("Congratulations!", MessageType.INFO.getPopupBackground(), project);
+            }
+            else {
+              task.setStatus(StudyStatus.Failed, oldStatus);
               for (Map.Entry<String, TaskFile> entry : taskFiles.entrySet()) {
                 String name = entry.getKey();
                 TaskFile taskFile = entry.getValue();
-                VirtualFile virtualFile = taskDir.findChild(name);
-                if (virtualFile == null) {
+                if (taskFile.getTaskWindows().size() < 2) {
+                  taskFile.setStatus(StudyStatus.Failed, StudyStatus.Unchecked);
                   continue;
                 }
-                VirtualFile windowFile = StudyUtils.flushWindows(FileDocumentManager.getInstance().getDocument(virtualFile), taskFile, virtualFile);
-                filesToDelete.add(windowFile);
-                FileDocumentManager.getInstance().saveAllDocuments();
+                runSmartTestProcess(taskDir, testRunner, name, taskFile, project);
               }
-
-              StudyRunAction runAction = (StudyRunAction)ActionManager.getInstance().getAction(StudyRunAction.ACTION_ID);
-              if (runAction != null && currentTask.getTaskFiles().size() == 1) {
-                runAction.run(project);
-              }
-              final StudyTestRunner testRunner = new StudyTestRunner(currentTask, taskDir);
-              Process testProcess = null;
-              try {
-                testProcess = testRunner.launchTests(project, openedFile.getPath());
-              }
-              catch (ExecutionException e) {
-                LOG.error(e);
-              }
-              if (testProcess != null) {
-                String failedMessage = testRunner.getPassedTests(testProcess);
-                if (failedMessage.equals(StudyTestRunner.TEST_OK)) {
-                  currentTask.setStatus(StudyStatus.Solved, oldStatus);
-                  StudyUtils.updateStudyToolWindow(project);
-                  selectedTaskFile.drawAllWindows(selectedEditor);
-                  ProjectView.getInstance(project).refresh();
-                  for (VirtualFile file:filesToDelete) {
-                    try {
-                      file.delete(this);
-                    }
-                    catch (IOException e) {
-                      LOG.error(e);
-                    }
-                  }
-                  createTestResultPopUp("Congratulations!", JBColor.GREEN, project);
-                  return;
-                }
-                for (Map.Entry<String, TaskFile> entry : taskFiles.entrySet()) {
-                  String name = entry.getKey();
-                  TaskFile taskFile = entry.getValue();
-                  TaskFile answerTaskFile = new TaskFile();
-                  VirtualFile virtualFile = taskDir.findChild(name);
-                  if (virtualFile == null) {
-                    continue;
-                  }
-                  VirtualFile answerFile = getCopyWithAnswers(taskDir, virtualFile, taskFile, answerTaskFile);
-                  for (TaskWindow taskWindow : answerTaskFile.getTaskWindows()) {
-                    Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
-                    if (document == null) {
-                      continue;
-                    }
-                    if (!taskWindow.isValid(document)) {
-                      continue;
-                    }
-                    check(project, taskWindow, answerFile, answerTaskFile, taskFile, document, testRunner, virtualFile);
-                  }
-                  FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(virtualFile);
-                  Editor editor = null;
-                  if (fileEditor instanceof StudyEditor) {
-                    StudyEditor studyEditor = (StudyEditor) fileEditor;
-                    editor = studyEditor.getEditor();
-                  }
-
-                  if (editor != null) {
-                    taskFile.drawAllWindows(editor);
-                    StudyUtils.synchronize();
-                  }
-                  try {
-                    answerFile.delete(this);
-                  }
-                  catch (IOException e) {
-                    LOG.error(e);
-                  }
-                }
-                for (VirtualFile file:filesToDelete) {
-                  try {
-                    file.delete(this);
-                  }
-                  catch (IOException e) {
-                    LOG.error(e);
-                  }
-                }
-                currentTask.setStatus(StudyStatus.Failed, oldStatus);
-                StudyUtils.updateStudyToolWindow(project);
-                createTestResultPopUp(failedMessage, JBColor.RED, project);
-              }
+              createTestResultPopUp(failedMessage, MessageType.ERROR.getPopupBackground(), project);
+              navigateToFailedTaskWindow(studyState, task, taskDir, project);
             }
+            StudyUtils.updateStudyToolWindow(project);
+            drawAllTaskWindows(project, task, taskDir);
+            ProjectView.getInstance(project).refresh();
+            deleteWindowDescriptions(task, taskDir);
           }
-        }
-
-         }
-      });
+        });
       }
     });
   }
 
-  private void check(Project project,
-                     TaskWindow taskWindow,
-                     VirtualFile answerFile,
-                     TaskFile answerTaskFile,
-                     TaskFile usersTaskFile,
-                     Document usersDocument,
-                     StudyTestRunner testRunner,
-                     VirtualFile openedFile) {
-
-    try {
-       VirtualFile windowCopy = answerFile.copy(this, answerFile.getParent(), answerFile.getNameWithoutExtension() + "_window" + taskWindow.getIndex() + ".py");
-      final FileDocumentManager documentManager = FileDocumentManager.getInstance();
-      final Document windowDocument = documentManager.getDocument(windowCopy);
-      if (windowDocument != null) {
-        StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
-        Course course = taskManager.getCourse();
-        Task task = usersTaskFile.getTask();
-        int taskNum = task.getIndex() + 1;
-        int lessonNum = task.getLesson().getIndex() + 1;
-        assert course != null;
-        String pathToResource = FileUtil.join(new File(course.getResourcePath()).getParent(), Lesson.LESSON_DIR + lessonNum,  Task.TASK_DIR + taskNum);
-        File resourceFile = new File(pathToResource, windowCopy.getName());
-        FileUtil.copy(new File(pathToResource, openedFile.getName()), resourceFile);
-        TaskFile windowTaskFile = new TaskFile();
-        TaskFile.copy(answerTaskFile, windowTaskFile);
-        StudyDocumentListener listener = new StudyDocumentListener(windowTaskFile);
-        windowDocument.addDocumentListener(listener);
-        int start = taskWindow.getRealStartOffset(windowDocument);
-        int end = start + taskWindow.getLength();
-        TaskWindow userTaskWindow = usersTaskFile.getTaskWindows().get(taskWindow.getIndex());
-        int userStart = userTaskWindow.getRealStartOffset(usersDocument);
-        int userEnd = userStart + userTaskWindow.getLength();
-        String text = usersDocument.getText(new TextRange(userStart, userEnd));
-        windowDocument.replaceString(start, end, text);
-        ApplicationManager.getApplication().runWriteAction(new Runnable() {
-          @Override
-          public void run() {
-            documentManager.saveDocument(windowDocument);
+  private static void navigateToFailedTaskWindow(@NotNull final StudyState studyState,
+                                                 @NotNull final Task task,
+                                                 @NotNull final VirtualFile taskDir,
+                                                 @NotNull final Project project) {
+    TaskFile selectedTaskFile = studyState.getTaskFile();
+    Editor editor = studyState.getEditor();
+    TaskFile taskFileToNavigate = selectedTaskFile;
+    VirtualFile fileToNavigate = studyState.getVirtualFile();
+    if (!selectedTaskFile.hasFailedTaskWindows()) {
+      for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
+        String name = entry.getKey();
+        TaskFile taskFile = entry.getValue();
+        if (taskFile.hasFailedTaskWindows()) {
+          taskFileToNavigate = taskFile;
+          VirtualFile virtualFile = taskDir.findChild(name);
+          if (virtualFile == null) {
+            continue;
           }
-        });
-        VirtualFile fileWindows = StudyUtils.flushWindows(windowDocument, windowTaskFile, windowCopy);
-        Process smartTestProcess = testRunner.launchTests(project, windowCopy.getPath());
-        boolean res = testRunner.getPassedTests(smartTestProcess).equals(StudyTestRunner.TEST_OK);
-        userTaskWindow.setStatus(res ? StudyStatus.Solved : StudyStatus.Failed, StudyStatus.Unchecked);
-        windowCopy.delete(this);
-        fileWindows.delete(this);
-        if (!resourceFile.delete()) {
-          LOG.error("failed to delete", resourceFile.getPath());
+          FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(virtualFile);
+          if (fileEditor instanceof StudyEditor) {
+            StudyEditor studyEditor = (StudyEditor)fileEditor;
+            editor = studyEditor.getEditor();
+          }
+          fileToNavigate = virtualFile;
+          break;
         }
       }
     }
-    catch (IOException e) {
-      LOG.error(e);
-    }
-    catch (ExecutionException e) {
-      LOG.error(e);
-    }
+    FileEditorManager.getInstance(project).openFile(fileToNavigate, true);
+    final Editor editorToNavigate = editor;
+    ApplicationManager.getApplication().invokeLater(new Runnable() {
+      @Override
+      public void run() {
+        IdeFocusManager.getInstance(project).requestFocus(editorToNavigate.getContentComponent(), true);
+      }
+    });
+    taskFileToNavigate.navigateToFirstFailedTaskWindow(editor);
   }
 
+  private void runSmartTestProcess(@NotNull final VirtualFile taskDir,
+                                   @NotNull final StudyTestRunner testRunner,
+                                   final String taskFileName,
+                                   @NotNull final TaskFile taskFile,
+                                   @NotNull final Project project) {
+    TaskFile answerTaskFile = new TaskFile();
+    VirtualFile virtualFile = taskDir.findChild(taskFileName);
+    if (virtualFile == null) {
+      return;
+    }
+    VirtualFile answerFile = getCopyWithAnswers(taskDir, virtualFile, taskFile, answerTaskFile);
+    for (TaskWindow taskWindow : answerTaskFile.getTaskWindows()) {
+      Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
+      if (document == null) {
+        continue;
+      }
+      if (!taskWindow.isValid(document)) {
+        continue;
+      }
+      taskWindow.smartCheck(project, answerFile, answerTaskFile, taskFile, testRunner, virtualFile, document);
+    }
+    StudyUtils.deleteFile(answerFile);
+  }
 
-  private VirtualFile getCopyWithAnswers(final VirtualFile taskDir,
-                                         final VirtualFile file,
-                                         final TaskFile source,
-                                         TaskFile target) {
+  private VirtualFile getCopyWithAnswers(@NotNull final VirtualFile taskDir,
+                                         @NotNull final VirtualFile file,
+                                         @NotNull final TaskFile source,
+                                         @NotNull final TaskFile target) {
     VirtualFile copy = null;
     try {
 
-      copy = file.copy(this, taskDir, file.getNameWithoutExtension() +"_answers.py");
+      copy = file.copy(this, taskDir, file.getNameWithoutExtension() + ANSWERS_POSTFIX);
       final FileDocumentManager documentManager = FileDocumentManager.getInstance();
       final Document document = documentManager.getDocument(copy);
       if (document != null) {
@@ -315,19 +252,18 @@
     catch (IOException e) {
       LOG.error(e);
     }
-
-
     return copy;
   }
 
   private static void createTestResultPopUp(final String text, Color color, @NotNull final Project project) {
     BalloonBuilder balloonBuilder =
       JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(text, null, color, null);
-    Balloon balloon = balloonBuilder.createBalloon();
+    final Balloon balloon = balloonBuilder.createBalloon();
     StudyEditor studyEditor = StudyEditor.getSelectedStudyEditor(project);
     assert studyEditor != null;
     JButton checkButton = studyEditor.getCheckButton();
     balloon.showInCenterOf(checkButton);
+    Disposer.register(project, balloon);
   }
 
   @Override
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyEditInputAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyEditInputAction.java
index 5b9a6fe..72660fc 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyEditInputAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyEditInputAction.java
@@ -19,6 +19,7 @@
 import com.intellij.ui.tabs.TabInfo;
 import com.intellij.ui.tabs.TabsListener;
 import com.intellij.ui.tabs.impl.JBEditorTabs;
+import com.intellij.util.PlatformIcons;
 import com.jetbrains.python.edu.StudyTaskManager;
 import com.jetbrains.python.edu.StudyUtils;
 import com.jetbrains.python.edu.course.Task;
@@ -26,7 +27,6 @@
 import com.jetbrains.python.edu.course.UserTest;
 import com.jetbrains.python.edu.editor.StudyEditor;
 import com.jetbrains.python.edu.ui.StudyTestContentPanel;
-import icons.StudyIcons;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
@@ -92,7 +92,7 @@
         i++;
       }
       TabInfo plusTab = new TabInfo(new JPanel());
-      plusTab.setIcon(StudyIcons.Add);
+      plusTab.setIcon(PlatformIcons.ADD_ICON);
       tabbedPane.addTabSilently(plusTab, tabbedPane.getTabCount());
       final JBPopup hint =
         JBPopupFactory.getInstance().createComponentPopupBuilder(tabbedPane.getComponent(), tabbedPane.getComponent())
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java
new file mode 100644
index 0000000..0b75c4b
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.edu.actions;
+
+import com.jetbrains.python.edu.StudyDirectoryProjectGenerator;
+import com.jetbrains.python.newProject.actions.GenerateProjectCallback;
+import com.jetbrains.python.newProject.actions.ProjectSpecificAction;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class StudyNewProject extends ProjectSpecificAction {
+
+  public StudyNewProject(@NotNull final String name, @Nullable final Runnable runnable) {
+    super(new GenerateProjectCallback(runnable), new StudyDirectoryProjectGenerator(), name, true);
+  }
+
+  public StudyNewProject() {
+    this("Learn Python", null);
+  }
+
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextStudyTaskAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextStudyTaskAction.java
index 81818a9..3c971c3 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextStudyTaskAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextStudyTaskAction.java
@@ -2,13 +2,14 @@
 
 import com.jetbrains.python.edu.editor.StudyEditor;
 import com.jetbrains.python.edu.course.Task;
+import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
 
 public class StudyNextStudyTaskAction extends StudyTaskNavigationAction {
 
   @Override
-  protected JButton getButton(StudyEditor selectedStudyEditor) {
+  protected JButton getButton(@NotNull final StudyEditor selectedStudyEditor) {
     return selectedStudyEditor.getNextTaskButton();
   }
 
@@ -18,7 +19,7 @@
   }
 
   @Override
-  protected Task getTargetTask(Task sourceTask) {
+  protected Task getTargetTask(@NotNull final Task sourceTask) {
     return sourceTask.next();
   }
 }
\ No newline at end of file
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java
index 595aeef..fcf9ef4 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java
@@ -1,8 +1,8 @@
 package com.jetbrains.python.edu.actions;
 
+import com.intellij.icons.AllIcons;
 import com.jetbrains.python.edu.StudyUtils;
 import com.jetbrains.python.edu.course.TaskWindow;
-import icons.StudyIcons;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
@@ -16,7 +16,7 @@
   public static final String SHORTCUT2 = "ctrl pressed ENTER";
 
   public StudyNextWindowAction() {
-    super("NextWindowAction", "Select next window", StudyIcons.Next);
+    super("NextWindowAction", "Select next window", AllIcons.Actions.Forward);
   }
 
   @Override
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPreviousStudyTaskAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPreviousStudyTaskAction.java
index bc26c28..f6da6a0 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPreviousStudyTaskAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPreviousStudyTaskAction.java
@@ -3,13 +3,14 @@
 
 import com.jetbrains.python.edu.editor.StudyEditor;
 import com.jetbrains.python.edu.course.Task;
+import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
 
 public class StudyPreviousStudyTaskAction extends StudyTaskNavigationAction {
 
   @Override
-  protected JButton getButton(StudyEditor selectedStudyEditor) {
+  protected JButton getButton(@NotNull final StudyEditor selectedStudyEditor) {
     return selectedStudyEditor.getPrevTaskButton();
   }
 
@@ -19,7 +20,7 @@
   }
 
   @Override
-  protected Task getTargetTask(Task sourceTask) {
+  protected Task getTargetTask(@NotNull final Task sourceTask) {
     return sourceTask.prev();
   }
 }
\ No newline at end of file
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskFileAction.java
similarity index 90%
rename from python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskAction.java
rename to python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskFileAction.java
index f8abb0b..a9448dd 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskFileAction.java
@@ -14,6 +14,7 @@
 import com.intellij.openapi.ui.popup.Balloon;
 import com.intellij.openapi.ui.popup.BalloonBuilder;
 import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.wm.IdeFocusManager;
 import com.jetbrains.python.edu.StudyDocumentListener;
@@ -24,8 +25,8 @@
 
 import java.io.*;
 
-public class StudyRefreshTaskAction extends DumbAwareAction {
-  private static final Logger LOG = Logger.getInstance(StudyRefreshTaskAction.class.getName());
+public class StudyRefreshTaskFileAction extends DumbAwareAction {
+  private static final Logger LOG = Logger.getInstance(StudyRefreshTaskFileAction.class.getName());
 
   public void refresh(final Project project) {
         ApplicationManager.getApplication().invokeLater(new Runnable() {
@@ -92,14 +93,20 @@
                     document.addDocumentListener(listener);
                   }
                   selectedTaskFile.drawAllWindows(editor);
-                  IdeFocusManager.getInstance(project).requestFocus(editor.getContentComponent(), true);
+                  ApplicationManager.getApplication().invokeLater(new Runnable() {
+                    @Override
+                    public void run() {
+                      IdeFocusManager.getInstance(project).requestFocus(editor.getContentComponent(), true);
+                    }
+                  });
                   selectedTaskFile.navigateToFirstTaskWindow(editor);
                   BalloonBuilder balloonBuilder =
                     JBPopupFactory.getInstance().createHtmlTextBalloonBuilder("You can now start again", MessageType.INFO, null);
-                  Balloon balloon = balloonBuilder.createBalloon();
+                  final Balloon balloon = balloonBuilder.createBalloon();
                   StudyEditor selectedStudyEditor = StudyEditor.getSelectedStudyEditor(project);
                   assert selectedStudyEditor != null;
                   balloon.showInCenterOf(selectedStudyEditor.getRefreshButton());
+                  Disposer.register(project, balloon);
                 }
                 catch (FileNotFoundException e1) {
                   LOG.error(e1);
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java
index 1efa908..2952486 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java
@@ -5,19 +5,18 @@
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.LogicalPosition;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.popup.JBPopup;
 import com.intellij.openapi.ui.popup.JBPopupFactory;
-import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.util.Disposer;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.PsiManager;
+import com.jetbrains.python.edu.StudyState;
 import com.jetbrains.python.edu.StudyTaskManager;
 import com.jetbrains.python.edu.StudyUtils;
 import com.jetbrains.python.edu.course.Course;
-import com.jetbrains.python.edu.course.TaskFile;
 import com.jetbrains.python.edu.course.TaskWindow;
 import com.jetbrains.python.edu.editor.StudyEditor;
 import icons.StudyIcons;
@@ -33,58 +32,56 @@
   }
 
   public void actionPerformed(AnActionEvent e) {
-    Project project = e.getProject();
-    if (project != null) {
+    final Project project = e.getProject();
+    if (project == null) {
+      return;
+    }
+    Course course = StudyTaskManager.getInstance(project).getCourse();
+    if (course == null) {
+      return;
+    }
+    StudyState studyState = new StudyState(StudyEditor.getSelectedStudyEditor(project));
+    if (!studyState.isValid()) {
+      return;
+    }
+    PsiFile file = PsiManager.getInstance(project).findFile(studyState.getVirtualFile());
+    final Editor editor = studyState.getEditor();
+    LogicalPosition pos = editor.getCaretModel().getLogicalPosition();
+    TaskWindow taskWindow = studyState.getTaskFile().getTaskWindow(editor.getDocument(), pos);
+    if (file == null || taskWindow == null) {
+      return;
+    }
+    String hint = taskWindow.getHint();
+    if (hint == null) {
+      return;
+    }
+    File resourceFile = new File(course.getResourcePath());
+    File resourceRoot = resourceFile.getParentFile();
+    if (resourceRoot == null || !resourceRoot.exists()) {
+      return;
+    }
+    File hintsDir = new File(resourceRoot, Course.HINTS_DIR);
+    if (hintsDir.exists()) {
+      String hintText = StudyUtils.getFileText(hintsDir.getAbsolutePath(), hint, true);
+      int offset = editor.getDocument().getLineStartOffset(pos.line) + pos.column;
+      PsiElement element = file.findElementAt(offset);
+      if (hintText == null || element == null) {
+        return;
+      }
+
       DocumentationManager documentationManager = DocumentationManager.getInstance(project);
       DocumentationComponent component = new DocumentationComponent(documentationManager);
-      Editor selectedEditor = StudyEditor.getSelectedEditor(project);
-      FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
-      assert selectedEditor != null;
-      VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
-      if (openedFile != null) {
-        StudyTaskManager taskManager = StudyTaskManager.getInstance(e.getProject());
-        TaskFile taskFile = taskManager.getTaskFile(openedFile);
-        if (taskFile != null) {
-          PsiFile file = PsiManager.getInstance(project).findFile(openedFile);
-          if (file != null) {
-            LogicalPosition pos = selectedEditor.getCaretModel().getLogicalPosition();
-            TaskWindow taskWindow = taskFile.getTaskWindow(selectedEditor.getDocument(), pos);
-            if (taskWindow != null) {
-              String hint = taskWindow.getHint();
-              if (hint == null) {
-                return;
-              }
-              Course course = taskManager.getCourse();
-              if (course != null) {
-                File resourceFile = new File(course.getResourcePath());
-                File resourceRoot = resourceFile.getParentFile();
-                if (resourceRoot != null && resourceRoot.exists()) {
-                  File hintsDir = new File(resourceRoot, Course.HINTS_DIR);
-                  if (hintsDir.exists()) {
-                    String hintText = StudyUtils.getFileText(hintsDir.getAbsolutePath(), hint, true);
-                    if (hintText != null) {
-                      int offset = selectedEditor.getDocument().getLineStartOffset(pos.line) + pos.column;
-                      PsiElement element = file.findElementAt(offset);
-                      if (element != null) {
-                        component.setData(element, hintText, true, null);
-                        final JBPopup popup =
-                          JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
-                            .setDimensionServiceKey(project, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false)
-                            .setResizable(true)
-                            .setMovable(true)
-                            .setRequestFocus(true)
-                            .createPopup();
-                        component.setHint(popup);
-                        popup.showInBestPositionFor(selectedEditor);
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
+      component.setData(element, hintText, true, null);
+      final JBPopup popup =
+        JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
+          .setDimensionServiceKey(project, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false)
+          .setResizable(true)
+          .setMovable(true)
+          .setRequestFocus(true)
+          .createPopup();
+      component.setHint(popup);
+      popup.showInBestPositionFor(editor);
+      Disposer.dispose(component);
     }
   }
 
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java
index b781e7d..46c0981 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java
@@ -1,8 +1,6 @@
 package com.jetbrains.python.edu.actions;
 
 import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
@@ -11,37 +9,34 @@
 import com.intellij.openapi.ui.popup.BalloonBuilder;
 import com.intellij.openapi.ui.popup.JBPopupFactory;
 import com.intellij.openapi.vfs.VirtualFile;
-import com.jetbrains.python.edu.StudyTaskManager;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.jetbrains.python.edu.StudyState;
 import com.jetbrains.python.edu.course.Lesson;
 import com.jetbrains.python.edu.course.Task;
 import com.jetbrains.python.edu.course.TaskFile;
 import com.jetbrains.python.edu.editor.StudyEditor;
+import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
 import java.util.Map;
 
-/**
- * author: liana
- * data: 7/21/14.
- */
+
 abstract public class StudyTaskNavigationAction extends DumbAwareAction {
-  public void navigateTask(Project project) {
-    Editor selectedEditor = StudyEditor.getSelectedEditor(project);
-    FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
-    assert selectedEditor != null;
-    VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
-    StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
-    assert openedFile != null;
-    TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
-    assert selectedTaskFile != null;
-    Task currentTask = selectedTaskFile.getTask();
-    Task nextTask = getTargetTask(currentTask);
+  public void navigateTask(@NotNull final Project project) {
+    StudyEditor studyEditor = StudyEditor.getSelectedStudyEditor(project);
+    StudyState studyState = new StudyState(studyEditor);
+    if (!studyState.isValid()) {
+      return;
+    }
+    Task nextTask = getTargetTask(studyState.getTask());
     if (nextTask == null) {
       BalloonBuilder balloonBuilder =
         JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(getNavigationFinishedMessage(), MessageType.INFO, null);
       Balloon balloon = balloonBuilder.createBalloon();
-      StudyEditor selectedStudyEditor = StudyEditor.getSelectedStudyEditor(project);
-      balloon.showInCenterOf(getButton(selectedStudyEditor));
+      assert studyEditor != null;
+      balloon.showInCenterOf(getButton(studyEditor));
       return;
     }
     for (VirtualFile file : FileEditorManager.getInstance(project).getOpenFiles()) {
@@ -82,16 +77,24 @@
     if (shouldBeActive != null) {
       FileEditorManager.getInstance(project).openFile(shouldBeActive, true);
     }
+    ToolWindow runToolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.RUN);
+    if (runToolWindow != null) {
+      runToolWindow.hide(null);
+    }
   }
 
-  protected abstract JButton getButton(StudyEditor selectedStudyEditor);
+  protected abstract JButton getButton(@NotNull final StudyEditor selectedStudyEditor);
 
   @Override
   public void actionPerformed(AnActionEvent e) {
-    navigateTask(e.getProject());
+    Project project = e.getProject();
+    if (project == null) {
+      return;
+    }
+    navigateTask(project);
   }
 
   protected abstract String getNavigationFinishedMessage();
 
-  protected abstract Task getTargetTask(Task sourceTask);
+  protected abstract Task getTargetTask(@NotNull final Task sourceTask);
 }
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java b/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java
index 4f17fc0..c46c4f5 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java
@@ -21,7 +21,7 @@
  * which is visible to student in project view
  */
 
-public class TaskFile implements Stateful{
+public class TaskFile implements Stateful {
   public List<TaskWindow> taskWindows = new ArrayList<TaskWindow>();
   private Task myTask;
   @Transient
@@ -173,7 +173,18 @@
     for (TaskWindow w : taskWindows) {
       if ((w.getLine() == line) && (w.getStart() >= oldEndOffsetInLine)) {
         int distance = w.getStart() - oldEndOffsetInLine;
-        if (lineChange != 0 || newEndOffsetInLine <= w.getStart()) {
+        boolean coveredByPrevTW = false;
+        int prevIndex = w.getIndex() - 1;
+        if (StudyUtils.indexIsValid(prevIndex, taskWindows)) {
+          TaskWindow prevTW = taskWindows.get(prevIndex);
+          if (prevTW.getLine() == line) {
+            int endOffset = prevTW.getStart() + prevTW.getLength();
+            if (endOffset >= newEndOffsetInLine) {
+              coveredByPrevTW = true;
+            }
+          }
+        }
+        if (lineChange != 0 || newEndOffsetInLine <= w.getStart() || coveredByPrevTW) {
           w.setStart(distance + newEndOffsetInLine);
           w.setLine(line + lineChange);
         }
@@ -217,12 +228,33 @@
   public void navigateToFirstTaskWindow(@NotNull final Editor editor) {
     if (!taskWindows.isEmpty()) {
       TaskWindow firstTaskWindow = StudyUtils.getFirst(taskWindows);
-      mySelectedTaskWindow = firstTaskWindow;
-      LogicalPosition taskWindowStart = new LogicalPosition(firstTaskWindow.getLine(), firstTaskWindow.getStart());
-      editor.getCaretModel().moveToLogicalPosition(taskWindowStart);
-      int startOffset = firstTaskWindow.getRealStartOffset(editor.getDocument());
-      int endOffset = startOffset + firstTaskWindow.getLength();
-      editor.getSelectionModel().setSelection(startOffset, endOffset);
+      navigateToTaskWindow(editor, firstTaskWindow);
     }
   }
+
+  private void navigateToTaskWindow(@NotNull final Editor editor, @NotNull final TaskWindow firstTaskWindow) {
+    if (!firstTaskWindow.isValid(editor.getDocument())) {
+      return;
+    }
+    mySelectedTaskWindow = firstTaskWindow;
+    LogicalPosition taskWindowStart = new LogicalPosition(firstTaskWindow.getLine(), firstTaskWindow.getStart());
+    editor.getCaretModel().moveToLogicalPosition(taskWindowStart);
+    int startOffset = firstTaskWindow.getRealStartOffset(editor.getDocument());
+    int endOffset = startOffset + firstTaskWindow.getLength();
+    editor.getSelectionModel().setSelection(startOffset, endOffset);
+  }
+
+  public void navigateToFirstFailedTaskWindow(@NotNull final Editor editor) {
+    for (TaskWindow taskWindow : taskWindows) {
+      if (taskWindow.getStatus() != StudyStatus.Failed) {
+        continue;
+      }
+      navigateToTaskWindow(editor, taskWindow);
+      break;
+    }
+  }
+
+  public boolean hasFailedTaskWindows() {
+    return taskWindows.size() > 0 && getStatus() == StudyStatus.Failed;
+  }
 }
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskWindow.java b/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskWindow.java
index 4fb112c..dc4a75a 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskWindow.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskWindow.java
@@ -1,5 +1,8 @@
 package com.jetbrains.python.edu.course;
 
+import com.intellij.execution.ExecutionException;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.colors.EditorColors;
@@ -8,16 +11,27 @@
 import com.intellij.openapi.editor.markup.HighlighterTargetArea;
 import com.intellij.openapi.editor.markup.RangeHighlighter;
 import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.ui.JBColor;
+import com.jetbrains.python.edu.StudyDocumentListener;
+import com.jetbrains.python.edu.StudyTestRunner;
+import com.jetbrains.python.edu.StudyUtils;
 import org.jetbrains.annotations.NotNull;
 
+import java.io.File;
+import java.io.IOException;
+
 /**
  * Implementation of windows which user should type in
  */
 
 
 public class TaskWindow implements Comparable, Stateful {
-
+  private static final String WINDOW_POSTFIX = "_window.py";
+  private static final Logger LOG = Logger.getInstance(TaskWindow.class);
   public int line = 0;
   public int start = 0;
   public String hint = "";
@@ -174,4 +188,55 @@
   public int getIndex() {
     return myIndex;
   }
+
+  public void smartCheck(@NotNull final Project project,
+                         @NotNull final VirtualFile answerFile,
+                         @NotNull final TaskFile answerTaskFile,
+                         @NotNull final TaskFile usersTaskFile,
+                         @NotNull final StudyTestRunner testRunner,
+                         @NotNull final VirtualFile virtualFile,
+                         @NotNull final Document usersDocument) {
+
+    try {
+      VirtualFile windowCopy =
+        answerFile.copy(this, answerFile.getParent(), answerFile.getNameWithoutExtension() + WINDOW_POSTFIX);
+      final FileDocumentManager documentManager = FileDocumentManager.getInstance();
+      final Document windowDocument = documentManager.getDocument(windowCopy);
+      if (windowDocument != null) {
+        File resourceFile = StudyUtils.copyResourceFile(virtualFile.getName(), windowCopy.getName(), project, usersTaskFile.getTask());
+        TaskFile windowTaskFile = new TaskFile();
+        TaskFile.copy(answerTaskFile, windowTaskFile);
+        StudyDocumentListener listener = new StudyDocumentListener(windowTaskFile);
+        windowDocument.addDocumentListener(listener);
+        int start = getRealStartOffset(windowDocument);
+        int end = start + getLength();
+        TaskWindow userTaskWindow = usersTaskFile.getTaskWindows().get(getIndex());
+        int userStart = userTaskWindow.getRealStartOffset(usersDocument);
+        int userEnd = userStart + userTaskWindow.getLength();
+        String text = usersDocument.getText(new TextRange(userStart, userEnd));
+        windowDocument.replaceString(start, end, text);
+        ApplicationManager.getApplication().runWriteAction(new Runnable() {
+          @Override
+          public void run() {
+            documentManager.saveDocument(windowDocument);
+          }
+        });
+        VirtualFile fileWindows = StudyUtils.flushWindows(windowTaskFile, windowCopy);
+        Process smartTestProcess = testRunner.launchTests(project, windowCopy.getPath());
+        boolean res = testRunner.getPassedTests(smartTestProcess).equals(StudyTestRunner.TEST_OK);
+        userTaskWindow.setStatus(res ? StudyStatus.Solved : StudyStatus.Failed, StudyStatus.Unchecked);
+        StudyUtils.deleteFile(windowCopy);
+        StudyUtils.deleteFile(fileWindows);
+        if (!resourceFile.delete()) {
+          LOG.error("failed to delete", resourceFile.getPath());
+        }
+      }
+    }
+    catch (ExecutionException e) {
+      LOG.error(e);
+    }
+    catch (IOException e) {
+      LOG.error(e);
+    }
+  }
 }
\ No newline at end of file
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java b/python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java
index 69c5acc..6b27c4a 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java
@@ -1,8 +1,10 @@
 package com.jetbrains.python.edu.editor;
 
 import com.intellij.codeHighlighting.BackgroundEditorHighlighter;
+import com.intellij.icons.AllIcons;
 import com.intellij.ide.structureView.StructureViewBuilder;
 import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.EditorFactory;
@@ -17,9 +19,15 @@
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
 import com.intellij.pom.Navigatable;
+import com.intellij.ui.BrowserHyperlinkListener;
 import com.intellij.ui.HideableTitledPanel;
 import com.intellij.ui.JBColor;
+import com.intellij.util.ui.EmptyClipboardOwner;
 import com.intellij.util.ui.UIUtil;
 import com.jetbrains.python.edu.StudyDocumentListener;
 import com.jetbrains.python.edu.StudyTaskManager;
@@ -36,8 +44,8 @@
 import javax.swing.text.StyleConstants;
 import javax.swing.text.StyledDocument;
 import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import java.awt.datatransfer.StringSelection;
+import java.awt.event.*;
 import java.beans.PropertyChangeListener;
 import java.util.HashMap;
 import java.util.Map;
@@ -50,12 +58,13 @@
   private static final String TASK_TEXT_HEADER = "Task Text";
   private final FileEditor myDefaultEditor;
   private final JComponent myComponent;
+  private final TaskFile myTaskFile;
   private JButton myCheckButton;
   private JButton myNextTaskButton;
   private JButton myPrevTaskButton;
   private JButton myRefreshButton;
   private static final Map<Document, StudyDocumentListener> myDocumentListeners = new HashMap<Document, StudyDocumentListener>();
-  private Project myProject;
+  private final Project myProject;
 
   public JButton getCheckButton() {
     return myCheckButton;
@@ -65,6 +74,10 @@
     return myPrevTaskButton;
   }
 
+  public TaskFile getTaskFile() {
+    return myTaskFile;
+  }
+
   private static JButton addButton(@NotNull final JComponent parentComponent, String toolTipText, Icon icon) {
     JButton newButton = new JButton();
     newButton.setToolTipText(toolTipText);
@@ -89,26 +102,72 @@
     myComponent = myDefaultEditor.getComponent();
     JPanel studyPanel = new JPanel();
     studyPanel.setLayout(new BoxLayout(studyPanel, BoxLayout.Y_AXIS));
-    TaskFile taskFile = StudyTaskManager.getInstance(myProject).getTaskFile(file);
-    if (taskFile != null) {
-      Task currentTask = taskFile.getTask();
+    myTaskFile = StudyTaskManager.getInstance(myProject).getTaskFile(file);
+    if (myTaskFile != null) {
+      Task currentTask = myTaskFile.getTask();
       String taskText = currentTask.getResourceText(project, currentTask.getText(), false);
       initializeTaskText(studyPanel, taskText);
       JPanel studyButtonPanel = new JPanel(new GridLayout(1, 2));
       JPanel taskActionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
       studyButtonPanel.add(taskActionsPanel);
       studyButtonPanel.add(new JPanel());
-      initializeButtons(taskActionsPanel, taskFile);
+      initializeButtons(taskActionsPanel, myTaskFile);
       studyPanel.add(studyButtonPanel);
       myComponent.add(studyPanel, BorderLayout.NORTH);
     }
   }
 
-  private static void initializeTaskText(JPanel studyPanel, @Nullable String taskText) {
+  class CopyListener extends MouseAdapter {
+    final JTextPane myTextPane;
+
+    public CopyListener(JTextPane textPane) {
+      myTextPane = textPane;
+    }
+
+    @Override
+    public void mouseReleased(MouseEvent e) {
+      ApplicationManager.getApplication().invokeLater(new Runnable() {
+        @Override
+        public void run() {
+          ToolWindow projectView = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PROJECT_VIEW);
+          if (projectView == null) {
+            return;
+          }
+          final Component focusComponent = projectView.getComponent();
+          IdeFocusManager.getInstance(myProject).requestFocus(focusComponent, true);
+          final String text = myTextPane.getSelectedText();
+          if (text == null) {
+            return;
+          }
+          KeyAdapter keyAdapter = new KeyAdapter() {
+            @Override
+            public void keyPressed(KeyEvent ev) {
+              if (ev.getKeyCode() == KeyEvent.VK_C
+                  && ev.getModifiers() == InputEvent.CTRL_MASK) {
+                StringSelection selection = new StringSelection(text);
+                Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, EmptyClipboardOwner.INSTANCE);
+                ApplicationManager.getApplication().invokeLater(new Runnable() {
+                  @Override
+                  public void run() {
+                    IdeFocusManager.getInstance(myProject).requestFocus(myDefaultEditor.getComponent(), true);
+                  }
+                });
+              }
+            }
+          };
+          focusComponent.addKeyListener(keyAdapter);
+        }
+      });
+    }
+  }
+
+  private void initializeTaskText(JPanel studyPanel, @Nullable String taskText) {
     JTextPane taskTextPane = new JTextPane();
+    taskTextPane.addMouseListener(new CopyListener(taskTextPane));
     taskTextPane.setContentType("text/html");
     taskTextPane.setEditable(false);
     taskTextPane.setText(taskText);
+    taskTextPane.addHyperlinkListener(new BrowserHyperlinkListener());
     EditorColorsScheme editorColorsScheme = EditorColorsManager.getInstance().getGlobalScheme();
     int fontSize = editorColorsScheme.getEditorFontSize();
     String fontName = editorColorsScheme.getEditorFontName();
@@ -134,10 +193,10 @@
   private void initializeButtons(@NotNull final JPanel taskActionsPanel, @NotNull final TaskFile taskFile) {
     myCheckButton = addButton(taskActionsPanel, "Check task", StudyIcons.Resolve);
     myPrevTaskButton = addButton(taskActionsPanel, "Prev Task", StudyIcons.Prev);
-    myNextTaskButton = addButton(taskActionsPanel, "Next Task", StudyIcons.Next);
-    myRefreshButton = addButton(taskActionsPanel, "Start task again", StudyIcons.Refresh24);
+    myNextTaskButton = addButton(taskActionsPanel, "Next Task", AllIcons.Actions.Forward);
+    myRefreshButton = addButton(taskActionsPanel, "Start task again", AllIcons.Actions.Refresh);
     if (!taskFile.getTask().getUserTests().isEmpty()) {
-      JButton runButton = addButton(taskActionsPanel, "Run", StudyIcons.Run);
+      JButton runButton = addButton(taskActionsPanel, "Run", AllIcons.General.Run);
       runButton.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
@@ -149,7 +208,8 @@
       watchInputButton.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
-          StudyEditInputAction studyEditInputAction = (StudyEditInputAction)ActionManager.getInstance().getAction("WatchInputAction");
+          StudyEditInputAction studyEditInputAction =
+            (StudyEditInputAction)ActionManager.getInstance().getAction("WatchInputAction");
           studyEditInputAction.showInput(myProject);
         }
       });
@@ -165,7 +225,8 @@
     myNextTaskButton.addActionListener(new ActionListener() {
       @Override
       public void actionPerformed(ActionEvent e) {
-        StudyNextStudyTaskAction studyNextTaskAction = (StudyNextStudyTaskAction)ActionManager.getInstance().getAction("NextTaskAction");
+        StudyNextStudyTaskAction studyNextTaskAction =
+          (StudyNextStudyTaskAction)ActionManager.getInstance().getAction("NextTaskAction");
         studyNextTaskAction.navigateTask(myProject);
       }
     });
@@ -180,7 +241,8 @@
     myRefreshButton.addActionListener(new ActionListener() {
       @Override
       public void actionPerformed(ActionEvent e) {
-        StudyRefreshTaskAction studyRefreshTaskAction = (StudyRefreshTaskAction)ActionManager.getInstance().getAction("RefreshTaskAction");
+        StudyRefreshTaskFileAction studyRefreshTaskAction =
+          (StudyRefreshTaskFileAction)ActionManager.getInstance().getAction("RefreshTaskAction");
         studyRefreshTaskAction.refresh(myProject);
       }
     });
@@ -300,7 +362,8 @@
       if (fileEditor instanceof StudyEditor) {
         return (StudyEditor)fileEditor;
       }
-    } catch (Exception e) {
+    }
+    catch (Exception e) {
       return null;
     }
     return null;
@@ -325,8 +388,9 @@
   @NotNull
   @Override
   public Editor getEditor() {
-    if (myDefaultEditor instanceof TextEditor)
+    if (myDefaultEditor instanceof TextEditor) {
       return ((TextEditor)myDefaultEditor).getEditor();
+    }
     return EditorFactory.getInstance().createViewer(new DocumentImpl(""), myProject);
   }
 
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/highlighting/StudyVisitorFilter.java b/python/edu/learn-python/src/com/jetbrains/python/edu/highlighting/StudyVisitorFilter.java
new file mode 100644
index 0000000..dc7495a
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/highlighting/StudyVisitorFilter.java
@@ -0,0 +1,18 @@
+package com.jetbrains.python.edu.highlighting;
+
+import com.intellij.psi.PsiFile;
+import com.jetbrains.python.edu.StudyTaskManager;
+import com.jetbrains.python.inspections.PythonVisitorFilter;
+import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
+import org.jetbrains.annotations.NotNull;
+
+public class StudyVisitorFilter implements PythonVisitorFilter {
+  @Override
+  public boolean isSupported(@NotNull final Class visitorClass, @NotNull final PsiFile file) {
+    if (StudyTaskManager.getInstance(file.getProject()).getCourse() == null) return true;
+    if (visitorClass == PyUnresolvedReferencesInspection.class) {
+      return false;
+    }
+    return true;
+  }
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java b/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java
index abf648c..2f80dba 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java
@@ -32,7 +32,7 @@
 
   @Override
   protected void updateImpl(PresentationData data) {
-    data.setIcon(StudyIcons.Unchecked);
+    data.setIcon(StudyIcons.Task);
     String valueName = myValue.getName();
     StudyTaskManager studyTaskManager = StudyTaskManager.getInstance(myProject);
     Course course = studyTaskManager.getCourse();
@@ -41,7 +41,7 @@
     }
     if (valueName.equals(myProject.getName())) {
       data.clearText();
-      data.addText(course.getName(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, JBColor.BLUE));
+      data.addText(course.getName(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, JBColor.BLACK));
       data.addText(" (" + valueName + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
       return;
     }
@@ -91,15 +91,16 @@
     StudyStatus taskStatus = stateful.getStatus();
     switch (taskStatus) {
       case Unchecked: {
-        updatePresentation(data, additionalName, JBColor.blue, StudyIcons.Unchecked);
+        updatePresentation(data, additionalName, JBColor.BLACK, stateful instanceof Lesson ? StudyIcons.Lesson : StudyIcons.Task);
         break;
       }
       case Solved: {
-        updatePresentation(data, additionalName, new JBColor(new Color(0, 134, 0), new Color(98, 150, 85)), StudyIcons.Checked);
+        updatePresentation(data, additionalName, new JBColor(new Color(0, 134, 0), new Color(98, 150, 85)),
+                           stateful instanceof Lesson ? StudyIcons.LessonCompl : StudyIcons.TaskCompl);
         break;
       }
       case Failed: {
-        updatePresentation(data, additionalName, JBColor.RED, StudyIcons.Failed);
+        updatePresentation(data, additionalName, JBColor.RED, stateful instanceof Lesson ? StudyIcons.Lesson : StudyIcons.TaskProbl);
       }
     }
   }
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form
index 133c38d..8dd6506 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form
@@ -39,11 +39,9 @@
           </component>
         </children>
       </grid>
-      <component id="6c40c" class="javax.swing.JLabel">
+      <component id="6c40c" class="javax.swing.JLabel" binding="myLabel">
         <constraints>
-          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
-            <preferred-size width="81" height="-1"/>
-          </grid>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <font/>
@@ -67,9 +65,7 @@
       </component>
       <component id="f1e10" class="javax.swing.JButton" binding="myRefreshButton">
         <constraints>
-          <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
-            <minimum-size width="30" height="23"/>
-          </grid>
+          <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
           <hideActionText value="false"/>
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java
index 0f1ec08..6edad63 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java
@@ -2,6 +2,7 @@
 
 import com.intellij.facet.ui.FacetValidatorsManager;
 import com.intellij.facet.ui.ValidationResult;
+import com.intellij.icons.AllIcons;
 import com.intellij.openapi.fileChooser.FileChooser;
 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -9,7 +10,6 @@
 import com.jetbrains.python.edu.StudyDirectoryProjectGenerator;
 import com.jetbrains.python.edu.StudyUtils;
 import com.jetbrains.python.edu.course.CourseInfo;
-import icons.StudyIcons;
 
 import javax.swing.*;
 import java.awt.event.ActionEvent;
@@ -32,6 +32,7 @@
   private JPanel myContentPanel;
   private JLabel myAuthorLabel;
   private JLabel myDescriptionLabel;
+  private JLabel myLabel;
   private final StudyDirectoryProjectGenerator myGenerator;
   private static final String CONNECTION_ERROR = "<html>Failed to download courses.<br>Check your Internet connection.</html>";
   private static final String INVALID_COURSE = "Selected course is invalid";
@@ -56,7 +57,9 @@
     }
     initListeners();
     myRefreshButton.setVisible(true);
-    myRefreshButton.setIcon(StudyIcons.Refresh);
+    myRefreshButton.setIcon(AllIcons.Actions.Refresh);
+
+    myLabel.setPreferredSize(new JLabel("Project name").getPreferredSize());
   }
 
   private void initListeners() {