diff --git a/cms/djangoapps/contentstore/management/commands/export_convert_format.py b/cms/djangoapps/contentstore/management/commands/export_convert_format.py
index 5b1b1d7cfdb21c2444328bad14b21e027afa3c8f..f97ff305fc76ab36a51bdf5de336b58881f41eb2 100644
--- a/cms/djangoapps/contentstore/management/commands/export_convert_format.py
+++ b/cms/djangoapps/contentstore/management/commands/export_convert_format.py
@@ -7,6 +7,7 @@ Sample invocation: ./manage.py export_convert_format mycourse.tar.gz ~/newformat
 import os
 from path import path
 from django.core.management.base import BaseCommand, CommandError
+from django.conf import settings
 
 from tempfile import mkdtemp
 import tarfile
@@ -32,8 +33,8 @@ class Command(BaseCommand):
         output_path = args[1]
 
         # Create temp directories to extract the source and create the target archive.
-        temp_source_dir = mkdtemp()
-        temp_target_dir = mkdtemp()
+        temp_source_dir = mkdtemp(dir=settings.DATA_DIR)
+        temp_target_dir = mkdtemp(dir=settings.DATA_DIR)
         try:
             extract_source(source_archive, temp_source_dir)
 
diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_export_convert_format.py b/cms/djangoapps/contentstore/management/commands/tests/test_export_convert_format.py
index fd83d58f890bb44c925965353b01dee390acc661..ddcdb725fbede91c504b91efac51016f5dc4fec6 100644
--- a/cms/djangoapps/contentstore/management/commands/tests/test_export_convert_format.py
+++ b/cms/djangoapps/contentstore/management/commands/tests/test_export_convert_format.py
@@ -3,6 +3,7 @@ Test for export_convert_format.
 """
 from unittest import TestCase
 from django.core.management import call_command, CommandError
+from django.conf import settings
 from tempfile import mkdtemp
 import shutil
 from path import path
@@ -18,7 +19,7 @@ class ConvertExportFormat(TestCase):
         """ Common setup. """
         super(ConvertExportFormat, self).setUp()
 
-        self.temp_dir = mkdtemp()
+        self.temp_dir = mkdtemp(dir=settings.DATA_DIR)
         self.addCleanup(shutil.rmtree, self.temp_dir)
         self.data_dir = path(__file__).realpath().parent / 'data'
         self.version0 = self.data_dir / "Version0_drafts.tar.gz"
@@ -52,8 +53,8 @@ class ConvertExportFormat(TestCase):
         """
         Helper function for determining if 2 archives are equal.
         """
-        temp_dir_1 = mkdtemp()
-        temp_dir_2 = mkdtemp()
+        temp_dir_1 = mkdtemp(dir=settings.DATA_DIR)
+        temp_dir_2 = mkdtemp(dir=settings.DATA_DIR)
         try:
             extract_source(file1, temp_dir_1)
             extract_source(file2, temp_dir_2)
diff --git a/cms/djangoapps/contentstore/views/tests/test_import_export.py b/cms/djangoapps/contentstore/views/tests/test_import_export.py
index 3375a30d0916c1c5523e5c93e2efee879d404f77..f251d0a295979ed91e3544eaf2a52450a8464580 100644
--- a/cms/djangoapps/contentstore/views/tests/test_import_export.py
+++ b/cms/djangoapps/contentstore/views/tests/test_import_export.py
@@ -209,6 +209,19 @@ class ImportTestCase(CourseTestCase):
 
         return outside_tar
 
+    def _edx_platform_tar(self):
+        """
+        Tarfile with file that extracts to edx-platform directory.
+
+        Extracting this tarfile in directory <dir> will also put its contents
+        directly in <dir> (rather than <dir/tarname>).
+        """
+        outside_tar = self.unsafe_common_dir / "unsafe_file.tar.gz"
+        with tarfile.open(outside_tar, "w:gz") as tar:
+            tar.addfile(tarfile.TarInfo(os.path.join(os.path.abspath("."), "a_file")))
+
+        return outside_tar
+
     def test_unsafe_tar(self):
         """
         Check that safety measure work.
@@ -233,6 +246,12 @@ class ImportTestCase(CourseTestCase):
         try_tar(self._symlink_tar())
         try_tar(self._outside_tar())
         try_tar(self._outside_tar2())
+        try_tar(self._edx_platform_tar())
+
+        # test trying to open a tar outside of the normal data directory
+        with self.settings(DATA_DIR='/not/the/data/dir'):
+            try_tar(self._edx_platform_tar())
+
         # Check that `import_status` returns the appropriate stage (i.e.,
         # either 3, indicating all previous steps are completed, or 0,
         # indicating no upload in progress)
@@ -294,13 +313,19 @@ class ImportTestCase(CourseTestCase):
         self.assertIn(test_block3.url_name, children)
         self.assertIn(test_block4.url_name, children)
 
-        extract_dir = path(tempfile.mkdtemp())
+        extract_dir = path(tempfile.mkdtemp(dir=settings.DATA_DIR))
+        # the extract_dir needs to be passed as a relative dir to
+        # import_library_from_xml
+        extract_dir_relative = path.relpath(extract_dir, settings.DATA_DIR)
+
         try:
-            tar = tarfile.open(path(TEST_DATA_DIR) / 'imports' / 'library.HhJfPD.tar.gz')
-            safetar_extractall(tar, extract_dir)
+            with tarfile.open(path(TEST_DATA_DIR) / 'imports' / 'library.HhJfPD.tar.gz') as tar:
+                safetar_extractall(tar, extract_dir)
             library_items = import_library_from_xml(
-                self.store, self.user.id,
-                settings.GITHUB_REPO_ROOT, [extract_dir / 'library'],
+                self.store,
+                self.user.id,
+                settings.GITHUB_REPO_ROOT,
+                [extract_dir_relative / 'library'],
                 load_error_modules=False,
                 static_content_store=contentstore(),
                 target_id=lib_key
diff --git a/cms/envs/bok_choy.py b/cms/envs/bok_choy.py
index 8c7e7f8585eeb4ec16574b12a5bebdb85e4bf650..84916debe96b6fba8f63dbf51f047e62708deeb5 100644
--- a/cms/envs/bok_choy.py
+++ b/cms/envs/bok_choy.py
@@ -39,6 +39,7 @@ INSTALLED_APPS += ('django_extensions',)
 TEST_ROOT = REPO_ROOT / "test_root"  # pylint: disable=no-value-for-parameter
 GITHUB_REPO_ROOT = (TEST_ROOT / "data").abspath()
 LOG_DIR = (TEST_ROOT / "log").abspath()
+DATA_DIR = TEST_ROOT / "data"
 
 # Configure modulestore to use the test folder within the repo
 update_module_store_settings(
diff --git a/cms/envs/test.py b/cms/envs/test.py
index ba6d9e7df1202e8a5e502a497171ba0db40c209a..289c3c67d378bc82cfa0f24f81b3cf6819cb39c1 100644
--- a/cms/envs/test.py
+++ b/cms/envs/test.py
@@ -65,6 +65,7 @@ TEST_ROOT = path('test_root')
 STATIC_ROOT = TEST_ROOT / "staticfiles"
 
 GITHUB_REPO_ROOT = TEST_ROOT / "data"
+DATA_DIR = TEST_ROOT / "data"
 COMMON_TEST_DATA_ROOT = COMMON_ROOT / "test" / "data"
 
 # For testing "push to lms"
diff --git a/common/djangoapps/course_modes/tests/test_views.py b/common/djangoapps/course_modes/tests/test_views.py
index 3883a5acd819e1fe8b5929cb23951a12f28b9522..11d2afc3944f0dcc70723af1b74e6c38c27b9696 100644
--- a/common/djangoapps/course_modes/tests/test_views.py
+++ b/common/djangoapps/course_modes/tests/test_views.py
@@ -325,6 +325,22 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase):
 
         self.assertEquals(course_modes, expected_modes)
 
+    @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
+    @patch.dict(settings.FEATURES, {"IS_EDX_DOMAIN": True})
+    def test_hide_nav(self):
+        # Create the course modes
+        for mode in ["honor", "verified"]:
+            CourseModeFactory(mode_slug=mode, course_id=self.course.id)
+
+        # Load the track selection page
+        url = reverse('course_modes_choose', args=[unicode(self.course.id)])
+        response = self.client.get(url)
+
+        # Verify that the header navigation links are hidden for the edx.org version
+        self.assertNotContains(response, "How it Works")
+        self.assertNotContains(response, "Find courses")
+        self.assertNotContains(response, "Schools & Partners")
+
 
 @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
 class TrackSelectionEmbargoTest(UrlResetMixin, ModuleStoreTestCase):
diff --git a/common/djangoapps/course_modes/views.py b/common/djangoapps/course_modes/views.py
index 290aef92495e1f8b4d753894900833b63bb28103..0dc790b7667b29261c05233d48be7631f3766ec1 100644
--- a/common/djangoapps/course_modes/views.py
+++ b/common/djangoapps/course_modes/views.py
@@ -119,7 +119,8 @@ class ChooseModeView(View):
             "course_num": course.display_number_with_default,
             "chosen_price": chosen_price,
             "error": error,
-            "responsive": True
+            "responsive": True,
+            "nav_hidden": True,
         }
         if "verified" in modes:
             context["suggested_prices"] = [
diff --git a/common/djangoapps/student/tests/tests.py b/common/djangoapps/student/tests/tests.py
index 5051421cd40ebddc72c0ab4ef5556afdd9209e98..00af8014b5f11e838b13745c8313af1319be53e1 100644
--- a/common/djangoapps/student/tests/tests.py
+++ b/common/djangoapps/student/tests/tests.py
@@ -529,6 +529,19 @@ class DashboardTest(ModuleStoreTestCase):
             response_3 = self.client.get(reverse('dashboard'))
             self.assertEquals(response_3.status_code, 200)
 
+    @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
+    @patch.dict(settings.FEATURES, {"IS_EDX_DOMAIN": True})
+    def test_dashboard_header_nav_has_find_courses(self):
+        self.client.login(username="jack", password="test")
+        response = self.client.get(reverse("dashboard"))
+
+        # "Find courses" is shown in the side panel
+        self.assertContains(response, "Find courses")
+
+        # But other links are hidden in the navigation
+        self.assertNotContains(response, "How it Works")
+        self.assertNotContains(response, "Schools & Partners")
+
 
 class UserSettingsEventTestMixin(EventTestMixin):
     """
diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py
index 03dd7ef302d0857259d715214828297916e58ce4..60c1f088095423247ae5740c8c18097cf68fd134 100644
--- a/common/djangoapps/student/views.py
+++ b/common/djangoapps/student/views.py
@@ -694,6 +694,7 @@ def dashboard(request):
         'order_history_list': order_history_list,
         'courses_requirements_not_met': courses_requirements_not_met,
         'ccx_membership_triplets': ccx_membership_triplets,
+        'nav_hidden': True,
     }
 
     return render_to_response('dashboard.html', context)
diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py
index e12b1454f4459ccb13f4c9097783391315081014..2f55f57a4147b15c94f18e9b4653a2cfbcc61fe3 100644
--- a/common/lib/xmodule/xmodule/x_module.py
+++ b/common/lib/xmodule/xmodule/x_module.py
@@ -591,6 +591,12 @@ class XModuleMixin(XModuleFields, XBlock):
 
             if field.scope.user == UserScope.ONE:
                 field._del_cached_value(self)  # pylint: disable=protected-access
+                # not the most elegant way of doing this, but if we're removing
+                # a field from the module's field_data_cache, we should also
+                # remove it from its _dirty_fields
+                # pylint: disable=protected-access
+                if field in self._dirty_fields:
+                    del self._dirty_fields[field]
 
         # Set the new xmodule_runtime and field_data (which are user-specific)
         self.xmodule_runtime = xmodule_runtime
diff --git a/common/static/js/utils/rwd_header.js b/common/static/js/utils/rwd_header.js
deleted file mode 100644
index d2137fd9bcb8f8a996f2b29613dc85e581e1c179..0000000000000000000000000000000000000000
--- a/common/static/js/utils/rwd_header.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * Adds rwd classes and click handlers.
- */
-
-(function($) {
-    'use strict';
-
-    var rwd = (function() {
-
-        var _fn = {
-            header: 'header.global-new',
-
-            resultsUrl: 'course-search',
-
-            init: function() {
-                _fn.$header = $( _fn.header );
-                _fn.$footer = $( _fn.footer );
-                _fn.$navContainer = _fn.$header.find('.nav-container');
-                _fn.$globalNav = _fn.$header.find('.nav-global');
-
-                _fn.add.elements();
-                _fn.add.classes();
-                _fn.eventHandlers.init();
-            },
-
-            add: {
-                classes: function() {
-                    // Add any RWD-specific classes
-                    _fn.$header.addClass('rwd');
-                },
-
-                elements: function() {
-                    _fn.add.burger();
-                    _fn.add.registerLink();
-                },
-
-                burger: function() {
-                    _fn.$navContainer.prepend([
-                        '<a href="#" class="mobile-menu-button" aria-label="menu">',
-                            '<i class="icon fa fa-bars" aria-hidden="true"></i>',
-                        '</a>'
-                    ].join(''));
-                },
-
-                registerLink: function() {
-                    var $register = _fn.$header.find('.cta-register'),
-                        $li = {},
-                        $a = {},
-                        count = 0;
-
-                    // Add if register link is shown
-                    if ( $register.length > 0 ) {
-                        count = _fn.$globalNav.find('li').length + 1;
-
-                        // Create new li
-                        $li = $('<li/>');
-                        $li.addClass('desktop-hide nav-global-0' + count);
-
-                        // Clone register link and remove classes
-                        $a = $register.clone();
-                        $a.removeClass();
-
-                        // append to DOM
-                        $a.appendTo( $li );
-                        _fn.$globalNav.append( $li );
-                    }
-                }
-            },
-
-            eventHandlers: {
-                init: function() {
-                    _fn.eventHandlers.click();
-                },
-
-                click: function() {
-                    // Toggle menu
-                    _fn.$header.on( 'click', '.mobile-menu-button', _fn.toggleMenu );
-                }
-            },
-
-            toggleMenu: function( event ) {
-                event.preventDefault();
-
-                _fn.$globalNav.toggleClass('show');
-            }
-        };
-
-        return {
-            init: _fn.init
-        };
-    })();
-
-    rwd.init();
-})(jQuery);
diff --git a/common/test/acceptance/pages/lms/dashboard.py b/common/test/acceptance/pages/lms/dashboard.py
index 30b72a4e37cae2260664b9c333ca6cb006596a42..cba42d2154647bab50531110e455d0bbdee7b988 100644
--- a/common/test/acceptance/pages/lms/dashboard.py
+++ b/common/test/acceptance/pages/lms/dashboard.py
@@ -48,20 +48,6 @@ class DashboardPage(PageObject):
 
         return self.q(css='h3.course-title > a').map(_get_course_name).results
 
-    @property
-    def sidebar_menu_title(self):
-        """
-        Return the title value for sidebar menu.
-        """
-        return self.q(css='.user-info span.title').text[0]
-
-    @property
-    def sidebar_menu_description(self):
-        """
-        Return the description text for sidebar menu.
-        """
-        return self.q(css='.user-info span.copy').text[0]
-
     def get_enrollment_mode(self, course_name):
         """Get the enrollment mode for a given course on the dashboard.
 
diff --git a/common/test/acceptance/tests/lms/test_lms.py b/common/test/acceptance/tests/lms/test_lms.py
index aca838c47bce640cf496d5137f874832c72c3ea3..9d0ae381c259f9daad536bdf2c596c1550d105b1 100644
--- a/common/test/acceptance/tests/lms/test_lms.py
+++ b/common/test/acceptance/tests/lms/test_lms.py
@@ -267,12 +267,6 @@ class RegisterFromCombinedPageTest(UniqueCourseTest):
         course_names = self.dashboard_page.wait_for_page().available_courses
         self.assertIn(self.course_info["display_name"], course_names)
 
-        self.assertEqual("want to change your account settings?", self.dashboard_page.sidebar_menu_title.lower())
-        self.assertEqual(
-            "click the arrow next to your username above.",
-            self.dashboard_page.sidebar_menu_description.lower()
-        )
-
     def test_register_failure(self):
         # Navigate to the registration page
         self.register_page.visit()
diff --git a/lms/djangoapps/commerce/tests/test_views.py b/lms/djangoapps/commerce/tests/test_views.py
index f04b530debc67176d20b11e983cdddd3aa90ec18..80c4920edbdb34c587d640628fab81f35ebe6c00 100644
--- a/lms/djangoapps/commerce/tests/test_views.py
+++ b/lms/djangoapps/commerce/tests/test_views.py
@@ -84,3 +84,14 @@ class ReceiptViewTests(UserMixin, TestCase):
         system_message = "A system error occurred while processing your payment"
         self.assertRegexpMatches(response.content, user_message if is_user_message_expected else system_message)
         self.assertNotRegexpMatches(response.content, user_message if not is_user_message_expected else system_message)
+
+    @mock.patch.dict(settings.FEATURES, {"IS_EDX_DOMAIN": True})
+    def test_hide_nav_header(self):
+        self._login()
+        post_data = {'decision': 'ACCEPT', 'reason_code': '200', 'signed_field_names': 'dummy'}
+        response = self.post_to_receipt_page(post_data)
+
+        # Verify that the header navigation links are hidden for the edx.org version
+        self.assertNotContains(response, "How it Works")
+        self.assertNotContains(response, "Find courses")
+        self.assertNotContains(response, "Schools & Partners")
diff --git a/lms/djangoapps/commerce/views.py b/lms/djangoapps/commerce/views.py
index 9c504878332b0642897d487dbfee4fe7d18991ed..58e1ec0cd89f95df92c7982ea3af168842209cf7 100644
--- a/lms/djangoapps/commerce/views.py
+++ b/lms/djangoapps/commerce/views.py
@@ -66,6 +66,7 @@ def checkout_receipt(request):
         'error_text': error_text,
         'for_help_text': for_help_text,
         'payment_support_email': payment_support_email,
-        'username': request.user.username
+        'username': request.user.username,
+        'nav_hidden': True,
     }
     return render_to_response('commerce/checkout_receipt.html', context)
diff --git a/lms/djangoapps/courseware/tests/test_module_render.py b/lms/djangoapps/courseware/tests/test_module_render.py
index d5c9824cad3ca3a23cccfbb8c0b0c4baa7e64173..d9f1ebf98f826082adcc921a981ac84cc148b012 100644
--- a/lms/djangoapps/courseware/tests/test_module_render.py
+++ b/lms/djangoapps/courseware/tests/test_module_render.py
@@ -1360,23 +1360,44 @@ class TestRebindModule(TestSubmittingProblems):
         super(TestRebindModule, self).setUp()
         self.homework = self.add_graded_section_to_course('homework')
         self.lti = ItemFactory.create(category='lti', parent=self.homework)
+        self.problem = ItemFactory.create(category='problem', parent=self.homework)
         self.user = UserFactory.create()
         self.anon_user = AnonymousUser()
 
-    def get_module_for_user(self, user):
+    def get_module_for_user(self, user, item=None):
         """Helper function to get useful module at self.location in self.course_id for user"""
         mock_request = MagicMock()
         mock_request.user = user
         field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
             self.course.id, user, self.course, depth=2)
 
+        if item is None:
+            item = self.lti
+
         return render.get_module(  # pylint: disable=protected-access
             user,
             mock_request,
-            self.lti.location,
+            item.location,
             field_data_cache,
         )._xmodule
 
+    def test_rebind_module_to_new_users(self):
+        module = self.get_module_for_user(self.user, self.problem)
+
+        # Bind the module to another student, which will remove "correct_map"
+        # from the module's _field_data_cache and _dirty_fields.
+        user2 = UserFactory.create()
+        module.descriptor.bind_for_student(module.system, user2.id)
+
+        # XBlock's save method assumes that if a field is in _dirty_fields,
+        # then it's also in _field_data_cache. If this assumption
+        # doesn't hold, then we get an error trying to bind this module
+        # to a third student, since we've removed "correct_map" from
+        # _field_data cache, but not _dirty_fields, when we bound
+        # this module to the second student. (TNL-2640)
+        user3 = UserFactory.create()
+        module.descriptor.bind_for_student(module.system, user3.id)
+
     def test_rebind_noauth_module_to_user_not_anonymous(self):
         """
         Tests that an exception is thrown when rebind_noauth_module_to_user is run from a
diff --git a/lms/djangoapps/verify_student/tests/test_views.py b/lms/djangoapps/verify_student/tests/test_views.py
index 0d900044a9006c6008a97c7f9f381383580cf045..60ebc36c861bd54783be78fc746a1ab2142bde51 100644
--- a/lms/djangoapps/verify_student/tests/test_views.py
+++ b/lms/djangoapps/verify_student/tests/test_views.py
@@ -237,6 +237,17 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase):
         )
         self._assert_redirects_to_dashboard(response)
 
+    @patch.dict(settings.FEATURES, {"IS_EDX_DOMAIN": True})
+    def test_pay_and_verify_hides_header_nav(self):
+        course = self._create_course("verified")
+        self._enroll(course.id, "verified")
+        response = self._get_page('verify_student_start_flow', course.id)
+
+        # Verify that the header navigation links are hidden for the edx.org version
+        self.assertNotContains(response, "How it Works")
+        self.assertNotContains(response, "Find courses")
+        self.assertNotContains(response, "Schools & Partners")
+
     def test_verify_now(self):
         # We've already paid, and now we're trying to verify
         course = self._create_course("verified")
diff --git a/lms/djangoapps/verify_student/views.py b/lms/djangoapps/verify_student/views.py
index 288a86710b110370e25d392a3e98e242ece66430..74d993ebb2573210048f338903b41a8f5e183a03 100644
--- a/lms/djangoapps/verify_student/views.py
+++ b/lms/djangoapps/verify_student/views.py
@@ -376,6 +376,7 @@ class PayAndVerifyView(View):
             'already_verified': already_verified,
             'verification_good_until': verification_good_until,
             'capture_sound': staticfiles_storage.url("audio/camera_capture.wav"),
+            'nav_hidden': True,
         }
         return render_to_response("verify_student/pay_and_verify.html", context)
 
diff --git a/lms/envs/aws.py b/lms/envs/aws.py
index 94e7563d2a6c392609cc065091ef710e01eca2b6..4952abed45b8949012c5940faa4071ef99e6eeaf 100644
--- a/lms/envs/aws.py
+++ b/lms/envs/aws.py
@@ -678,3 +678,8 @@ if FEATURES.get('ENABLE_LTI_PROVIDER'):
 
 ##################### Credit Provider help link ####################
 CREDIT_HELP_LINK_URL = ENV_TOKENS.get('CREDIT_HELP_LINK_URL', CREDIT_HELP_LINK_URL)
+
+
+#### JWT configuration ####
+JWT_ISSUER = ENV_TOKENS.get('JWT_ISSUER', JWT_ISSUER)
+JWT_EXPIRATION = ENV_TOKENS.get('JWT_EXPIRATION', JWT_EXPIRATION)
diff --git a/lms/envs/common.py b/lms/envs/common.py
index 833c8c6d61654389a30c7b079b24967c0ad929cf..1cd367d770fde02c4a6c5815ec9583e6f2c20457 100644
--- a/lms/envs/common.py
+++ b/lms/envs/common.py
@@ -1247,7 +1247,6 @@ dashboard_js = (
 )
 dashboard_search_js = ['js/search/dashboard/main.js']
 discussion_js = sorted(rooted_glob(COMMON_ROOT / 'static', 'coffee/src/discussion/**/*.js'))
-rwd_header_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'js/utils/rwd_header.js'))
 staff_grading_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/staff_grading/**/*.js'))
 open_ended_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/open_ended/**/*.js'))
 notes_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/notes/**/*.js'))
@@ -1260,7 +1259,6 @@ instructor_dash_js = (
 # These are not courseware, so they do not need many of the courseware-specific
 # JavaScript modules.
 student_account_js = [
-    'js/utils/rwd_header.js',
     'js/utils/edx.utils.validate.js',
     'js/form.ext.js',
     'js/my_courses_dropdown.js',
@@ -1549,10 +1547,6 @@ PIPELINE_JS = {
         'source_filenames': dashboard_search_js,
         'output_filename': 'js/dashboard-search.js',
     },
-    'rwd_header': {
-        'source_filenames': rwd_header_js,
-        'output_filename': 'js/rwd_header.js'
-    },
     'student_account': {
         'source_filenames': student_account_js,
         'output_filename': 'js/student_account.js'
diff --git a/lms/static/sass/elements/_controls.scss b/lms/static/sass/elements/_controls.scss
index ceede5d14f081b0d7f1d4d90368145257f457364..a38dc4a7399866216343df792700cdf7a3884dc2 100644
--- a/lms/static/sass/elements/_controls.scss
+++ b/lms/static/sass/elements/_controls.scss
@@ -352,6 +352,19 @@
   }
 }
 
+%btn-pl-elevated-alt {
+  @extend %btn-pl-default-base;
+  box-shadow: 0 3px 0 0 $gray-l4;
+  border: 1px solid $gray-l4;
+
+  &:hover {
+    box-shadow: 0 3px 0 0 $action-primary-bg;
+    border: 1px solid $action-primary-bg;
+    background-color: lighten($action-primary-bg,20%);
+    color: $white;
+  }
+}
+
 // ====================
 
   // application: canned actions
diff --git a/lms/static/sass/multicourse/_dashboard.scss b/lms/static/sass/multicourse/_dashboard.scss
index 1ecf983515cfb8446bb11134f4d5a57b4f2f09ee..64f10ca9a20f6667eb68b394314ed52dbcaf70d5 100644
--- a/lms/static/sass/multicourse/_dashboard.scss
+++ b/lms/static/sass/multicourse/_dashboard.scss
@@ -15,14 +15,31 @@
   @include clearfix();
   padding: ($baseline*2) 0 $baseline 0;
 
+  .wrapper-find-courses {
+    @include float(right);
+    @include margin-left(flex-gutter());
+    width: flex-grid(3);
+    margin-top: ($baseline*2);
+    border-top: 3px solid $blue;
+    padding: $baseline 0;
+
+    .copy {
+      @extend %t-copy-sub1;
+    }
+
+    .btn-find-courses {
+      @extend %btn-pl-elevated-alt;
+    }
+  }
+
   .profile-sidebar {
     background: transparent;
     @include float(right);
-    margin-top: ($baseline*2);
+    @include margin-left(flex-gutter());
     width: flex-grid(3);
-    box-shadow: 0 0 1px $shadow-l1;
-    border: 1px solid $border-color-2;
-    border-radius: 3px;
+    margin-top: ($baseline*2);
+    border-top: 3px solid $blue;
+    padding: $baseline 0;
 
     .user-info {
       @include clearfix();
@@ -31,7 +48,7 @@
         @include box-sizing(border-box);
         @include clearfix();
         margin: 0;
-        padding: $baseline;
+        padding: 0;
         width: flex-grid(12);
 
         li {
@@ -59,7 +76,7 @@
           }
 
           span.title {
-            @extend %t-copy-sub1;
+            @extend %t-title6;
             @extend %t-strong;
 
             a {
diff --git a/lms/static/sass/shared/_header.scss b/lms/static/sass/shared/_header.scss
index 648b9404162a2ab80ff85a23c4f76529ccc5b9cd..43535f2ddd805335faf848b1853b357627b333a1 100644
--- a/lms/static/sass/shared/_header.scss
+++ b/lms/static/sass/shared/_header.scss
@@ -620,8 +620,8 @@ header.global-new {
       a {
         display:block;
         padding: 3px 10px;
-        font-size: 18px;
-        line-height: 24px;
+        font-size: 14px;
+        line-height: 1.5;
         font-weight: 600;
         font-family: $header-sans-serif;
         color: $courseware-navigation-color;
@@ -708,7 +708,6 @@ header.global-new {
         font-size: 14px;
 
         &.nav-courseware-button {
-          width: 86px;
           text-align: center;
           margin-top: -3px;
         }
@@ -826,13 +825,6 @@ header.global-new {
       .wrapper-header {
         padding: 17px 0;
       }
-
-      .nav-global,
-      .nav-courseware {
-        a {
-          font-size: 18px;
-        }
-      }
     }
   }
 }
diff --git a/lms/templates/commerce/checkout_receipt.html b/lms/templates/commerce/checkout_receipt.html
index 12ea45a9de313e143891e35bf37db3c3a77e4eba..3ff3b73bc7d41b0a1557af86a34026732c1a17e6 100644
--- a/lms/templates/commerce/checkout_receipt.html
+++ b/lms/templates/commerce/checkout_receipt.html
@@ -18,7 +18,6 @@ from django.utils.translation import ugettext as _
 
 </%block>
 <%block name="js_extra">
-<%static:js group='rwd_header'/>
 <script src="${static.url('js/vendor/jquery.ajax-retry.js')}"></script>
 <script src="${static.url('js/vendor/underscore-min.js')}"></script>
 <script src="${static.url('js/vendor/underscore.string.min.js')}"></script>
diff --git a/lms/templates/dashboard.html b/lms/templates/dashboard.html
index 8d3fb0ad4388a208544e4bf305150101a146cd0f..5d1ffc4c8875c6ac4df83f6718262e29af9b0fca 100644
--- a/lms/templates/dashboard.html
+++ b/lms/templates/dashboard.html
@@ -147,16 +147,19 @@ from django.core.urlresolvers import reverse
     <section id="dashboard-search-results" class="search-results dashboard-search-results"></section>
   % endif
 
-  <section class="profile-sidebar" id="profile-sidebar" role="region" aria-label="User info">
+  % if settings.FEATURES.get('IS_EDX_DOMAIN'):
+    <div class="wrapper-find-courses">
+      <p class="copy">Check out our recently launched courses and what's new in your favorite subjects</p>
+      <p><a class="btn-find-courses" href="${marketing_link('COURSES')}">${_("Find New Courses")}</a></p>
+    </div>
+  % endif
+
+  <section class="profile-sidebar" id="profile-sidebar" role="region" aria-label="Account Status Info">
     <header class="profile">
-      <h2 class="username-header"><span class="sr">${_("Username")}: </span></h2>
+      <h2 class="account-status-title sr">${_("Account Status Info")}: </h2>
     </header>
     <section class="user-info">
       <ul>
-        <li class="heads-up">
-          <span class="title">${_("Want to change your account settings?")}</span>
-          <span class="copy">${_("Click the arrow next to your username above.")}</span>
-        </li>
 
         % if len(order_history_list):
         <li class="order-history">
diff --git a/lms/templates/navigation-edx.html b/lms/templates/navigation-edx.html
index 8374bb6e139ee4b529391c5a29b3bf73bef090d9..d0c17fb22bf84f050b9dabf02a6db54356fc25b1 100644
--- a/lms/templates/navigation-edx.html
+++ b/lms/templates/navigation-edx.html
@@ -53,6 +53,7 @@ site_status_msg = get_site_status_msg(course_id)
 
     % if user.is_authenticated():
       % if not course or disable_courseware_header:
+        % if not nav_hidden:
     <nav aria-label="Main" class="nav-main">
       <ul class="left nav-global authenticated">
         <%block name="navigation_global_links_authenticated">
@@ -68,6 +69,7 @@ site_status_msg = get_site_status_msg(course_id)
         </%block>
       </ul>
     </nav>
+        % endif
       % endif
 
     <ul class="user">
@@ -101,44 +103,28 @@ site_status_msg = get_site_status_msg(course_id)
       % endif
 
     % else:
-    <nav aria-label="Main" class="nav-main">
-      <ul class="left nav-global">
-        <%block name="navigation_global_links">
-            <li class="nav-global-01">
-              <a href="${marketing_link('HOW_IT_WORKS')}">${_("How it Works")}</a>
-            </li>
-            <li class="nav-global-02">
-              <a href="${marketing_link('COURSES')}">${_("Find Courses")}</a>
-            </li>
-            <li class="nav-global-03">
-              <a href="${marketing_link('SCHOOLS')}">${_("Schools & Partners")}</a>
-            </li>
-        </%block>
-      </ul>
-    </nav>
-
     <nav aria-label="Account" class="nav-account-management">
       <div class="right nav-courseware">
+        <div class="nav-courseware-01">
+          % if not settings.FEATURES['DISABLE_LOGIN_BUTTON']:
+              % if course and settings.FEATURES.get('RESTRICT_ENROLL_BY_REG_METHOD') and course.enrollment_domain:
+              <a class="cta cta-login" href="${reverse('course-specific-login', args=[course.id.to_deprecated_string()])}${login_query()}">${_("Sign in")}</a>
+              % else:
+              <a class="cta cta-login" href="/login${login_query()}">${_("Sign in")}</a>
+              % endif
+          % endif
+        </div>
         % if not settings.FEATURES['DISABLE_LOGIN_BUTTON']:
           % if course and settings.FEATURES.get('RESTRICT_ENROLL_BY_REG_METHOD') and course.enrollment_domain:
-          <div class="nav-courseware-01">
-            <a class="cta cta-register" href="${reverse('course-specific-register', args=[course.id.to_deprecated_string()])}">${_("Register")}</a>
+          <div class="nav-courseware-02">
+            <a class="cta cta-register nav-courseware-button" href="${reverse('course-specific-register', args=[course.id.to_deprecated_string()])}">${_("Register")}</a>
           </div>
           % else:
-          <div class="nav-courseware-01">
-            <a class="cta cta-register" href="/register">${_("Register")}</a>
+          <div class="nav-courseware-02">
+            <a class="cta cta-register nav-courseware-button" href="/register">${_("Register")}</a>
           </div>
           % endif
         % endif
-        <div class="nav-courseware-02">
-          % if not settings.FEATURES['DISABLE_LOGIN_BUTTON']:
-              % if course and settings.FEATURES.get('RESTRICT_ENROLL_BY_REG_METHOD') and course.enrollment_domain:
-              <a class="cta cta-login nav-courseware-button" href="${reverse('course-specific-login', args=[course.id.to_deprecated_string()])}${login_query()}">${_("Sign in")}</a>
-              % else:
-              <a class="cta cta-login nav-courseware-button" href="/login${login_query()}">${_("Sign in")}</a>
-              % endif
-          % endif
-        </div>
       </div>
     </nav>
     % endif
diff --git a/lms/templates/verify_student/incourse_reverify.html b/lms/templates/verify_student/incourse_reverify.html
index a6a3144bc5e673cd024eaf2129970fd17c172abd..a7b101dff4c7f6c96d7606d1889a8dbdcdb25527 100644
--- a/lms/templates/verify_student/incourse_reverify.html
+++ b/lms/templates/verify_student/incourse_reverify.html
@@ -18,7 +18,6 @@ from django.utils.translation import ugettext as _
     % endfor
 </%block>
 <%block name="js_extra">
-  <%static:js group='rwd_header'/>
   <script src="${static.url('js/vendor/underscore-min.js')}"></script>
   <script src="${static.url('js/vendor/underscore.string.min.js')}"></script>
   <script src="${static.url('js/vendor/backbone-min.js')}"></script>
diff --git a/lms/templates/verify_student/pay_and_verify.html b/lms/templates/verify_student/pay_and_verify.html
index 802ca32ac0662cdf6953c127ae34883f0f6bf182..7b90d72001c2f43ca01cde7d17f378123386f5cd 100644
--- a/lms/templates/verify_student/pay_and_verify.html
+++ b/lms/templates/verify_student/pay_and_verify.html
@@ -35,7 +35,6 @@ from verify_student.views import PayAndVerifyView
     % endfor
 </%block>
 <%block name="js_extra">
-  <%static:js group='rwd_header'/>
   <script src="${static.url('js/vendor/underscore-min.js')}"></script>
   <script src="${static.url('js/vendor/underscore.string.min.js')}"></script>
   <script src="${static.url('js/vendor/backbone-min.js')}"></script>
diff --git a/lms/templates/verify_student/reverify.html b/lms/templates/verify_student/reverify.html
index 3f2d0db042d5f3306d98a24461d454bb84f32927..8218392e9571707fb6caff949cdbcd4deca9bf95 100644
--- a/lms/templates/verify_student/reverify.html
+++ b/lms/templates/verify_student/reverify.html
@@ -16,7 +16,6 @@ from django.utils.translation import ugettext as _
     % endfor
 </%block>
 <%block name="js_extra">
-  <%static:js group='rwd_header'/>
   <script src="${static.url('js/vendor/underscore-min.js')}"></script>
   <script src="${static.url('js/vendor/underscore.string.min.js')}"></script>
   <script src="${static.url('js/vendor/backbone-min.js')}"></script>
diff --git a/openedx/core/djangoapps/content/course_overviews/migrations/0004_default_lowest_passing_grade_to_None.py b/openedx/core/djangoapps/content/course_overviews/migrations/0004_default_lowest_passing_grade_to_None.py
new file mode 100644
index 0000000000000000000000000000000000000000..0876dbe7470e22e3d830f5739d9028b7af9a9a34
--- /dev/null
+++ b/openedx/core/djangoapps/content/course_overviews/migrations/0004_default_lowest_passing_grade_to_None.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+
+        # Changing field 'CourseOverview.lowest_passing_grade'
+        db.alter_column('course_overviews_courseoverview', 'lowest_passing_grade', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=5, decimal_places=2))
+
+    def backwards(self, orm):
+
+        # Changing field 'CourseOverview.lowest_passing_grade'
+        db.alter_column('course_overviews_courseoverview', 'lowest_passing_grade', self.gf('django.db.models.fields.DecimalField')(default=0.5, max_digits=5, decimal_places=2))
+
+    models = {
+        'course_overviews.courseoverview': {
+            'Meta': {'object_name': 'CourseOverview'},
+            '_location': ('xmodule_django.models.UsageKeyField', [], {'max_length': '255'}),
+            '_pre_requisite_courses_json': ('django.db.models.fields.TextField', [], {}),
+            'advertised_start': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'cert_html_view_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'cert_name_long': ('django.db.models.fields.TextField', [], {}),
+            'cert_name_short': ('django.db.models.fields.TextField', [], {}),
+            'certificates_display_behavior': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'certificates_show_before_end': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'course_image_url': ('django.db.models.fields.TextField', [], {}),
+            'days_early_for_beta': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
+            'display_name': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'display_number_with_default': ('django.db.models.fields.TextField', [], {}),
+            'display_org_with_default': ('django.db.models.fields.TextField', [], {}),
+            'end': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+            'end_of_course_survey_url': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'facebook_url': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'has_any_active_web_certificate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'id': ('xmodule_django.models.CourseKeyField', [], {'max_length': '255', 'primary_key': 'True', 'db_index': 'True'}),
+            'lowest_passing_grade': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '5', 'decimal_places': '2'}),
+            'mobile_available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'social_sharing_url': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'start': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+            'visible_to_staff_only': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+        }
+    }
+
+    complete_apps = ['course_overviews']
\ No newline at end of file
diff --git a/openedx/core/djangoapps/content/course_overviews/models.py b/openedx/core/djangoapps/content/course_overviews/models.py
index 14387a8d96c716fbe7661dbd3772188a4fbd8d27..4b8429f9cc7183d75a9ec4dffc7e4ba1f4aaca0e 100644
--- a/openedx/core/djangoapps/content/course_overviews/models.py
+++ b/openedx/core/djangoapps/content/course_overviews/models.py
@@ -52,7 +52,7 @@ class CourseOverview(django.db.models.Model):
     cert_name_long = TextField()
 
     # Grading
-    lowest_passing_grade = DecimalField(max_digits=5, decimal_places=2)
+    lowest_passing_grade = DecimalField(max_digits=5, decimal_places=2, null=True)
 
     # Access parameters
     days_early_for_beta = FloatField(null=True)
@@ -77,6 +77,16 @@ class CourseOverview(django.db.models.Model):
         from lms.djangoapps.certificates.api import get_active_web_certificate
         from lms.djangoapps.courseware.courses import course_image_url
 
+        # Workaround for a problem discovered in https://openedx.atlassian.net/browse/TNL-2806.
+        # If the course has a malformed grading policy such that
+        # course._grading_policy['GRADE_CUTOFFS'] = {}, then
+        # course.lowest_passing_grade will raise a ValueError.
+        # Work around this for now by defaulting to None.
+        try:
+            lowest_passing_grade = course.lowest_passing_grade
+        except ValueError:
+            lowest_passing_grade = None
+
         return CourseOverview(
             id=course.id,
             _location=course.location,
@@ -98,7 +108,7 @@ class CourseOverview(django.db.models.Model):
             has_any_active_web_certificate=(get_active_web_certificate(course) is not None),
             cert_name_short=course.cert_name_short,
             cert_name_long=course.cert_name_long,
-            lowest_passing_grade=course.lowest_passing_grade,
+            lowest_passing_grade=lowest_passing_grade,
             end_of_course_survey_url=course.end_of_course_survey_url,
 
             days_early_for_beta=course.days_early_for_beta,
diff --git a/openedx/core/djangoapps/content/course_overviews/tests.py b/openedx/core/djangoapps/content/course_overviews/tests.py
index dc87856ae64ec14f30603e0694f836393c069100..8a56bb51725948be2e6e422215b1d96f6d74cde4 100644
--- a/openedx/core/djangoapps/content/course_overviews/tests.py
+++ b/openedx/core/djangoapps/content/course_overviews/tests.py
@@ -294,3 +294,18 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
             # which causes get_from_id to raise an IOError.
             with self.assertRaises(IOError):
                 CourseOverview.get_from_id(course.id)
+
+    def test_malformed_grading_policy(self):
+        """
+        Test that CourseOverview handles courses with a malformed grading policy
+        such that course._grading_policy['GRADE_CUTOFFS'] = {} by defaulting
+        .lowest_passing_grade to None.
+
+        Created in response to https://openedx.atlassian.net/browse/TNL-2806.
+        """
+        course = CourseFactory.create()
+        course._grading_policy['GRADE_CUTOFFS'] = {}  # pylint: disable=protected-access
+        with self.assertRaises(ValueError):
+            __ = course.lowest_passing_grade
+        course_overview = CourseOverview._create_from_course(course)  # pylint: disable=protected-access
+        self.assertEqual(course_overview.lowest_passing_grade, None)
diff --git a/openedx/core/lib/extract_tar.py b/openedx/core/lib/extract_tar.py
index ea464880ea18f051e4fbf05323a763d723b816be..58079ad065a22dd866fea6f9873d70725ccf92be 100644
--- a/openedx/core/lib/extract_tar.py
+++ b/openedx/core/lib/extract_tar.py
@@ -7,6 +7,7 @@ http://stackoverflow.com/questions/10060069/safely-extract-zip-or-tar-using-pyth
 """
 from os.path import abspath, realpath, dirname, join as joinpath
 from django.core.exceptions import SuspiciousOperation
+from django.conf import settings
 import logging
 
 log = logging.getLogger(__name__)
@@ -28,19 +29,23 @@ def _is_bad_path(path, base):
 
 def _is_bad_link(info, base):
     """
-    Does the file sym- ord hard-link to files outside `base`?
+    Does the file sym- or hard-link to files outside `base`?
     """
     # Links are interpreted relative to the directory containing the link
     tip = resolved(joinpath(base, dirname(info.name)))
     return _is_bad_path(info.linkname, base=tip)
 
 
-def safemembers(members):
+def safemembers(members, base):
     """
     Check that all elements of a tar file are safe.
     """
 
-    base = resolved(".")
+    base = resolved(base)
+
+    # check that we're not trying to import outside of the data_dir
+    if not base.startswith(resolved(settings.DATA_DIR)):
+        raise SuspiciousOperation("Attempted to import course outside of data dir")
 
     for finfo in members:
         if _is_bad_path(finfo.name, base):
@@ -61,8 +66,8 @@ def safemembers(members):
     return members
 
 
-def safetar_extractall(tarf, *args, **kwargs):
+def safetar_extractall(tar_file, path=".", members=None):  # pylint: disable=unused-argument
     """
-    Safe version of `tarf.extractall()`.
+    Safe version of `tar_file.extractall()`.
     """
-    return tarf.extractall(members=safemembers(tarf), *args, **kwargs)
+    return tar_file.extractall(path, safemembers(tar_file, path))