diff --git a/models/database.py b/models/database.py
index 582c9ece0f1faad29f2f7f443d4586861988e6d1..2ca9abccc8c6b0225237f016520ece1bb9147b43 100644
--- a/models/database.py
+++ b/models/database.py
@@ -4,7 +4,7 @@ from datetime import datetime, time, date, timedelta
 import math
 
 from shared import db
-from utils import random_string, url_manager
+from utils import random_string, url_manager, get_etherpad_url
 from models.errors import DateNotMatchingException
 
 import os
@@ -128,10 +128,7 @@ class Protocol(db.Model):
         identifier = self.get_identifier()
         if identifier is None:
             return ""
-        return config.ETHERPAD_URL + self.get_identifier()
-
-    def get_etherpad_source_link(self):
-        return self.get_etherpad_link() + "/export/txt"
+        return get_etherpad_url(self.get_identifier())
 
     def has_nonplanned_tops(self):
         return len([top for top in self.tops if not top.planned]) > 0
diff --git a/requirements.txt b/requirements.txt
index 5b99e670aed8f6717aac26d6ed92001613f8988d..78fd29d3b2f7a85a018f12b226677f767f69a521 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,15 +3,19 @@ amqp==2.1.4
 appdirs==1.4.0
 argh==0.26.2
 billiard==3.5.0.2
+blessings==1.6
 blinker==1.4
+bpython==0.16
 celery==4.0.2
 click==6.7
+curtsies==0.2.11
 Flask==0.12
 Flask-Migrate==2.0.3
 Flask-Script==2.0.5
 Flask-SocketIO==2.8.4
 Flask-SQLAlchemy==2.1
 Flask-WTF==0.14.2
+greenlet==0.4.12
 itsdangerous==0.24
 Jinja2==2.9.5
 kombu==4.0.2
@@ -20,6 +24,7 @@ MarkupSafe==0.23
 packaging==16.8
 pathtools==0.1.2
 psycopg2==2.6.2
+Pygments==2.2.0
 pyldap==2.4.28
 pyparsing==2.1.10
 python-editor==1.0.3
@@ -34,5 +39,6 @@ six==1.10.0
 SQLAlchemy==1.1.5
 vine==1.1.3
 watchdog==0.8.3
+wcwidth==0.1.7
 Werkzeug==0.11.15
 WTForms==2.1
diff --git a/server.py b/server.py
index a9d1962a935e9ff0be8ce1139cb1e8f6af370c94..befafacba92dd7c6ce55bd99a27bb84bfd230882 100755
--- a/server.py
+++ b/server.py
@@ -8,14 +8,13 @@ from flask_script import Manager, prompt
 from flask_migrate import Migrate, MigrateCommand
 #from flask_socketio import SocketIO
 from celery import Celery
-import requests
 from io import StringIO, BytesIO
 import os
 from datetime import datetime
 
 import config
 from shared import db, date_filter, datetime_filter, date_filter_long, time_filter, ldap_manager, security_manager, current_user, check_login, login_required, group_required
-from utils import is_past, mail_manager, url_manager, get_first_unused_int
+from utils import is_past, mail_manager, url_manager, get_first_unused_int, set_etherpad_text, get_etherpad_text
 from models.database import ProtocolType, Protocol, DefaultTOP, TOP, Document, Todo, Decision, MeetingReminder, Error
 from views.forms import LoginForm, ProtocolTypeForm, DefaultTopForm, MeetingReminderForm, NewProtocolForm, DocumentUploadForm, KnownProtocolSourceUploadForm, NewProtocolSourceUploadForm, ProtocolForm, TopForm
 from views.tables import ProtocolsTable, ProtocolTypesTable, ProtocolTypeTable, DefaultTOPsTable, MeetingRemindersTable, ErrorsTable, TodosTable, DocumentsTable
@@ -351,9 +350,7 @@ def etherpull_protocol(protocol_id):
     if protocol is None or not protocol.protocoltype.has_modify_right(user):
         flash("Invalides Protokoll oder keine Berechtigung.", "alert-error")
         return redirect(request.args.get("next") or url_for("index"))
-    source_req = requests.get(protocol.get_etherpad_source_link())
-    source = source_req.text
-    protocol.source = source
+    protocol.source = get_etherpad_text(protocol.get_identifier())
     db.session.commit()
     tasks.parse_protocol(protocol)
     flash("Das Protokoll wird kompiliert.", "alert-success")
@@ -435,6 +432,20 @@ def get_protocol_template(protocol_id):
     file_like = BytesIO(protocol.get_template().encode("utf-8"))
     return send_file(file_like, cache_timeout=1, as_attachment=True, attachment_filename="{}-template.txt".format(protocol.get_identifier()))
 
+@app.route("/protocol/etherpush/<int:protocol_id>")
+@login_required
+def etherpush_protocol(protocol_id):
+    user = current_user()
+    protocol = Protocol.query.filter_by(id=protocol_id).first()
+    if protocol is None or not protocol.protocoltype.has_modify_right(user):
+        flash("Invalides Protokoll oder keine Berechtigung.", "alert-error")
+        return redirect(request.args.get("next") or url_for("index"))
+    if set_etherpad_text(protocol.get_identifier(), protocol.get_template()):
+        flash("Vorlage von {} in Etherpad hochgeladen.".format(protocol.get_identifier()), "alert-success")
+    else:
+        flash("Das Etherpad wurde bereits bearbeitet.", "alert-error")
+    return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id))
+
 @app.route("/protocol/update/<int:protocol_id>", methods=["GET", "POST"])
 @login_required
 def update_protocol(protocol_id):
diff --git a/shared.py b/shared.py
index 9761b10c54092fa978f5ea3a49801aeb9963941f..d7a6b65e4dbe57be217c8b55f32737d2f36cd1c1 100644
--- a/shared.py
+++ b/shared.py
@@ -111,9 +111,4 @@ def group_required(function, group):
             return redirect(request.args.get("next") or url_for("index"))
     return decorated_function
 
-EMPTY_ETHERPAD = """Welcome to Etherpad!
 
-This pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!
-
-Get involved with Etherpad at http://etherpad.org
-"""
diff --git a/templates/protocol-show.html b/templates/protocol-show.html
index 20dd1a6983112fb4e53cac72744bfe652cb9364b..2f9a02ee8fb15034a5974cf81b3a0b22a84d72c6 100644
--- a/templates/protocol-show.html
+++ b/templates/protocol-show.html
@@ -18,7 +18,8 @@
             {% endif %} 
             <a class="btn {% if protocol.is_done() %}btn-success{% else %}btn-default{% endif %}" href="{{url_for("update_protocol", protocol_id=protocol.id)}}">Protokoll editieren</a>
             {% if not protocol.is_done() %}
-                <a class="btn btn-default" href="{{url_for("get_protocol_template", protocol_id=protocol.id)}}">Vorlage herunterladen</a>
+                <a class="btn btn-default" href="{{url_for("get_protocol_template", protocol_id=protocol.id)}}">Vorlage</a>
+                <a class="btn btn-primary" href="{{url_for("etherpush_protocol", protocol_id=protocol.id)}}">In Etherpad</a>
             {% endif %}
             <a class="btn btn-default" href="{{protocol.get_etherpad_link()}}" target="_blank">Etherpad</a>
             <a class="btn btn-default" href="{{url_for("show_type", type_id=protocol.protocoltype.id)}}">Typ</a>
diff --git a/utils.py b/utils.py
index 47738f34704e7782ae55291ae7548adefc385a00..6d818bc921a1d59084ac33e27c86a0fa30109944 100644
--- a/utils.py
+++ b/utils.py
@@ -7,6 +7,8 @@ import smtplib
 from email.mime.multipart import MIMEMultipart
 from email.mime.text import MIMEText
 from datetime import datetime, date, timedelta
+import requests
+from io import BytesIO
 
 import config
 
@@ -100,3 +102,25 @@ def get_first_unused_int(numbers):
         if linear < given:
             return linear
     return highest + 1
+
+def get_etherpad_url(pad):
+    return "{}/p/{}".format(config.ETHERPAD_URL, pad)
+def get_etherpad_export_url(pad):
+    return "{}/p/{}/export/txt".format(config.ETHERPAD_URL, pad)
+def get_etherpad_import_url(pad):
+    return "{}/p/{}/import".format(config.ETHERPAD_URL, pad)
+
+def get_etherpad_text(pad):
+    req = requests.get("{}/p/{}/export/txt".format(config.ETHERPAD_URL, pad))
+    return req.text
+
+def set_etherpad_text(pad, text, only_if_default=True):
+    if only_if_default:
+        current_text = get_etherpad_text(pad)
+        if current_text != config.EMPTY_ETHERPAD and len(current_text.strip()) > 0:
+            return False
+    file_like = BytesIO(text.encode("utf-8"))
+    files = {"file": file_like}
+    req = requests.post(get_etherpad_import_url(pad), files=files)
+    return req.status_code == 200
+