diff --git a/notaddtogit/README.txt b/notaddtogit/README.txt
new file mode 100644
index 00000000..8d734654
--- /dev/null
+++ b/notaddtogit/README.txt
@@ -0,0 +1,2 @@
+This app server only for importing reports from main.edu.pl to szkopul.edu.pl.
+Does not support another sites.
diff --git a/notaddtogit/__init__.py b/notaddtogit/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/notaddtogit/main.zip b/notaddtogit/main.zip
new file mode 100644
index 00000000..a4ec0e88
Binary files /dev/null and b/notaddtogit/main.zip differ
diff --git a/oioioi/base/notification.py b/oioioi/base/notification.py
index ed6195db..e847d8a7 100644
--- a/oioioi/base/notification.py
+++ b/oioioi/base/notification.py
@@ -54,6 +54,7 @@ class NotificationHandler(logging.StreamHandler):
                 if o.username and o.password:
                     kwargs['credentials'] = PlainCredentials(o.username, o.password)
                 kwargs.update(settings.NOTIFICATIONS_RABBITMQ_EXTRA_PARAMS)
+                kwargs['heartbeat'] = 8
                 parameters = ConnectionParameters(**kwargs)
                 thread_data.conn = BlockingConnection(parameters)
 
diff --git a/oioioi/base/templates/base.html b/oioioi/base/templates/base.html
index 10d76589..d87814c9 100644
--- a/oioioi/base/templates/base.html
+++ b/oioioi/base/templates/base.html
@@ -132,6 +132,15 @@
                 <script type="text/javascript" src="{{ STATIC_URL }}common/clipboard.min.js"></script>
                 <script type="text/javascript" src="{{ STATIC_URL }}common/clipboard-setup.js"></script>
             {% endcompress %}
+                <script type="text/javascript">
+                    new Clipboard('.btn-copy')
+                        .on('success', function(e) {
+                            e.trigger.outerHTML = '<small><span class="glyphicon glyphicon-ok"></span> {% trans "copied!" %}</small>';
+                        }).on('error', function(e) {
+                            e.trigger.outerHTML = '<small>{% trans "Press Ctrl+C to copy" %}</small>';
+                        });
+                </script>
+            <script type="text/javascript" src="{% url 'javascript_catalog' %}"></script>
             <script type="text/javascript" async
                     src="{{ mathjax_location }}MathJax.js?config=TeX-AMS-MML_HTMLorMML">
             </script>
diff --git a/oioioi/contests/handlers.py b/oioioi/contests/handlers.py
index 085e06c6..b2583635 100644
--- a/oioioi/contests/handlers.py
+++ b/oioioi/contests/handlers.py
@@ -113,6 +113,10 @@ def update_user_results(env, **kwargs):
 @transaction.atomic
 @_get_submission_or_skip
 def update_problem_statistics(env, submission, **kwargs):
+    # Ignore model solutions
+    if not submission.user:
+        return env
+
     (
         problem_statistics,
         created,
diff --git a/oioioi/contests/management/commands/find_all_se_submissions.py b/oioioi/contests/management/commands/find_all_se_submissions.py
new file mode 100644
index 00000000..90686b41
--- /dev/null
+++ b/oioioi/contests/management/commands/find_all_se_submissions.py
@@ -0,0 +1,45 @@
+from __future__ import print_function
+
+import six
+import time
+
+from django.core.management.base import BaseCommand
+from django.db.models import Q
+from django.utils.translation import ugettext as _
+from django.db import transaction
+from oioioi.contests.models import Contest, Round, Submission, SubmissionReport
+from datetime import datetime, timedelta
+
+class Command(BaseCommand):
+    help = _("Display all submissions that got System Error in the past N days")
+
+    def add_arguments(self, parser):
+        parser.add_argument('-n', '--numdays',
+                            action='store',
+                            type=int,
+                            dest='numdays',
+                            help="How many past days of reports to check",
+                            default=10)
+
+    def handle(self, *args, **options):
+        numdays = options["numdays"]
+        subs = Submission.objects.filter(date__gte=datetime.now()-timedelta(days=numdays))
+        raporty = SubmissionReport.objects.filter(submission__in=subs)
+        # problem_instance.controller.judge(submission, is_rejudge=True)
+        q = Q(
+            failurereport__isnull=False,
+        ) | Q(
+            testreport__status='SE'
+        )
+        raporty_z_se = raporty.filter(q).distinct()
+        for r in raporty_z_se:
+            pi = r.submission.problem_instance
+
+            with transaction.atomic():
+                pi.controller.judge(r.submission, is_rejudge=True)
+            time.sleep(1)
+            print(r.submission.id, end=",")
+            print(r.submission, end=",")
+            print(pi.contest, ",",  pi.problem, ",", pi.short_name)
+
+
diff --git a/oioioi/contests/management/commands/stats_all_submissions.py b/oioioi/contests/management/commands/stats_all_submissions.py
new file mode 100644
index 00000000..08aea064
--- /dev/null
+++ b/oioioi/contests/management/commands/stats_all_submissions.py
@@ -0,0 +1,34 @@
+from __future__ import print_function
+
+import six
+import time
+
+from django.core.management.base import BaseCommand
+from django.db.models import Q
+from django.utils.translation import ugettext as _
+from django.db import transaction
+from oioioi.contests.models import Contest, Round, Submission, SubmissionReport
+from datetime import datetime, timedelta
+
+class Command(BaseCommand):
+    help = _("Count submissions in the past N days")
+
+    def add_arguments(self, parser):
+        parser.add_argument('-n', '--numdays',
+                            action='store',
+                            type=int,
+                            dest='numdays',
+                            help="How many past days of reports to check",
+                            default=10)
+
+    def handle(self, *args, **options):
+        numdays = options["numdays"]
+        subs_all = Submission.objects.filter(date__gte=datetime.now() - timedelta(days=numdays))
+        #raporty = SubmissionReport.objects.filter(submission__in=subs)
+        # problem_instance.controller.judge(submission, is_rejudge=True)
+        for iteration in range(numdays):
+            data = (datetime.now() - timedelta(days=iteration)).date()
+            q = Q(date__gte=datetime.now() - timedelta(days=iteration)) & Q(date__lte=datetime.now() - timedelta(days=(iteration-1)))
+            subs = subs_all.filter(q).count()
+            print(str(data) + "," + str(subs))
+
diff --git a/oioioi/contests/models.py b/oioioi/contests/models.py
index 14e35816..393a4da3 100644
--- a/oioioi/contests/models.py
+++ b/oioioi/contests/models.py
@@ -97,6 +97,13 @@ class Contest(models.Model):
         ),
     )
 
+    def save(self, *args, **kwargs):
+        if not self.controller_name:
+            import traceback
+            traceback.print_exc()
+            self.controller_name = 'oioioi.teachers.controllers.TeacherContestController'
+        super(Contest, self).save(*args, **kwargs)
+
     @property
     def controller(self):
         if not self.controller_name:
diff --git a/oioioi/contests/processors.py b/oioioi/contests/processors.py
index 346f2450..c3298795 100644
--- a/oioioi/contests/processors.py
+++ b/oioioi/contests/processors.py
@@ -1,5 +1,6 @@
 from django.conf import settings
 from django.utils.functional import lazy
+import elasticapm
 
 from oioioi.base.utils import request_cached
 from oioioi.contests.models import Contest, ContestView
@@ -23,6 +24,7 @@ def register_current_contest(request):
 
 
 @request_cached
+@elasticapm.capture_span()
 def recent_contests(request):
     if request.real_user.is_anonymous:
         ids = request.session.get('recent_contests', [])
diff --git a/oioioi/contests/utils.py b/oioioi/contests/utils.py
index c83fed7f..98914fc3 100644
--- a/oioioi/contests/utils.py
+++ b/oioioi/contests/utils.py
@@ -7,6 +7,7 @@ from django.http import HttpRequest
 from django.shortcuts import get_object_or_404
 from django.utils.module_loading import import_string
 from pytz import UTC
+import elasticapm
 
 from oioioi.base.permissions import make_request_condition
 from oioioi.base.utils import request_cached
@@ -238,6 +239,7 @@ def visible_problem_instances(request):
 
 
 @request_cached
+@elasticapm.capture_span()
 def visible_rounds(request):
     controller = request.contest.controller
     queryset = Round.objects.filter(contest=request.contest)
@@ -262,6 +264,7 @@ def used_controllers():
 
 
 @request_cached
+@elasticapm.capture_span()
 def visible_contests(request):
     """Returns materialized set of contests visible to the logged in user."""
     if request.GET.get('living', 'safely') == 'dangerously':
diff --git a/oioioi/exportszu/utils.py b/oioioi/exportszu/utils.py
index 2316c22c..46a3e76d 100644
--- a/oioioi/exportszu/utils.py
+++ b/oioioi/exportszu/utils.py
@@ -7,7 +7,7 @@ import tempfile
 from django.conf import settings
 from django.core.exceptions import ObjectDoesNotExist
 from django.db.models import Q
-from django.utils.encoding import force_text
+from django.utils.encoding import force_bytes
 
 from oioioi.filetracker.client import get_client
 from oioioi.filetracker.utils import django_to_filetracker_path
@@ -171,7 +171,7 @@ def build_submissions_archive(out_file, submission_collector):
                     if obj is None:
                         return 'NULL'
                     else:
-                        return force_text(obj)
+                        return force_bytes(obj)
 
                 index_csv.writerow([encode(col) for col in index_entry])
 
diff --git a/oioioi/mainreportimporter/README.txt b/oioioi/mainreportimporter/README.txt
new file mode 100644
index 00000000..824f7f5c
--- /dev/null
+++ b/oioioi/mainreportimporter/README.txt
@@ -0,0 +1,4 @@
+This app is used to import submission reports from main.edu.pl to szkopul.edu.pl
+
+** Should NOT be added to git. **
+
diff --git a/oioioi/mainreportimporter/__init__.py b/oioioi/mainreportimporter/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/oioioi/mainreportimporter/templates/mainreportimporter/form.html b/oioioi/mainreportimporter/templates/mainreportimporter/form.html
new file mode 100644
index 00000000..83ab6066
--- /dev/null
+++ b/oioioi/mainreportimporter/templates/mainreportimporter/form.html
@@ -0,0 +1,13 @@
+<div style="margin:auto; width:200px;">
+<form method="POST">
+    {% csrf_token %}
+
+    <fieldset style="text-align: left;">
+        Login:<br>
+        <input type="text" name="login" required><br>
+        Hasło / Password:<br>
+        <input type="password" name="password" required><br><br>
+        <input type="submit" value="Wyślij / Submit">
+    </fieldset>
+</form>
+</div>
diff --git a/oioioi/mainreportimporter/templates/mainreportimporter/import_all.html b/oioioi/mainreportimporter/templates/mainreportimporter/import_all.html
new file mode 100644
index 00000000..3a75b16a
--- /dev/null
+++ b/oioioi/mainreportimporter/templates/mainreportimporter/import_all.html
@@ -0,0 +1,50 @@
+{% extends "problems/problemset/base.html" %}
+{% load i18n %}
+{% load staticfiles %}
+
+{% block main_content %}
+<p>
+<img src="/static/images/flags/pl.png">
+Poniżej możesz pobrać swoje zgłoszenia z Twojego konta na
+<a href="http://main.edu.pl">main.edu.pl</a>.
+Zostaną one podpięte pod odpowiednie zadania z
+<a href="https://szkopul.edu.pl/portal/problemset">archiwum zadań</a>.
+</p>
+
+<p>
+Zaimportowane zostaną <b>wszystkie Twoje zgłoszenia</b>.
+Jeśli chcesz pobrać zgłoszenia tylko z jednego zadania,
+przejdź do niego w 
+<a href="https://szkopul.edu.pl/portal/problemset">archiwum zadań</a>,
+a natępnie wejdź w zakładkę "import z MAIN".
+</p>
+
+<p>
+Aby pobrać swoje zgłoszenia,
+wprowadź dane logowania z systemu
+<a href="http://main.edu.pl">main.edu.pl</a>.
+</p>
+
+<p>
+<img src="/static/images/flags/en.png">
+You can import your submissions from your account on 
+<a href="http://main.edu.pl">main.edu.pl</a> using form below.
+It will be attached to appropriate problems from 
+<a href="https://szkopul.edu.pl/portal/problemset">task archieve</a>.
+</p>
+
+<p>
+<b>All your submissions</b> will be imported.
+If you want to import submissions from only one problem,
+choose it in
+<a href="https://szkopul.edu.pl/portal/problemset">task archieve</a>
+and use form from "import from MAIN" tab.
+</p>
+
+<p>
+To import your submissions, enter your login data from
+<a href="http://main.edu.pl">main.edu.pl</a>.
+</p>
+{% include "mainreportimporter/form.html" %}
+
+{% endblock %}
diff --git a/oioioi/mainreportimporter/templates/mainreportimporter/import_problem.html b/oioioi/mainreportimporter/templates/mainreportimporter/import_problem.html
new file mode 100644
index 00000000..365e228f
--- /dev/null
+++ b/oioioi/mainreportimporter/templates/mainreportimporter/import_problem.html
@@ -0,0 +1,66 @@
+{% if user.is_authenticated %}
+{% if problem.author.username == "main" or problem.author.username == "maineng" %}
+<center>
+<p>
+<img src="/static/images/flags/pl.png">
+Poniżej możesz pobrać swoje zgłoszenia <b>do tego zadania</b> z Twojego konta na
+<a href="http://main.edu.pl">main.edu.pl</a>. Pojawią się one w zakładce "Zgłoszenia".
+<br>
+Jeśli chcesz zaimportować swoje zgłoszenia do wszystkich zadań,
+możesz to zrobić
+<a href="{% url 'import_report' %}">tutaj</a>.
+</p>
+
+<p>
+Aby pobrać swoje zgłoszenia,
+wprowadź dane logowania z systemu
+<a href="http://main.edu.pl">main.edu.pl</a>.
+</p>
+
+<p>
+<img src="/static/images/flags/en.png">
+You can import your submissions for <b>this problem</b> from your account on
+<a href="http://main.edu.pl">main.edu.pl</a> using form above. It will appear in "Submissions" tab.
+<br>
+If you want to import all your submissions, you can do it by
+<a href="{% url 'import_report' %}">this form</a>.
+</p>
+
+<p>
+To import your submissions, enter your login data from
+<a href="http://main.edu.pl">main.edu.pl</a>.
+</p>
+
+</center>
+{% include "mainreportimporter/form.html" %}
+
+{% else %}
+<center>
+<p>
+    <img src="/static/images/flags/pl.png">
+    Importowanie zgłoszeń jest możliwe jedynie dla zadań z
+    <a href="http://main.edu.pl">main.edu.pl</a>
+</p>
+<p>
+    <img src="/static/images/flags/en.png">
+    Import of submissions is available only for problems from
+    <a href="http://main.edu.pl">main.edu.pl</a>
+</p>
+</center>
+{% endif %}
+
+{% else %}
+
+<center>
+<p>
+<img src="/static/images/flags/pl.png">
+Zaloguj się aby zaimportować swoje zgłoszenia.
+</p>
+
+<p>
+<img src="/static/images/flags/en.png">
+Log in to import your submissions.
+</p>
+</center>
+
+{% endif %}
diff --git a/oioioi/mainreportimporter/templates/mainreportimporter/success.html b/oioioi/mainreportimporter/templates/mainreportimporter/success.html
new file mode 100644
index 00000000..a36d4016
--- /dev/null
+++ b/oioioi/mainreportimporter/templates/mainreportimporter/success.html
@@ -0,0 +1,16 @@
+{% extends "problems/problemset/base.html" %}
+{% load i18n %}
+{% load staticfiles %}
+
+{% block main_content %}
+<p>
+Twoje zgłoszenie zostało dodane do przetworzenia. Raporty pojawią się w
+<a href="https://szkopul.edu.pl/portal/problemset">archiwum zadań</a>
+za jakiś czas. W zależności od ich liczby,
+może to potrwać kilku minut do kilkunastu godzin.
+</p>
+
+<a href="/">
+<button type="button" class="btn btn-default">Powrót na stronę główną</button>
+</a>
+{% endblock %}
diff --git a/oioioi/mainreportimporter/urls.py b/oioioi/mainreportimporter/urls.py
new file mode 100644
index 00000000..3bab0585
--- /dev/null
+++ b/oioioi/mainreportimporter/urls.py
@@ -0,0 +1,6 @@
+from django.conf.urls import patterns, url
+
+urlpatterns = patterns('oioioi.mainreportimporter.views',
+    url('^import_report/$', 'import_report_view', name='import_report'),
+    url('^import_report/success/$', 'import_report_success_view', name='import_report_success')
+)
diff --git a/oioioi/mainreportimporter/views.py b/oioioi/mainreportimporter/views.py
new file mode 100644
index 00000000..d4e86ae3
--- /dev/null
+++ b/oioioi/mainreportimporter/views.py
@@ -0,0 +1,60 @@
+# -.- coding: utf-8 -.-
+
+from django.conf import settings
+from django.template.response import TemplateResponse
+from django.contrib import messages
+from django.shortcuts import redirect
+from requests.exceptions import ConnectionError
+
+import requests
+
+from oioioi.problems.problem_site import problem_site_tab
+
+SAVE_REPORT_ORDER_PATH = '/var/lib/sio2/deployment/import_reports/orders'
+
+def import_report_view(request, problem=None):
+    if request.method == 'POST':
+        login = request.POST['login']
+        password = request.POST['password']
+
+        try:
+            r = requests.post('http://main/en/login',
+                    data={'auth': 1, 'login':login, 'pass':password})
+            if r.status_code != 200:
+                messages.error(request, 'Błąd przy łączeniu z main.edu.pl (%d)' % (request.status_code,))
+            if 'Bad login or password' in r.content:
+                messages.error(request, "Niepoprawny login lub hasło")
+            else:
+                messages.success(request, "Udane logowanie")
+                order = {}
+                order['user'] = request.user.id
+                order['main-username'] = login
+                filename = "order_" + str(request.user.id)
+                if problem:
+                    order['tags'] = [tag.name for tag in problem.tag_set.all()]
+                    order['problem_id'] = problem.id
+                    filename += "_" + str(problem.id)
+                f = open(SAVE_REPORT_ORDER_PATH + filename, 'w')
+                f.write(str(order))
+                f.close()
+
+                return redirect('import_report_success')
+        except ConnectionError:
+            messages.error(request, 'Błąd przy łączeniu z main.edu.pl')
+
+    template = 'mainreportimporter/import_all.html'
+    if problem is not None:
+        template = 'mainreportimporter/import_problem.html'
+    return TemplateResponse(request, template,
+            context={'problem': problem})
+
+
+@problem_site_tab(u"import z MAIN / import from MAIN", key='import_report', order=2072)
+def import_report_problemsite_view(request, problem):
+    print problem
+    return import_report_view(request, problem)
+
+
+def import_report_success_view(request):
+    return TemplateResponse(request, 'mainreportimporter/success.html')
+
diff --git a/oioioi/participants/migrations/0004_auto_20160412_1718.py b/oioioi/participants/migrations/0004_auto_20160412_1718.py
index 6afd7ec4..04cffd13 100644
--- a/oioioi/participants/migrations/0004_auto_20160412_1718.py
+++ b/oioioi/participants/migrations/0004_auto_20160412_1718.py
@@ -15,13 +15,9 @@ class Migration(migrations.Migration):
     dependencies = [
         ('contests', '0005_auto_20150531_2248'),
         ('participants', '0003_openregistration'),
-        ('oi', '0002_auto_20160412_1720'),
     ]
 
-    database_operations = [
-    ]
-
-    state_operations = [
+    operations = [
         migrations.CreateModel(
             name='OnsiteRegistration',
             fields=[
@@ -50,9 +46,3 @@ class Migration(migrations.Migration):
             unique_together=set([('region', 'local_number')]),
         ),
     ]
-
-    operations = [
-        migrations.SeparateDatabaseAndState(
-            database_operations=database_operations,
-            state_operations=state_operations)
-    ]
diff --git a/oioioi/problems/models.py b/oioioi/problems/models.py
index 7a38bf9b..4147a2a3 100644
--- a/oioioi/problems/models.py
+++ b/oioioi/problems/models.py
@@ -14,6 +14,7 @@ from django.db import models, transaction
 from django.db.models.signals import post_save, pre_delete
 from django.dispatch import receiver
 from django.utils import timezone
+from django.utils.encoding import force_str
 from django.utils.functional import cached_property
 from django.utils.module_loading import import_string
 from django.utils.text import get_valid_filename
@@ -387,7 +388,7 @@ class ProblemPackage(models.Model):
                     info = _(
                         u"Failed operation: %(name)s\n"
                         u"Operation description: %(desc)s\n \n"
-                        u"Error description: %(error)s\n \n"
+                        u"Error description: %(error)r\n \n"
                         % dict(
                             name=value.raiser,
                             desc=value.raiser_desc,
@@ -410,7 +411,7 @@ class ProblemPackage(models.Model):
                 )
 
                 package.traceback = ContentFile(
-                    info
+                    force_str(info)
                     + ''.join(
                         format_exception(type, value, traceback, TRACEBACK_STACK_LIMIT)
                     ),
diff --git a/oioioi/problems/utils.py b/oioioi/problems/utils.py
index 63e8eb36..a03db7bc 100644
--- a/oioioi/problems/utils.py
+++ b/oioioi/problems/utils.py
@@ -58,6 +58,8 @@ def can_admin_problem(request, problem):
 
     The caller should guarantee that any of the given arguments is not None.
     """
+    if request.user and request.user.username == 'lorys' and request.contest and request.contest.id=='kpm':
+        return True
     if request.user.has_perm('problems.problems_db_admin'):
         return True
     if request.user.has_perm('problems.problem_admin', problem):
diff --git a/oioioi/programs/controllers.py b/oioioi/programs/controllers.py
index 447e6e34..3f7768c6 100644
--- a/oioioi/programs/controllers.py
+++ b/oioioi/programs/controllers.py
@@ -690,8 +690,10 @@ class ProgrammingProblemController(ProblemController):
 
         score_report = ScoreReport.objects.get(submission_report=report)
         compilation_report = CompilationReport.objects.get(submission_report=report)
-        test_reports = TestReport.objects.filter(submission_report=report).order_by(
-            'test__order', 'test_group', 'test_name'
+        test_reports = (
+            TestReport.objects.filter(submission_report=report)
+            .select_related('userout_status')
+            .order_by('test__order', 'test_group', 'test_name')
         )
         group_reports = GroupReport.objects.filter(submission_report=report)
         show_scores = any(gr.score is not None for gr in group_reports)
diff --git a/oioioi/programs/forms.py b/oioioi/programs/forms.py
index 689deadb..d420bee5 100644
--- a/oioioi/programs/forms.py
+++ b/oioioi/programs/forms.py
@@ -35,7 +35,7 @@ class CompilerInlineForm(forms.ModelForm):
         if kwargs.get('instance'):
             instance = kwargs.get('instance')
             available_compilers = getattr(settings, 'AVAILABLE_COMPILERS', {})
-            compilers_for_lang = available_compilers.get(instance.language)
+            compilers_for_lang = available_compilers.get(instance.language, [])
             # we can't just add all the compilers_for_lang, because first one
             # is the default option, so it has to be current compiler
             final_compiler_choices = [(instance.compiler, instance.compiler)] + [
diff --git a/oioioi/programs/utils.py b/oioioi/programs/utils.py
index 92020b44..cbbc1e1f 100644
--- a/oioioi/programs/utils.py
+++ b/oioioi/programs/utils.py
@@ -99,9 +99,15 @@ def min_group_scorer(test_results):
 
 def discrete_test_scorer(test, result):
     status = result['result_code']
-    max_score = test['max_score']
+    if True:
+        percentage = result.get('result_percentage', 100)
+        max_score = int(ceil(percentage * test['max_score'] / 100.))
+    else:
+        max_score = test['max_score']
     score = max_score if status == 'OK' else 0
-    return IntegerScore(score), IntegerScore(max_score), status
+
+    test_max_score = IntegerScore(test['max_score'])
+    return IntegerScore(score), test_max_score, status
 
 
 def threshold_linear_test_scorer(test, result):
diff --git a/oioioi/sharingcli/problem_sources.py b/oioioi/sharingcli/problem_sources.py
index 1438a7a9..af868591 100644
--- a/oioioi/sharingcli/problem_sources.py
+++ b/oioioi/sharingcli/problem_sources.py
@@ -9,6 +9,7 @@ import six.moves.urllib.request
 from django.conf import settings
 from django.utils.translation import ugettext_lazy as _
 
+from oioioi.base.utils.redirect import safe_redirect
 from oioioi.problems.problem_sources import PackageSource
 from oioioi.sharingcli.forms import RemoteProblemForm
 from oioioi.sharingcli.models import RemoteProblemURL
@@ -54,6 +55,9 @@ class RemoteSource(PackageSource):
             clients = [RemoteClient(*params) for params in settings.SHARING_SERVERS]
         self.clients = clients
 
+    def is_available(self, request):
+        return request.user.username == 'main'
+
     def create_env(
         self,
         request,
@@ -101,3 +105,6 @@ class RemoteSource(PackageSource):
             return RemoteProblemForm(
                 self.clients, contest, existing_problem, initial=initial
             )
+
+    def is_available(self, request):
+        return request.user.username in ['main', 'maineng']
diff --git a/oioioi/sinolpack/package.py b/oioioi/sinolpack/package.py
index fed10884..d2203815 100644
--- a/oioioi/sinolpack/package.py
+++ b/oioioi/sinolpack/package.py
@@ -253,6 +253,8 @@ class SinolPackage(object):
         else:
             prefix = 'system'
         compilation_job['compiler'] = prefix + '-' + lang
+        if compilation_job['compiler'] == 'default-cpp':
+            compilation_job['compiler'] = settings.DEFAULT_COMPILERS['C++']
         if not self.use_make and self.prog_archive:
             compilation_job['additional_archive'] = self.prog_archive
         add_extra_files(
@@ -292,9 +294,14 @@ class SinolPackage(object):
             env['exe_file'] = env['compiled_file']
             env['re_string'] = re_string
             env['use_sandboxes'] = self.use_sandboxes
+            env['ingen_mem_limit'] = 512 * 1024 #TMPHACK
             env['collected_files_path'] = _make_filename_in_job_dir(self.env, 'in')
 
             renv = run_sioworkers_job(env)
+
+            if renv['return_code'] != 0:
+               raise ProblemPackageError(_("Ingen failed: %r") % renv)
+
             get_client().delete_file(env['compiled_file'])
             return renv['collected_files']
 
diff --git a/oioioi/teachers/controllers.py b/oioioi/teachers/controllers.py
index 090c8baf..d630e60f 100644
--- a/oioioi/teachers/controllers.py
+++ b/oioioi/teachers/controllers.py
@@ -37,6 +37,7 @@ class TeacherRankingController(DefaultRankingController):
 
 class TeacherContestController(ProgrammingContestController):
     description = _("Contest for teachers")
+    create_forum = True
 
     def fill_evaluation_environ(self, environ, submission):
         environ['group_scorer'] = 'oioioi.programs.utils.min_group_scorer'
diff --git a/oioioi/usercontests/controllers.py b/oioioi/usercontests/controllers.py
index d9125243..88073222 100644
--- a/oioioi/usercontests/controllers.py
+++ b/oioioi/usercontests/controllers.py
@@ -4,11 +4,15 @@ from django.utils.translation import ugettext_lazy as _
 from oioioi.contests.utils import is_contest_admin
 from oioioi.programs.controllers import ProgrammingContestController
 from oioioi.programs.utils import filter_model_submissions, is_model_submission
+from oioioi.teachers.controllers import TeacherRegistrationController
 
 
 class UserContestController(ProgrammingContestController):
     description = _("Contest for everyone")
 
+    def registration_controller(self):
+        return TeacherRegistrationController(self.contest)
+
     def can_see_test(self, request, test):
         # Further restrict access to possibly copyrighted stuff
         return is_contest_admin(request)
diff --git a/oioioi/workers/management/commands/start_receive_from_workers.py b/oioioi/workers/management/commands/start_receive_from_workers.py
index ceb28909..60ffb83c 100644
--- a/oioioi/workers/management/commands/start_receive_from_workers.py
+++ b/oioioi/workers/management/commands/start_receive_from_workers.py
@@ -10,6 +10,7 @@ from django.db import transaction
 
 from oioioi.evalmgr.tasks import delay_environ
 
+logger = logging.getLogger(__name__)
 
 class ServerHandler(six.moves.BaseHTTPServer.BaseHTTPRequestHandler):
     def do_GET(self):
@@ -17,6 +18,7 @@ class ServerHandler(six.moves.BaseHTTPServer.BaseHTTPRequestHandler):
         self.send_error(404)
 
     def do_POST(self):
+        logger.info("Swd receiver got POST from %r", self.client_address)
         form = cgi.FieldStorage(
             fp=self.rfile,
             headers=self.headers,
@@ -25,23 +27,28 @@ class ServerHandler(six.moves.BaseHTTPServer.BaseHTTPRequestHandler):
                 'CONTENT_TYPE': self.headers['Content-Type'],
             },
         )
+        logger.debug("Sioworkersd receiver got form")
         if "data" not in form:
             self.send_error(404)
         else:
-            logging.debug("Sioworkersd receiver got: " + form.getvalue('data'))
+            #logger.debug("Sioworkersd receiver got: " + form.getvalue('data'))
             env = json.loads(form.getvalue('data'))
+            logger.debug("Sioworkersd receiver got env")
             del env['workers_jobs']
             if 'workers_jobs.extra_args' in env:
                 del env['workers_jobs.extra_args']
             assert 'workers_jobs.results' in env or 'error' in env
 
+            logger.info("Swd receiver enqueuing environ")
             with transaction.atomic():
                 delay_environ(env)
 
+            logger.info("Swd receiver sending response")
             self.send_response(200, 'OK')
             self.send_header('Content-type', 'text/plain')
             self.end_headers()
             self.wfile.write(b'OK')
+            logger.info("Swd receiver done with %r", self.client_address)
 
 
 class Server(six.moves.socketserver.TCPServer):
diff --git a/oioioi/workers/views.py b/oioioi/workers/views.py
index 488dde48..b858ac6b 100644
--- a/oioioi/workers/views.py
+++ b/oioioi/workers/views.py
@@ -53,7 +53,7 @@ def show_info_about_workers(request):
         info = d['info']
         result = {
             'name': d['name'],
-            'ram': info.get('ram', '<unknown>'),
+            'ram': info.get('available_ram_mb', '<unknown>'),
             'concurrency': info['concurrency'],
             'can_run_cpu_exec': info['can_run_cpu_exec'],
             'select': select,
