diff --git a/db/migrations/stored/R__functions.sql b/db/migrations/stored/R__functions.sql
index 85b866306b9b8c493b7c3cc4b6f896eae05e4d86..562f2b1adac93425a2233c1b3d8a7542b981e909 100644
--- a/db/migrations/stored/R__functions.sql
+++ b/db/migrations/stored/R__functions.sql
@@ -162,33 +162,36 @@ DROP FUNCTION IF EXISTS CreateGroup//
 CREATE FUNCTION CreateGroup (
     pGradeID INT,
     pGroupNum INT,
-    pSpecializationID INT,
-    pGroupName VARCHAR(50) CHARSET utf8,
+    pSpecName VARCHAR(200) CHARSET utf8,
+    pFacultyID INT,
     pYear INT
 ) RETURNS int(11) # group id
 NO SQL
 BEGIN
-    DECLARE vGroupID, vFacultyID, vGroupYear, vIsSpecMatch INT DEFAULT -1;
+    DECLARE vGroupID, vSpecId, vGroupYear, vIsSpecMatch INT DEFAULT -1;
     DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1;
 
-    SET vFacultyID = (SELECT FacultyID FROM specializations WHERE specializations.ID = pSpecializationID LIMIT 1);
+    # create specialization
+    INSERT INTO specializations (Name, Abbr, FacultyID) VALUES  (pSpecName, NULL, pFacultyID)
+    ON DUPLICATE KEY UPDATE
+        specializations.ID = LAST_INSERT_ID(specializations.ID);
+    SET vSpecId = LAST_INSERT_ID();
 
-    # create discipline
-    INSERT INTO study_groups (GradeID, GroupNum, FacultyID) VALUES (pGradeID, pGroupNum, vFacultyID)
+    # create group
+    INSERT INTO study_groups (GradeID, GroupNum, FacultyID) VALUES (pGradeID, pGroupNum, pFacultyID)
         ON DUPLICATE KEY UPDATE
             study_groups.ID = LAST_INSERT_ID(study_groups.ID);
     SET vGroupID = LAST_INSERT_ID();
 
-    SELECT groups_years.GroupID, (groups_years.SpecializationID = pSpecializationID AND
-                                  (pGroupName IS NULL OR groups_years.Name <=> pGroupName))
+    SELECT groups_years.GroupID, groups_years.SpecializationID = vSpecId
         INTO vGroupYear, vIsSpecMatch
         FROM groups_years
         WHERE groups_years.GroupID = vGroupID AND groups_years.Year = pYear
         LIMIT 1;
 
     IF vGroupYear = -1 THEN
-        INSERT INTO groups_years (GroupID, Year, SpecializationID, Name)
-        VALUES (vGroupID, pYear, pSpecializationID, pGroupName);
+        INSERT INTO groups_years (GroupID, Year, SpecializationID)
+        VALUES (vGroupID, pYear, vSpecId);
     ELSEIF NOT vIsSpecMatch THEN
         RETURN -1;
     END IF;
@@ -245,7 +248,10 @@ BEGIN
     # create/get subject (subject name is unique key)
     INSERT INTO subjects (Name, Abbr, ExternalID) VALUES (pSubjectName, pSubjectAbbr, pExternalID)
         ON DUPLICATE KEY UPDATE
-            subjects.ID = LAST_INSERT_ID(subjects.ID);
+            subjects.ID = LAST_INSERT_ID(subjects.ID),
+            subjects.Name = pSubjectName,
+            subjects.Abbr = COALESCE(pSubjectAbbr, subjects.Abbr),
+            subjects.ExternalID = COALESCE(pExternalID, subjects.ExternalID);
     SET vSubjectID = LAST_INSERT_ID();
 
     BEGIN # handler block
@@ -719,18 +725,12 @@ CREATE FUNCTION CreateStudentEx (
 )   RETURNS int(11)
 NO SQL
 BEGIN
-    DECLARE vAccountID, vGradeID, vSpecID, vGroupID, vYear INT DEFAULT -1;
+    DECLARE vGradeID, vGroupID, vYear INT DEFAULT -1;
     DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1;
 
-    # get specialization id
-    INSERT INTO specializations (Name, Abbr, FacultyID) VALUES  (pSpecName, NULL, pFacultyID)
-        ON DUPLICATE KEY UPDATE
-            specializations.ID = LAST_INSERT_ID(specializations.ID);
-    SET vSpecID = LAST_INSERT_ID();
-
     SET vYear = COALESCE((SELECT Year FROM semesters WHERE semesters.ID = pSemesterID LIMIT 1), -1);
     SET vGradeID = CreateGrade(pGradeNum, pDegree);
-    SET vGroupID = CreateGroup(vGradeID, pGroupNum, vSpecID, NULL, vYear);
+    SET vGroupID = CreateGroup(vGradeID, pGroupNum, pSpecName, pFacultyID, vYear);
     RETURN CreateStudent(pLastName, pFirstName, pSecondName, vGroupID, pActivationCode, pSemesterID);
 END //
 
diff --git a/media/less/common.less b/media/less/common.less
index b1f1c3ca1405900a0475f9ac26a407d0572859b7..633ce67ed3d109c8aa22d381556a3cd26ba3d86d 100644
--- a/media/less/common.less
+++ b/media/less/common.less
@@ -238,12 +238,9 @@ input[type="checkbox"] {
         display: inline;
         text-align: right;
         float: right;
-        > div {
+        > * {
             display: inline-block;
-            margin: 0 5px;
-        }
-        a {
-            margin-left: 5px;
+            margin-left: 10px;
         }
     }
 }
@@ -342,23 +339,38 @@ input[type="checkbox"] {
 }
 
 .semesterLayer {
+    position: relative;
     display: inline-block;
     width: auto;
-    .semesterChanger, .semesterSwitcherBtn {
-        //margin-left: 0px;
-        font-family: @FontFamily;
-        font-size: 1em;
+    text-align: left;
+    font-family: @FontFamily;
+    font-size: 1em;
+
+    .semesterChanger {
+        text-align: right;
+
+        > * {
+            position: relative;
+            display: inline-block;
+
+            &:not(:last-child) {
+                margin-right: 5px;
+            }
+        }
     }
+
     .semesterSwitcher {
         display: block;
         padding: 10px;
         overflow: hidden;
         .modalWindow(auto);
+        min-width: 160px;
         margin-top: 5px;
         background: @ColorBaseWhite;
         border: 1px solid @ColorBaseGrey;
         .box-shadow(0 0 5px, @ColorGrey);
         .radius(5px);
+
         li {
             margin-bottom: 5px;
             &:last-child { margin-bottom: 0; }
@@ -371,22 +383,35 @@ input[type="checkbox"] {
     display: inline-block;
     width: auto;
     text-align: left;
-    .recordBookChanger, .recordBookSwitcherBtn {
-        //margin-left: 0px;
-        font-family: @FontFamily;
-        font-size: 1em;
+    font-family: @FontFamily;
+    font-size: 1em;
+
+    .recordBookChanger {
+        text-align: right;
+
+        > * {
+            position: relative;
+            display: inline-block;
+
+            &:not(:last-child) {
+                margin-right: 5px;
+            }
+        }
     }
+
     .recordBookSwitcher {
         display: block;
         padding: 10px;
         overflow: hidden;
         .modalWindow(auto);
         right: 0;
+        min-width: 160px;
         margin-top: 5px;
         background: @ColorBaseWhite;
         border: 1px solid @ColorBaseGrey;
         .box-shadow(0 0 5px, @ColorGrey);
         .radius(5px);
+
         li {
             margin-bottom: 5px;
             &:last-child { margin-bottom: 0; }
diff --git a/media/less/js/event_inspector.less b/media/less/js/event_inspector.less
index 2083b25833fffbbc74fe3b8dcb90dc50648e655c..f47b49a6abce045b07af60bbf3524855399e2d18 100644
--- a/media/less/js/event_inspector.less
+++ b/media/less/js/event_inspector.less
@@ -3,6 +3,7 @@
 
 .EventInspectorList {
   position: fixed;
+  z-index: 10000;
   height: auto;
   min-width: 200px;
   width: 15%;
diff --git a/media/less/student/index.less b/media/less/student/index.less
index efcf02dd871c3c7a4f197ed23bfc679d06285a7b..200ff2103eb04d9c0db13b76c21d6275be7b2f6c 100644
--- a/media/less/student/index.less
+++ b/media/less/student/index.less
@@ -111,12 +111,45 @@
     
     .header_wrapper {
         padding: 9pt 10px;
+
+        .logotype {
+            margin-right: 10px;
+        }
         
         .logotype span, #username {
             display: none;
         }
     }
-    
+
+    .semesterLayer {
+        .semesterChangerTitle {
+            display: none;
+        }
+    }
+
+    .recordBookLayer {
+        .recordBookChangerTitle {
+            display: none;
+        }
+
+        .recordBookChangerSelection {
+            width: calc(~"100vw - 235px");
+            overflow: hidden;
+            white-space: nowrap;
+            direction: rtl;
+
+            &:before {
+                content: '';
+                position: absolute;
+                left: 0;
+                top: 0;
+                width: 10px;
+                height: 100%;
+                background: linear-gradient(to right, @ColorBaseWhite, fade(@ColorBaseWhite, 0%));
+            }
+        }
+    }
+
     div.window {
         min-width: initial !important;
         
diff --git a/media/less/student/subject.less b/media/less/student/subject.less
index afb65318d3f88ced536ebc2dbebb70568b71ca1d..426a1bdf2a340d020adaae691eaa8915cc5d8fa8 100644
--- a/media/less/student/subject.less
+++ b/media/less/student/subject.less
@@ -164,11 +164,44 @@ h3.blockTitle
     .header_wrapper {
         padding: 9pt 10px;
 
+        .logotype {
+            margin-right: 10px;
+        }
+
         .logotype span, #username {
             display: none;
         }
     }
 
+    .semesterLayer {
+        .semesterChangerTitle {
+            display: none;
+        }
+    }
+
+    .recordBookLayer {
+        .recordBookChangerTitle {
+            display: none;
+        }
+
+        .recordBookChangerSelection {
+            width: calc(~"100vw - 235px");
+            overflow: hidden;
+            white-space: nowrap;
+            direction: rtl;
+
+            &:before {
+                content: '';
+                position: absolute;
+                left: 0;
+                top: 0;
+                width: 10px;
+                height: 100%;
+                background: linear-gradient(to right, @ColorBaseWhite, fade(@ColorBaseWhite, 0%));
+            }
+        }
+    }
+
     div.window {
         min-width: initial !important;
 
diff --git a/~dev_rating/application/classes/Controller/Api/V0/Student.php b/~dev_rating/application/classes/Controller/Api/V0/Student.php
index 29e32c19d9fd2aff0ef530ba538428ee66abb9ba..59fedd5837036db1038f1bdeda2ae17943d2c1d6 100644
--- a/~dev_rating/application/classes/Controller/Api/V0/Student.php
+++ b/~dev_rating/application/classes/Controller/Api/V0/Student.php
@@ -167,7 +167,14 @@ class Controller_Api_V0_Student extends Controller_Handler_Api {
                     throw new InvalidArgumentException('RecordBook: grade not found');
                 }
 
-                $group = Model_Group::find($gradeID, $recordBookData->group, $recordBookData->facultyID);
+                $speciality = $recordBookData->speciality;
+                if (strpos($speciality, ' - ') == 8) {
+                    $speciality = substr($speciality, 11);
+                }
+
+                $year = Model_Plan::load($recordBookData->planID)->Year;
+
+                $group = Model_Group::findOrCreate($gradeID, $recordBookData->group, $speciality, $recordBookData->facultyID, $year);
                 if (is_null($group)) {
                     throw new InvalidArgumentException('RecordBook: group not found');
                 }
diff --git a/~dev_rating/application/classes/Controller/Api/V0/StudyPlan.php b/~dev_rating/application/classes/Controller/Api/V0/StudyPlan.php
index fd256db602ffc3684b9effccbf95df05409931de..d959226b0657dfa219d705ce225ad980a29439ae 100644
--- a/~dev_rating/application/classes/Controller/Api/V0/StudyPlan.php
+++ b/~dev_rating/application/classes/Controller/Api/V0/StudyPlan.php
@@ -2,10 +2,6 @@
 
 class Controller_Api_V0_StudyPlan extends Controller_Handler_Api {
     private function normalizeDisciplinesData($disciplineData, $facultyID) {
-        if (!isset($disciplineData->subjectID) && isset($disciplineData->externalID)) {
-            $disciplineData->subjectID = Model_Subject::withExternalID($disciplineData->externalID, $disciplineData->name, '', $facultyID);
-        }
-
         foreach ($disciplineData->teachers as $teacherData) {
             if (empty($teacherData->hashSnils)) {
                 Log::instance()->add(Log::WARNING, '{0} {1}: {2}', array(
@@ -22,13 +18,7 @@ class Controller_Api_V0_StudyPlan extends Controller_Handler_Api {
         }
 
         if (empty($disciplineData->teacherIDs)) {
-            if (!empty($disciplineData->teachers)) {
-                Log::instance()->add(Log::WARNING, '{0} {1}: {2}', array(
-                    '{0}' => 'SYNC_DISCIPLINES',
-                    '{1}' => 'Discipline without teachers',
-                    '{2}' => json_encode($disciplineData),
-                ));
-            }
+            throw new InvalidArgumentException('Discipline without teachers');
         }
 
         switch ($disciplineData->type) {
@@ -45,6 +35,10 @@ class Controller_Api_V0_StudyPlan extends Controller_Handler_Api {
                 throw new InvalidArgumentException('Discipline has bad type');
         }
 
+        if (!isset($disciplineData->subjectID) && isset($disciplineData->externalID)) {
+            $disciplineData->subjectID = Model_Subject::withExternalID($disciplineData->externalID, $disciplineData->name, NULL, $facultyID);
+        }
+
         return $disciplineData;
     }
 
diff --git a/~dev_rating/application/classes/Model/Group.php b/~dev_rating/application/classes/Model/Group.php
index f4c759360b5649b297d60e815dd6a724f01baf38..e7d65539e0eeb9f805bfa326d4af221752350f51 100644
--- a/~dev_rating/application/classes/Model/Group.php
+++ b/~dev_rating/application/classes/Model/Group.php
@@ -14,12 +14,14 @@ class Model_Group extends Model
         return $g;
     }
 
-    public static function find($gradeID, $groupNum, $facultyID) {
-        $sql = 'SELECT `FindGroup`(:gradeID, :groupNum, :facultyID) AS `ID`';
+    public static function findOrCreate($gradeID, $groupNum, $specialization, $facultyID, $year) {
+        $sql = 'SELECT `CreateGroup`(:gradeID, :groupNum, :specialization, :facultyID, :year) AS `ID`';
         $id = DB::query(Database::SELECT, $sql)
             ->param(':gradeID', $gradeID)
             ->param(':groupNum', $groupNum)
+            ->param(':specialization', $specialization)
             ->param(':facultyID', $facultyID)
+            ->param(':year', $year)
             ->execute()->get('ID');
         if ($id <= 0) {
             return null;
diff --git a/~dev_rating/application/classes/Model/Subject.php b/~dev_rating/application/classes/Model/Subject.php
index 282b8b9145ad44a4cfc6b83352ba30f706aa3372..b7fa868f63c4999eec56d5c26b31e59f0fdfddf9 100644
--- a/~dev_rating/application/classes/Model/Subject.php
+++ b/~dev_rating/application/classes/Model/Subject.php
@@ -48,7 +48,7 @@ class Model_Subject
         return (int) $res->get('Num');
     }
 
-    public static function withExternalID($extID, $name='', $abbr='', $facultyID=null) {
+    public static function withExternalID($extID, $name, $abbr, $facultyID) {
         $sql = 'SELECT `Subject_GetByExternalID`(:extID) AS `ID`';
         $id = DB::query(Database::SELECT, $sql)
             ->param(':extID', $extID)
diff --git a/~dev_rating/application/views/base.twig b/~dev_rating/application/views/base.twig
index 9da3ef83619c68d4453c3a248c68dbffb45dc150..3b4536867fa15b1bbf5f5d3ff4ff3a3824f7b012 100644
--- a/~dev_rating/application/views/base.twig
+++ b/~dev_rating/application/views/base.twig
@@ -17,7 +17,8 @@
 {% macro SemesterSwitcher(SemesterList) %}
 	<a href="#" id="changeSemester" class="semesterChanger" title="Сменить семестр">
 		{% set Semester = SemesterList[User.SemesterID] %}
-		Семестр: {{ Rus[Semester.Season] }} {{ Semester.Num == 1 ? Semester.Year : (Semester.Year + 1) }}
+		<span class="semesterChangerTitle">Семестр:</span>
+		<span class="semesterChangerSelection">{{ Rus[Semester.Season] }} {{ Semester.Num == 1 ? Semester.Year : (Semester.Year + 1) }}</span>
 		<i class="fa fa-angle-down"></i>
 	</a>
 	<div class="semesterSwitcherBtn">
@@ -34,7 +35,8 @@
 {% macro RecordBookSwitcher(RecordBookList) %}
 	<a href="#" id="changeRecordBook" class="recordBookChanger" title="Сменить зачетку">
 		{% set RecordBook = RecordBookList[User.RecordBookID] %}
-		Зачетка: {{ RecordBook.ExternalID }}
+		<span class="recordBookChangerTitle">Зачетка:</span>
+		<span class="recordBookChangerSelection">{{ RecordBook.ExternalID }}</span>
 		<i class="fa fa-angle-down"></i>
 	</a>
 	<div class="recordBookSwitcherBtn">