diff --git a/common/decorators.py b/common/decorators.py
index c15d44119a62fe507ce1456c36eda860bc36bca8..7c1f4d85f75fdb2f0296f0a8e9c304767b963264 100644
--- a/common/decorators.py
+++ b/common/decorators.py
@@ -1,5 +1,12 @@
 from django.http import HttpResponseBadRequest
 
+from functools import wraps
+from inspect import getargspec
+from django.http import HttpResponse
+from simplejson import loads as json_decode, dumps as json_encode
+from common.util import stringify_keys
+from django.db import transaction
+
 #https://djangosnippets.org/snippets/771/
 def ajax_required(f):
     def wrap(request, *args, **kwargs):
@@ -9,3 +16,46 @@ def ajax_required(f):
     wrap.__doc__=f.__doc__
     wrap.__name__=f.__name__
     return wrap
+
+class AjaxError(Exception):
+    pass
+
+def json_decode_fallback(value):
+    try:
+        return json_decode(value)
+    except ValueError:
+        return value
+
+def ajax(login_required=False, method=None, encode_result=True):
+    def decorator(fun):
+        @wraps(fun)
+        def ajax_view(request):
+            kwargs = {}
+            request_params = None
+            if method == 'post':
+                request_params = request.POST
+            elif method == 'get':
+                request_params = request.GET
+            fun_params, xx, fun_kwargs, xxxx = getargspec(fun)
+            if request_params:
+                request_params = dict((key, json_decode_fallback(value))
+                                      for key, value in request_params.items()
+                                      if fun_kwargs or key in fun_params)
+                kwargs.update(stringify_keys(request_params))
+            res = None
+            if login_required and not request.user.is_authenticated():
+                res = {'result': 'logout'}
+            if not res:
+                try:
+                    res = fun(request, **kwargs)
+                except AjaxError as e:
+                    res = {'result': e.args[0]}
+                    transaction.rollback()
+            if encode_result:
+                if 'result' not in res:
+                    res['result'] = 'ok'
+                return HttpResponse(json_encode(res))
+            else:
+                return res
+        return ajax_view
+    return decorator
diff --git a/common/util.py b/common/util.py
new file mode 100644
index 0000000000000000000000000000000000000000..7fe84a431bc0ffc612ceb55067a78507da7afef8
--- /dev/null
+++ b/common/util.py
@@ -0,0 +1,3 @@
+def stringify_keys(dictionary):
+    return dict((str(keyword), value)
+        for keyword, value in dictionary.items())
diff --git a/entries/static/entries/css/jquery-impromptu.min.css b/entries/static/entries/css/jquery-impromptu.min.css
new file mode 100644
index 0000000000000000000000000000000000000000..8b031333bf53124f98f13de67eee67449a796217
--- /dev/null
+++ b/entries/static/entries/css/jquery-impromptu.min.css
@@ -0,0 +1,211 @@
+/*! jQuery-Impromptu - v5.2.4 - 2014-05-26
+* http://trentrichardson.com/Impromptu
+* Copyright (c) 2014 Trent Richardson; Licensed MIT */
+div.jqibox {
+    z-index: 1030 !important;
+}
+
+ul.ui-autocomplete {
+    z-index: 1031 !important;
+}
+
+.jqifade {
+    position: absolute;
+    background-color: #777;
+}
+
+div.jqi {
+    max-width: 90%;
+    font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
+    position: absolute;
+    background-color: #fff;
+    font-size: 11px;
+    text-align: left;
+    border: solid 1px #eee;
+    border-radius: 6px;
+    -moz-border-radius: 6px;
+    -webkit-border-radius: 6px;
+    padding: 7px
+}
+
+div.jqi .jqicontainer {
+}
+
+div.jqi .jqiclose {
+    position: absolute;
+    top: 4px;
+    right: -2px;
+    width: 18px;
+    cursor: default;
+    color: #bbb;
+    font-weight: 700
+}
+
+div.jqi .jqistate {
+    background-color: #fff
+}
+
+div.jqi .jqititle {
+    padding: 5px 10px;
+    font-size: 16px;
+    line-height: 20px;
+    border-bottom: solid 1px #eee
+}
+
+div.jqi .jqimessage {
+    padding: 10px;
+    line-height: 20px;
+    color: #444
+}
+
+div.jqi .jqibuttons {
+    text-align: right;
+    margin: 0 -7px -7px -7px;
+    border-top: solid 1px #e4e4e4;
+    background-color: #f4f4f4;
+    border-radius: 0 0 6px 6px;
+    -moz-border-radius: 0 0 6px 6px;
+    -webkit-border-radius: 0 0 6px 6px
+}
+
+div.jqi .jqibuttons button {
+    margin: 0;
+    padding: 15px 20px;
+    background-color: transparent;
+    font-weight: 400;
+    border: 0;
+    border-left: solid 1px #e4e4e4;
+    color: #777;
+    font-weight: 700;
+    font-size: 12px
+}
+
+div.jqi .jqibuttons button.jqidefaultbutton {
+    color: #489afe
+}
+
+div.jqi .jqibuttons button:hover, div.jqi .jqibuttons button:focus {
+    color: #287ade;
+    outline: 0
+}
+
+.jqiwarning .jqi .jqibuttons {
+    background-color: #b95656
+}
+
+div.jqi .jqiparentstate::after {
+    background-color: #777;
+    opacity: .6;
+    filter: alpha(opacity=60);
+    content: '';
+    position: absolute;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    border-radius: 6px;
+    -moz-border-radius: 6px;
+    -webkit-border-radius: 6px
+}
+
+div.jqi .jqisubstate {
+    position: absolute;
+    top: 0;
+    left: 20%;
+    width: 60%;
+    padding: 7px;
+    border: solid 1px #eee;
+    border-top: 0;
+    border-radius: 0 0 6px 6px;
+    -moz-border-radius: 0 0 6px 6px;
+    -webkit-border-radius: 0 0 6px 6px
+}
+
+div.jqi .jqisubstate .jqibuttons button {
+    padding: 10px 18px
+}
+
+.jqi .jqiarrow {
+    position: absolute;
+    height: 0;
+    width: 0;
+    line-height: 0;
+    font-size: 0;
+    border: solid 10px transparent
+}
+
+.jqi .jqiarrowtl {
+    left: 10px;
+    top: -20px;
+    border-bottom-color: #fff
+}
+
+.jqi .jqiarrowtc {
+    left: 50%;
+    top: -20px;
+    border-bottom-color: #fff;
+    margin-left: -10px
+}
+
+.jqi .jqiarrowtr {
+    right: 10px;
+    top: -20px;
+    border-bottom-color: #fff
+}
+
+.jqi .jqiarrowbl {
+    left: 10px;
+    bottom: -20px;
+    border-top-color: #fff
+}
+
+.jqi .jqiarrowbc {
+    left: 50%;
+    bottom: -20px;
+    border-top-color: #fff;
+    margin-left: -10px
+}
+
+.jqi .jqiarrowbr {
+    right: 10px;
+    bottom: -20px;
+    border-top-color: #fff
+}
+
+.jqi .jqiarrowlt {
+    left: -20px;
+    top: 10px;
+    border-right-color: #fff
+}
+
+.jqi .jqiarrowlm {
+    left: -20px;
+    top: 50%;
+    border-right-color: #fff;
+    margin-top: -10px
+}
+
+.jqi .jqiarrowlb {
+    left: -20px;
+    bottom: 10px;
+    border-right-color: #fff
+}
+
+.jqi .jqiarrowrt {
+    right: -20px;
+    top: 10px;
+    border-left-color: #fff
+}
+
+.jqi .jqiarrowrm {
+    right: -20px;
+    top: 50%;
+    border-left-color: #fff;
+    margin-top: -10px
+}
+
+.jqi .jqiarrowrb {
+    right: -20px;
+    bottom: 10px;
+    border-left-color: #fff
+}
diff --git a/entries/static/entries/js/entries.js b/entries/static/entries/js/entries.js
index aedb6d79d9b629e65904121da88a67c10b5a6714..1bda2081719971cab63fcff781ff1947fdc4f411 100644
--- a/entries/static/entries/js/entries.js
+++ b/entries/static/entries/js/entries.js
@@ -8,6 +8,7 @@ var curr_realisation_phrases = null;
 var curr_realisation_descriptions = null;
 var curr_examples = null;
 var curr_examples_by_id = null;
+var frame_content;
 
 function make_opinion_row(item, span, width) {
     var opinion_row = document.createElement('tr');
@@ -342,6 +343,9 @@ function show_semantics(frames, subentries) {
     var schemata_dom = subentries2dom(subentries);
     $('#semantics-schemata').append($(schemata_dom));
     var frames_dom = frames2dom(frames);
+
+    $('#semantics-frames').append('<button type="button" onclick="addSelectivePreference(frame_content[0], 1)" id="add_preference">Dodaj preferencje (przykład użycia - do wstawienia w odpowiednie miejsce)</button>');
+
     $('#semantics-frames').append($(frames_dom));
     
     $('.frame').mouseenter(function() {
@@ -798,6 +802,7 @@ function get_entry(entry_id, related) {
         data     : data,
         timeout  : 60000,
         success  : function(response) {
+            frame_content = response.frames;
             curr_entry = entry_id;
             curr_no_filters = related;
             clear_info();
@@ -1112,6 +1117,12 @@ $(document).ready(function() {
     initialize_schemata_form();
     
     //$('.local-filter').hide();
+
+    getPredefinedSelections();
+
+    $.getJSON('relations', function(data){
+        memorizeRelations(data.relations);
+    });
     
     $('#main-form').submit();
     
diff --git a/entries/static/entries/js/jquery-impromptu.min.js b/entries/static/entries/js/jquery-impromptu.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..b7295c694b9edbbfba322239132907face03658f
--- /dev/null
+++ b/entries/static/entries/js/jquery-impromptu.min.js
@@ -0,0 +1,4 @@
+/*! jQuery-Impromptu - v6.0.0 - 2014-12-27
+* http://trentrichardson.com/Impromptu
+* Copyright (c) 2014 Trent Richardson; Licensed MIT */
+(function(t,e){"function"==typeof define&&define.amd?define(["jquery"],e):e(t.jQuery)})(this,function(t){"use strict";var e=function(t,i){var n=this;return n.id=e.count++,e.lifo.push(n),t&&n.open(t,i),n};e.defaults={prefix:"jqi",classes:{box:"",fade:"",prompt:"",form:"",close:"",title:"",message:"",buttons:"",button:"",defaultButton:""},title:"",closeText:"&times;",buttons:{Ok:!0},loaded:function(){},submit:function(){},close:function(){},statechanging:function(){},statechanged:function(){},opacity:.6,zIndex:999,overlayspeed:"slow",promptspeed:"fast",show:"fadeIn",hide:"fadeOut",focus:0,defaultButton:0,useiframe:!1,top:"15%",position:{container:null,x:null,y:null,arrow:null,width:null},persistent:!0,timeout:0,states:{},state:{name:null,title:"",html:"",buttons:{Ok:!0},focus:0,defaultButton:0,position:{container:null,x:null,y:null,arrow:null,width:null},submit:function(){return!0}}},e.setDefaults=function(i){e.defaults=t.extend({},e.defaults,i)},e.setStateDefaults=function(i){e.defaults.state=t.extend({},e.defaults.state,i)},e.count=0,e.lifo=[],e.getLast=function(){var t=e.lifo.length;return t>0?e.lifo[t-1]:!1},e.removeFromStack=function(t){for(var i=e.lifo.length-1;i>=0;i--)if(e.lifo[i].id===t)return e.lifo.splice(i,1)[0]},e.prototype={id:null,open:function(i,n){var o=this;o.options=t.extend({},e.defaults,n),o.timeout&&clearTimeout(o.timeout),o.timeout=!1;var s=o.options,a=t(document.body),r=t(window),u='<div class="'+s.prefix+"box "+s.classes.box+'">';u+=s.useiframe&&t("object, applet").length>0?'<iframe src="javascript:false;" style="display:block;position:absolute;z-index:-1;" class="'+s.prefix+"fade "+s.classes.fade+'"></iframe>':'<div class="'+s.prefix+"fade "+s.classes.fade+'"></div>',u+='<div class="'+s.prefix+" "+s.classes.prompt+'">'+'<form action="javascript:false;" onsubmit="return false;" class="'+s.prefix+"form "+s.classes.form+'">'+'<div class="'+s.prefix+"close "+s.classes.close+'">'+s.closeText+"</div>"+'<div class="'+s.prefix+'states"></div>'+"</form>"+"</div>"+"</div>",o.jqib=t(u).appendTo(a),o.jqi=o.jqib.children("."+s.prefix),o.jqif=o.jqib.children("."+s.prefix+"fade"),i.constructor===String&&(i={state0:{title:s.title,html:i,buttons:s.buttons,position:s.position,focus:s.focus,defaultButton:s.defaultButton,submit:s.submit}}),o.options.states={};var f,l;for(f in i)l=t.extend({},e.defaults.state,{name:f},i[f]),o.addState(l.name,l),""===o.currentStateName&&(o.currentStateName=l.name);o.jqi.on("click","."+s.prefix+"buttons button",function(){var e=t(this),i=e.parents("."+s.prefix+"state"),n=o.options.states[i.data("jqi-name")],a=i.children("."+s.prefix+"message"),r=n.buttons[e.text()]||n.buttons[e.html()],u={};if(void 0===r)for(var f in n.buttons)(n.buttons[f].title===e.text()||n.buttons[f].title===e.html())&&(r=n.buttons[f].value);t.each(o.jqi.children("form").serializeArray(),function(t,e){void 0===u[e.name]?u[e.name]=e.value:typeof u[e.name]===Array||"object"==typeof u[e.name]?u[e.name].push(e.value):u[e.name]=[u[e.name],e.value]});var l=new t.Event("impromptu:submit");l.stateName=n.name,l.state=i,i.trigger(l,[r,a,u]),l.isDefaultPrevented()||o.close(!0,r,a,u)});var p=function(){if(s.persistent){var e=(""+s.top).indexOf("%")>=0?r.height()*(parseInt(s.top,10)/100):parseInt(s.top,10),i=parseInt(o.jqi.css("top").replace("px",""),10)-e;t("html,body").animate({scrollTop:i},"fast",function(){var t=0;o.jqib.addClass(s.prefix+"warning");var e=setInterval(function(){o.jqib.toggleClass(s.prefix+"warning"),t++>1&&(clearInterval(e),o.jqib.removeClass(s.prefix+"warning"))},100)})}else o.close(!0)},d=function(e){var i=window.event?event.keyCode:e.keyCode;if(27===i&&p(),13===i){var n=o.getCurrentState().find("."+s.prefix+"defaultbutton"),a=t(e.target);a.is("textarea,."+s.prefix+"button")===!1&&n.length>0&&(e.preventDefault(),n.click())}if(9===i){var r=t("input,select,textarea,button",o.getCurrentState()),u=!e.shiftKey&&e.target===r[r.length-1],f=e.shiftKey&&e.target===r[0];if(u||f)return setTimeout(function(){if(r){var t=r[f===!0?r.length-1:0];t&&t.focus()}},10),!1}};return o.position(),o.style(),o._windowResize=function(t){o.position(t)},r.resize({animate:!1},o._windowResize),o.jqif.click(p),o.jqi.find("."+s.prefix+"close").click(function(){o.close()}),o.jqib.on("keydown",d).on("impromptu:loaded",s.loaded).on("impromptu:close",s.close).on("impromptu:statechanging",s.statechanging).on("impromptu:statechanged",s.statechanged),o.jqif[s.show](s.overlayspeed),o.jqi[s.show](s.promptspeed,function(){var t=o.jqi.find("."+s.prefix+"states ."+s.prefix+"state").eq(0);o.goToState(t.data("jqi-name")),o.jqib.trigger("impromptu:loaded")}),s.timeout>0&&(o.timeout=setTimeout(function(){o.close(!0)},s.timeout)),o},close:function(i,n,o,s){var a=this;return e.removeFromStack(a.id),a.timeout&&(clearTimeout(a.timeout),a.timeout=!1),a.jqib&&a.jqib[a.options.hide]("fast",function(){a.jqib.trigger("impromptu:close",[n,o,s]),a.jqib.remove(),t(window).off("resize",a._windowResize),"function"==typeof i&&i()}),a.currentStateName="",a},addState:function(i,n,o){var s,a,r,u,f,l=this,p="",d=null,c="",m="",h=l.options,v=t("."+h.prefix+"states"),g=[],b=0;if(n=t.extend({},e.defaults.state,{name:i},n),null!==n.position.arrow&&(c='<div class="'+h.prefix+"arrow "+h.prefix+"arrow"+n.position.arrow+'"></div>'),n.title&&""!==n.title&&(m='<div class="lead '+h.prefix+"title "+h.classes.title+'">'+n.title+"</div>"),s=n.html,"function"==typeof n.html&&(s="Error: html function must return text"),p+='<div class="'+h.prefix+'state" data-jqi-name="'+i+'" style="display:none;">'+c+m+'<div class="'+h.prefix+"message "+h.classes.message+'">'+s+"</div>"+'<div class="'+h.prefix+"buttons "+h.classes.buttons+'"'+(t.isEmptyObject(n.buttons)?'style="display:none;"':"")+">",t.isArray(n.buttons))g=n.buttons;else if(t.isPlainObject(n.buttons))for(r in n.buttons)n.buttons.hasOwnProperty(r)&&g.push({title:r,value:n.buttons[r]});for(b=0,f=g.length;f>b;b++)u=g[b],a=n.focus===b||isNaN(n.focus)&&n.defaultButton===b?h.prefix+"defaultbutton "+h.classes.defaultButton:"",p+='<button class="'+h.classes.button+" "+h.prefix+"button "+a,u.classes!==void 0&&(p+=" "+(t.isArray(u.classes)?u.classes.join(" "):u.classes)+" "),p+='" name="'+h.prefix+"_"+i+"_button"+u.title.replace(/[^a-z0-9]+/gi,"")+'" value="'+u.value+'">'+u.title+"</button>";return p+="</div></div>",d=t(p),d.on("impromptu:submit",n.submit),void 0!==o?v.find('[data-jqi-name="'+o+'"]').after(d):v.append(d),l.options.states[i]=n,d},removeState:function(t,e){var i=this,n=i.getState(t),o=function(){n.remove()};return 0===n.length?!1:("none"!==n.css("display")?void 0!==e&&i.getState(e).length>0?i.goToState(e,!1,o):n.next().length>0?i.nextState(o):n.prev().length>0?i.prevState(o):i.close():n.slideUp("slow",o),!0)},getApi:function(){return this},getBox:function(){return this.jqib},getPrompt:function(){return this.jqi},getState:function(t){return this.jqi.find('[data-jqi-name="'+t+'"]')},getCurrentState:function(){return this.getState(this.getCurrentStateName())},getCurrentStateName:function(){return this.currentStateName},position:function(e){var i=this,n=t.fx.off,o=i.getCurrentState(),s=i.options.states[o.data("jqi-name")],a=s?s.position:void 0,r=t(window),u=document.body.scrollHeight,f=t(window).height(),l=(t(document).height(),u>f?u:f),p=parseInt(r.scrollTop(),10)+((""+i.options.top).indexOf("%")>=0?f*(parseInt(i.options.top,10)/100):parseInt(i.options.top,10));if(void 0!==e&&e.data.animate===!1&&(t.fx.off=!0),i.jqib.css({position:"absolute",height:l,width:"100%",top:0,left:0,right:0,bottom:0}),i.jqif.css({position:"fixed",height:l,width:"100%",top:0,left:0,right:0,bottom:0}),a&&a.container){var d=t(a.container).offset();t.isPlainObject(d)&&void 0!==d.top&&(i.jqi.css({position:"absolute"}),i.jqi.animate({top:d.top+a.y,left:d.left+a.x,marginLeft:0,width:void 0!==a.width?a.width:null}),p=d.top+a.y-((""+i.options.top).indexOf("%")>=0?f*(parseInt(i.options.top,10)/100):parseInt(i.options.top,10)),t("html,body").animate({scrollTop:p},"slow","swing",function(){}))}else a&&a.width?(i.jqi.css({position:"absolute",left:"50%"}),i.jqi.animate({top:a.y||p,left:a.x||"50%",marginLeft:-1*(a.width/2),width:a.width})):i.jqi.css({position:"absolute",top:p,left:"50%",marginLeft:-1*(i.jqi.outerWidth(!1)/2)});void 0!==e&&e.data.animate===!1&&(t.fx.off=n)},style:function(){var t=this;t.jqif.css({zIndex:t.options.zIndex,display:"none",opacity:t.options.opacity}),t.jqi.css({zIndex:t.options.zIndex+1,display:"none"}),t.jqib.css({zIndex:t.options.zIndex})},goToState:function(e,i,n){var o=this,s=(o.jqi,o.options),a=o.getState(e),r=s.states[a.data("jqi-name")],u=new t.Event("impromptu:statechanging"),f=o.options;if(void 0!==r){if("function"==typeof r.html){var l=r.html;a.find("."+f.prefix+"message ").html(l())}"function"==typeof i&&(n=i,i=!1),o.jqib.trigger(u,[o.getCurrentStateName(),e]),!u.isDefaultPrevented()&&a.length>0&&(o.jqi.find("."+f.prefix+"parentstate").removeClass(f.prefix+"parentstate"),i?(o.jqi.find("."+f.prefix+"substate").not(a).slideUp(s.promptspeed).removeClass("."+f.prefix+"substate").find("."+f.prefix+"arrow").hide(),o.jqi.find("."+f.prefix+"state:visible").addClass(f.prefix+"parentstate"),a.addClass(f.prefix+"substate")):o.jqi.find("."+f.prefix+"state").not(a).slideUp(s.promptspeed).find("."+f.prefix+"arrow").hide(),o.currentStateName=r.name,a.slideDown(s.promptspeed,function(){var i=t(this);"string"==typeof r.focus?i.find(r.focus).eq(0).focus():i.find("."+f.prefix+"defaultbutton").focus(),i.find("."+f.prefix+"arrow").show(s.promptspeed),"function"==typeof n&&o.jqib.on("impromptu:statechanged",n),o.jqib.trigger("impromptu:statechanged",[e]),"function"==typeof n&&o.jqib.off("impromptu:statechanged",n)}),i||o.position())}return a},nextState:function(t){var e=this,i=e.getCurrentState().next();return i.length>0&&e.goToState(i.data("jqi-name"),t),i},prevState:function(t){var e=this,i=e.getCurrentState().prev();return i.length>0&&e.goToState(i.data("jqi-name"),t),i}},t.prompt=function(t,i){var n=new e(t,i);return n.jqi},t.each(e,function(e,i){t.prompt[e]=i}),t.each(e.prototype,function(i){t.prompt[i]=function(){var t=e.getLast();return t&&"function"==typeof t[i]?t[i].apply(t,arguments):void 0}}),t.fn.prompt=function(e){void 0===e&&(e={}),void 0===e.withDataAndEvents&&(e.withDataAndEvents=!1),t.prompt(t(this).clone(e.withDataAndEvents).html(),e)},window.Impromptu=e});
\ No newline at end of file
diff --git a/entries/static/entries/js/selectional_preference.js b/entries/static/entries/js/selectional_preference.js
new file mode 100644
index 0000000000000000000000000000000000000000..d4a14e4d01b921afaa4a847c8b8fe9acf6eba0d9
--- /dev/null
+++ b/entries/static/entries/js/selectional_preference.js
@@ -0,0 +1,308 @@
+var predefined = [];
+var relations = [];
+var synsets = [];
+var change = false;
+
+function predefinedSelect() {
+    var display = "";
+
+    var i;
+    for (i = 0; i < predefined.length; i++) {
+        display += "<input type = \"checkbox\" name = \"predef\" value = \"" + predefined[i].id + "\">" + predefined[i].content + "<br>";
+    }
+
+    return display;
+}
+
+function getPredefinedSelections() {
+    $.ajax({
+        dataType: "json",
+        url: 'predefined_preferences',
+        success: function(data){
+            predefined = data.predefined;
+        },
+        async: false
+    });
+}
+
+function memorizeRelations(new_relations) {
+    relations = new_relations;
+}
+
+function relationsSelect() {
+    var display = "<select name = \"rel\">";
+
+    var i;
+    for (i = 0; i < relations.length; i++) {
+        display += "<option value = \"" + relations[i].id + "\">" + relations[i].content + "</option>";
+    }
+    display += "</select>"
+    return display;
+}
+
+function argumentSelect(frame, complement_id) {
+    var display = "<select name = \"arg\">";
+
+    var i;
+    for (i = 0; i < frame.arguments.length; i++) {
+        var local_complement_id = parseInt(frame.arguments[i].id.split('-')[1]);
+        if (local_complement_id != complement_id) {
+            // var list = frame_content[unified_frame_id].display.roles[i].argument;
+            //
+            // var text = [];
+            // var j;
+            // for (j = 0; j < list.length; j++) {
+            //     text.push(role_name[list[j]]);
+            // }
+            // display += "<option value = \"" + list + "\">" + text + "</option>";
+
+            // var text = [];
+            // text.push(frame.arguments[i].role);
+
+            display += "<option value = \"" + local_complement_id + "\">" + frame.arguments[i].role + "</option>";
+        }
+    }
+
+    display += "</select>"
+
+    return display;
+}
+
+function getSynsets(context, pos) {
+
+    if ((typeof pos) == 'undefined') {
+        pos = '_';
+    }
+
+    $.ajax({
+        dataType: "json",
+        url: 'synsets',
+        data: {base: context, pos: pos},
+        success: function(data){ synsets = data.synsets },
+        async: false
+    });
+
+    var display = "";
+
+    var i;
+    for (i = 0; i < synsets.length; i++) {
+        display += "<input type = \"radio\" name = \"synset\" value = \"" + synsets[i].id + "\"><div>";
+        var j;
+        for (j = 0; j < synsets[i].content.length; j++) {
+            var lexical_unit = synsets[i].content[j];
+            display += lexical_unit.base + "-" + lexical_unit.sense + ": <i>" + lexical_unit.glossa + "</i><br>";
+        }
+        display += "</div>";
+    }
+
+    return display;
+
+}
+
+function relationArgument(frame, complement_id) {
+    return relationsSelect() + "<br><br>" + argumentSelect(frame, complement_id);
+}
+
+function attachPlWNContextAutocomplete() {
+    $('#plWN_context_selection').autocomplete({
+        select: function(event, ui){
+        },
+        source: function(req, add){
+            $.getJSON('plWN_context_lookup', req, function(data) {
+                var suggestions = [];
+                $.each(data['result'], function(i, val){
+                    suggestions.push(val);
+                });
+                add(suggestions);
+            });
+        },
+    });
+}
+
+function addSelectivePreference(frame, complement_id) {
+
+    let unified_frame_id = frame.id;
+
+    var submitSynsetSelection = function(e,v,m,f){
+        if (v == -1) {
+            e.preventDefault();
+            $.prompt.goToState('state2');
+        }
+        if (v == 1) {
+            e.preventDefault();
+            var synset = normalizeFormData(f.synset);
+
+            var i;
+            for (i = 0; i < synset.length; i++) {
+                saveSynsetPreference(unified_frame_id, complement_id, synset[i])
+            }
+            $.prompt.goToState('state0');
+        }
+    }
+
+    var select_preference = {
+        state0: {
+            title: 'Typ preferencji selekcyjnej',
+            html: 'Wybierz typ preferencji selekcyjnej',
+            buttons: { Predefiniowana: 1, Słowosieć: 2, Relacja: 3, Koniec: -1 },
+            focus: -1,
+            submit: function(e,v,m,f){
+                if (v == -1) {
+                    e.preventDefault();
+
+                    get_entry(curr_entry, false);
+
+                    $.prompt.close();
+                }
+                if (v == 1) {
+                    e.preventDefault();
+                    $.prompt.goToState('state1');
+
+                }
+                if (v == 2) {
+                    e.preventDefault();
+                    $.prompt.goToState('state2');
+
+                }
+                if (v == 3) {
+                    e.preventDefault();
+                    $.prompt.goToState('state3');
+
+                }
+            }
+        },
+        state1: {
+            title: 'Wybierz preferencjÄ™ selekcyjnÄ…',
+            html: predefinedSelect(),
+            buttons: { Anuluj: -1, Zatwierdź: 1 },
+            focus: 1,
+            submit: function(e,v,m,f){
+
+                if (v == -1) {
+                    e.preventDefault();
+                    $.prompt.goToState('state0');
+                }
+                if (v == 1) {
+                    e.preventDefault();
+                    var predef = normalizeFormData(f.predef);
+
+                    var i;
+                    for (i = 0; i < predef.length; i++) {
+                        savePredefinedPreference(unified_frame_id, complement_id, predef[i])
+                        // addPreference(unified_frame_id, complement_id, { type: 'g', content: predef[i], text: predefined[indexOfId(predefined, predef[i])].content });
+                    }
+                    $.prompt.goToState('state0');
+                }
+            }
+        },
+        state2: {
+            title: 'Wybierz preferencjÄ™ selekcyjnÄ…',
+            html: "<input id=\"plWN_context_selection\" type=\"text\" name=\"context\">",
+            buttons: { Anuluj: -1, Wyszukaj: 1 },
+            focus: 1,
+            submit: function(e,v,m,f){
+                if (v == -1) {
+                    e.preventDefault();
+                    $.prompt.goToState('state0');
+                }
+                if (v == 1) {
+                    e.preventDefault();
+                    $.prompt.removeState('state21');
+                    $.prompt.addState('state21', {title: 'Znaczenia', html: getSynsets(f.context), buttons: {Anuluj: -1, Zatwierdź: 1}, focus: 1, submit: submitSynsetSelection}, 'state2');
+                    $.prompt.goToState('state21');
+                }
+            }
+        },
+        state3: {
+            title: 'Wybierz relacjÄ™ i argument',
+            html: relationArgument(frame, complement_id),
+            buttons: { Anuluj: -1, Zatwierdź: 1 },
+            focus: 1,
+            submit: function(e,v,m,f){
+                if (v == -1) {
+                    e.preventDefault();
+                    $.prompt.goToState('state0');
+                }
+                if (v == 1) {
+                    e.preventDefault();
+
+                    var rel = normalizeFormData(f.rel);
+                    var args = normalizeFormData(f.arg);
+
+                    var i, j;
+                    for (i = 0; i < rel.length; i++) {
+                        for (j = 0; j < args.length; j++) {
+                            saveRelationalSelectionalPreference(unified_frame_id, complement_id, args[j], rel[i])
+                            // addPreference(unified_frame_id, complement_id, {type: 'r', content: { relation: rel[i], to: args[j] }, text: relations[indexOfId(relations, rel[i])].content + "<br>-> [" + text + "]" });
+                        }
+                    }
+
+                    $.prompt.goToState('state0');
+                }
+            }
+        },
+    };
+    if (change == true) {
+        alertSemantics();
+    } else {
+        $.prompt(select_preference);
+        attachPlWNContextAutocomplete();
+    }
+
+}
+
+
+
+
+function saveSynsetPreference(frame_id, complement_id, synset_preference_id) {
+    var data = { 'frame_id' : frame_id, 'complement_id' : complement_id, 'synset_preference_id' : synset_preference_id };
+    $.ajax({
+        type     : 'post',
+        url      : '/' + lang + '/unifier/save_synset_preference/',
+        dataType : 'json',
+        data     : data,
+        timeout  : 60000,
+        success  : function(response) {
+            show_info('Preferencja zosała zapisana');
+        },
+        error: function(request, errorType, errorMessage) {
+            show_error(errorType + ' (' + errorMessage + ')');
+        }
+    });
+}
+
+function savePredefinedPreference(frame_id, complement_id, predefined_preference_id) {
+    var data = { 'frame_id' : frame_id, 'complement_id' : complement_id, 'predefined_preference_id' : predefined_preference_id };
+    $.ajax({
+        type     : 'post',
+        url      : '/' + lang + '/unifier/save_predefined_preference/',
+        dataType : 'json',
+        data     : data,
+        timeout  : 60000,
+        success  : function(response) {
+            show_info('Preferencja zosała zapisana');
+        },
+        error: function(request, errorType, errorMessage) {
+            show_error(errorType + ' (' + errorMessage + ')');
+        }
+    });
+}
+
+function saveRelationalSelectionalPreference(frame_id, complement_id_from, complement_id_to, relation_id) {
+    var data = { 'frame_id' : frame_id, 'complement_id_from' : complement_id_from, 'complement_id_to' : complement_id_to, 'relation_id': relation_id };
+    $.ajax({
+        type     : 'post',
+        url      : '/' + lang + '/unifier/save_relational_selectional_preference/',
+        dataType : 'json',
+        data     : data,
+        timeout  : 60000,
+        success  : function(response) {
+            show_info('Preferencja zosała zapisana');
+        },
+        error: function(request, errorType, errorMessage) {
+            show_error(errorType + ' (' + errorMessage + ')');
+        }
+    });
+}
+
+
diff --git a/entries/static/entries/js/unification_entries_list.js b/entries/static/entries/js/unification_entries_list.js
index e419a5005a0da8376702fe28c376a34dfd80e10f..ee4f091145721f1087482b8642bbcf93e677110b 100644
--- a/entries/static/entries/js/unification_entries_list.js
+++ b/entries/static/entries/js/unification_entries_list.js
@@ -25,6 +25,7 @@ function update_entries() {
             if (!row.data()) return;
             var drilldown = $("<div>").addClass("drilldown").data("row", this);
             row.child(drilldown).show();
+            // tutaj zmiana na liste zunifikowanych ram
             setup_lexical_units_table(drilldown, row.data().lexical_units, can_see_assignees);
             drilldown.closest("td").addClass("p-0 pl-4");
         }
diff --git a/entries/static/entries/js/utils.js b/entries/static/entries/js/utils.js
index 9bc705dcc1a502c615aa7ed6b351232fdddc8733..694904e3a929fa26be0780e87fb24e0f8dd2a6b7 100644
--- a/entries/static/entries/js/utils.js
+++ b/entries/static/entries/js/utils.js
@@ -18,3 +18,25 @@ var permissions = JSON.parse(document.getElementById('user-permissions').textCon
 function has_permission(permission) {
     return permissions.indexOf(permission) !== -1;
 }
+
+function normalizeFormData(data) {
+    if ((typeof data) == 'string') {
+        return [data];
+    } else {
+        if ((typeof data) == 'undefined') {
+            return [];
+        } else {
+            return data;
+        }
+    }
+}
+
+function indexOfId(array, id) {
+    var i;
+    for (i = 0; i < array.length; i++) {
+        if (array[i].id == id) {
+            return i;
+        }
+    }
+    return -1;
+}
diff --git a/entries/templates/entries_base.html b/entries/templates/entries_base.html
index 7b43abc79fc7cf411d31e6b6b93c332483f6a376..c0c20032ebe033d620c24f92cba134ed3097df54 100644
--- a/entries/templates/entries_base.html
+++ b/entries/templates/entries_base.html
@@ -12,6 +12,7 @@
     <!--link rel="stylesheet" type="text/css" href="{% static 'entries/css/panels.css' %}"-->
     <link rel="stylesheet" type="text/css" href="{% static 'entries/css/entries.css' %}">
     <link rel="stylesheet" type="text/css" href="{% static 'common/css/role_colours.css' %}">
+    <link rel="stylesheet" href="{% static 'entries/css/jquery-impromptu.min.css' %}" type="text/css" media="screen" charset="utf-8" />
 {% endblock %}
 
 {% block scripts %}
@@ -23,6 +24,8 @@
     <!--script src="{% static 'entries/js/panels.js' %}"></script-->
     <script src="{% static 'entries/js/forms.js' %}"></script>
     <script src="{% static 'entries/js/utils.js' %}"></script>
+    <script src="{% static 'entries/js/selectional_preference.js' %}"></script>
+    <script src="{% static 'entries/js/jquery-impromptu.min.js' %}"></script>
     <script src="{% static 'entries/js/entries.js' %}"></script>
 {% endblock %}
 
diff --git a/entries/templates/unification_entries_list.html b/entries/templates/unification_entries_list.html
index 48b737359c71740f56d4fc6838528a859613a25a..5c5df3e6c50cb7e9263397098091e6afd5920f2a 100644
--- a/entries/templates/unification_entries_list.html
+++ b/entries/templates/unification_entries_list.html
@@ -1,4 +1,7 @@
 {% load i18n %}
+<!--dupa-->
+<!--chcekcbox-->
+<!--update_entries()-->
 
 <table id="entries-table" class="table table-sm table-hover text-dark">
     <thead>
diff --git a/entries/urls.py b/entries/urls.py
index 37deeedf2ec924cfa3ee768bff8629b90dea18f9..697f591e3a626a6c0e46f52bc8576cbe3a86d787 100644
--- a/entries/urls.py
+++ b/entries/urls.py
@@ -1,6 +1,7 @@
 from django.urls import path
 
 from . import autocompletes, views
+from .views import ajax_plWN_context_lookup, ajax_predefined_preferences, ajax_relations, ajax_synsets
 
 app_name = 'entries'
 
@@ -17,6 +18,10 @@ urlpatterns = [
     path('unification', views.unification, name='unification'),
 
     path('autocomplete/', autocompletes.autocomplete, name='autocomplete'),
+    path('plWN_context_lookup/', ajax_plWN_context_lookup, name='plWN_context_lookup'),
+    path('predefined_preferences/', ajax_predefined_preferences, name='predefined_preferences'),
+    path('relations/', ajax_relations, name='relations'),
+    path('synsets/', ajax_synsets, name='synsets'),
 
     # TODO remove!
     #path('test/', views.test, name='test'),
diff --git a/entries/views.py b/entries/views.py
index 7d026a7f233d6ab62bd88db468e8165e4dcb2439..fda744eb18a6ca4a4c0d40ec2efcfd606f10018f 100644
--- a/entries/views.py
+++ b/entries/views.py
@@ -17,10 +17,11 @@ from django.utils.translation import gettext as _
 from crispy_forms.utils import render_crispy_form
 
 from connections.models import Entry, Subentry, ArgumentConnection, RealisationDescription
+from meanings.models import LexicalUnit
 from syntax.models import NaturalLanguageDescription, Schema
-from semantics.models import Frame
+from semantics.models import Frame, PredefinedSelectionalPreference, SelectivePreferenceRelations
 
-from common.decorators import ajax_required
+from common.decorators import ajax_required, ajax
 
 from .forms import (
     EntryForm,
@@ -842,3 +843,73 @@ def change_show_linked_entries(request):
         return JsonResponse({ 'success' : 1 })
     return JsonResponse({})
 
+@ajax(method='get', encode_result=True)
+def ajax_plWN_context_lookup(request, term):
+    results = []
+    # term = term.encode('utf8')
+    if len(term) > 0:
+        obj_results = LexicalUnit.objects.filter(base__startswith=term)
+        results = get_ordered_lexical_units_bases(obj_results)
+    return {'result': results}
+
+
+def get_ordered_lexical_units_bases(lexical_units_query):
+    last_unit_base = ''
+    lexical_unit_bases = []
+    ordered_lexical_units = lexical_units_query.order_by('base')
+    for lexical_unit in ordered_lexical_units:
+        if lexical_unit.base != last_unit_base:
+            lexical_unit_bases.append(lexical_unit.base)
+        last_unit_base = lexical_unit.base
+    return lexical_unit_bases
+
+
+@ajax(method='get', encode_result=True)
+def ajax_predefined_preferences(request):
+    predefined = []
+    for preference in PredefinedSelectionalPreference.objects.order_by('name'):
+        if preference.members:
+            members = [member.name for member in preference.members.generals.order_by('name')]
+            members.extend([str(synset) for synset in preference.members.synsets.all()])
+            content = '%s: (%s)' % (preference.name, ', '.join(members))
+        else:
+            content = '%s' % (preference.name)
+        predefined.append({"id": preference.id, "content": content})
+
+    context = {
+        'predefined': predefined,
+    }
+
+    return context
+
+# @render('relations.json')
+@ajax(method='get', encode_result=True)
+def ajax_relations(request):
+
+    relations = [{"id": relation.plwn_id, "content": relation.name} for relation in SelectivePreferenceRelations.objects.all()]
+
+    context = {
+        'relations': relations,
+    }
+
+    return context
+
+@ajax(method='get', encode_result=True)
+def ajax_synsets(request, base, pos):
+
+    if pos == '_':
+        lexical_units = LexicalUnit.objects.filter(base=base).order_by('pos', 'base', 'sense')
+    else:
+        lexical_units = LexicalUnit.objects.filter(base=base, pos=pos).order_by('pos', 'base', 'sense')
+
+    synsets = []
+    for representative in lexical_units:
+        synset = [{"id": lu.id, "luid": lu.luid, "base": lu.base, "sense": lu.sense, "pos": lu.pos, "glossa": lu.definition} for lu in LexicalUnit.objects.filter(synset=representative.synset)]
+        synsets.append({"id": representative.synset.id, "content": synset})
+
+    context = {
+        'synsets': synsets,
+    }
+
+    return context
+
diff --git a/importer/Argument.py b/importer/Argument.py
index f6ef194f740e777af082f356489fc1f4e996c0f3..956d3043e48b785ec711eebb999a472f3580e881 100644
--- a/importer/Argument.py
+++ b/importer/Argument.py
@@ -73,7 +73,7 @@ class SelectionalPreference:
 
     def store(self, frame, argument):
         if self._type == 'predef':
-            pref = PredefinedSelectionalPreference.objects.get(key=self._value)
+            pref = PredefinedSelectionalPreference.objects.get(name=self._value)
             argument.predefined.add(pref)
         elif self._type == 'synset':
             pref = Synset.objects.get(id=self._value)
diff --git a/importer/RealizationDescriptions.py b/importer/RealizationDescriptions.py
index 3f726b6e8cdf3cc742d11a6fca098a298b268027..8b0811ad770eda0b073e170b1955c095134c08a8 100644
--- a/importer/RealizationDescriptions.py
+++ b/importer/RealizationDescriptions.py
@@ -46,7 +46,7 @@ def get_predefined_lemma(argument, xp=False):
     predefined = argument.predefined.all()
     if not predefined:
         return None
-    predefs = sorted(p.key for p in predefined)
+    predefs = sorted(p.name for p in predefined)
     role = argument.role.role.role
     if role not in LOCATION_ROLES and {'LUDZIE', 'PODMIOTY'}.intersection(predefs):
         return ['LUDZIE']
diff --git a/semantics/models.py b/semantics/models.py
index 31e224ddd4e55f964f9aa0306151fcc6106ab505..c746064473c4caa2e02cf1e88001e77c27209a93 100644
--- a/semantics/models.py
+++ b/semantics/models.py
@@ -96,12 +96,12 @@ class RoleType(models.Model):
 
 
 class PredefinedSelectionalPreference(models.Model):
-    key = models.CharField(max_length=20, unique=True)
+    name = models.CharField(max_length=20, unique=True)
+    members = models.ForeignKey('SelectivePreference', null=True, on_delete=models.PROTECT)
     # name = TODO: wymaga lokalizacji
 
     def __str__(self):
-        return self.key
-
+        return self.name
 
 class RelationalSelectionalPreference(models.Model):
     relation = models.ForeignKey('SelectionalPreferenceRelation', on_delete=models.PROTECT)
@@ -110,6 +110,24 @@ class RelationalSelectionalPreference(models.Model):
     def __str__(self):
         return '%s -> %s' % (self.relation, self.to)
 
+class SelectivePreferenceRelations(models.Model):
+    plwn_id = models.IntegerField(null=True)
+    name = models.CharField(max_length=80)
+    sym_name = models.CharField(max_length=40)
+
+    def __unicode__(self):
+        return u'%s' % (self.name)
+
+class SynsetRelationalSelectivePreference(models.Model):
+    relation = models.ForeignKey(SelectivePreferenceRelations, on_delete=models.PROTECT)
+    to = models.ForeignKey(Synset, on_delete=models.PROTECT)
+
+class SelectivePreference(models.Model):
+    generals = models.ManyToManyField(PredefinedSelectionalPreference)
+    synsets = models.ManyToManyField(Synset)
+    relations = models.ManyToManyField(RelationalSelectionalPreference)
+    synset_relations = models.ManyToManyField(SynsetRelationalSelectivePreference)
+
 
 class SelectionalPreferenceRelation(models.Model):
     key = models.CharField(max_length=40, unique=True)
diff --git a/shellvalier/urls.py b/shellvalier/urls.py
index 1fa7a875c60dc8c90fddf7b461547362e17ce90b..985cf8e775a3c636ae593934bf3d41250d12ee69 100644
--- a/shellvalier/urls.py
+++ b/shellvalier/urls.py
@@ -16,6 +16,7 @@ urlpatterns = i18n_patterns(
     path('users/', include('users.urls')),
     path('jsi18n/', JavaScriptCatalog.as_view(), name='javascript-catalog'),
     path('admin/', admin.site.urls, name='admin'),
+    path('unifier/', include('unifier.urls')),
     path('', dash, name='dash'),
     # uncomment to leave default (Polish) urls unchanged
     #prefix_default_language=False,
diff --git a/syntax/management/commands/add_predefined_preferences.py b/syntax/management/commands/add_predefined_preferences.py
new file mode 100644
index 0000000000000000000000000000000000000000..d9b06b43026802e7c0c2490a9c72fbfa638247a1
--- /dev/null
+++ b/syntax/management/commands/add_predefined_preferences.py
@@ -0,0 +1,253 @@
+#-*- coding:utf-8 -*-
+
+from django.core.management.base import BaseCommand
+
+from meanings.models import LexicalUnit
+from semantics.models import SelectivePreference, PredefinedSelectionalPreference
+
+class Command(BaseCommand):
+    args = 'none'
+    help = ''
+
+    def handle(self, **options):
+        #clear_predefined_preferences()
+        create_predefined_preferences()
+        
+def clear_predefined_preferences():
+    PredefinedSelectionalPreference.objects.all().delete()
+    SelectivePreference.objects.all().delete()
+
+def create_predefined_preferences():
+    # ALL
+    all, xx = PredefinedSelectionalPreference.objects.get_or_create(name='ALL')
+    
+    
+    # POŁOŻENIE: miejsce-1, przestrzeń-1, obiekt-2
+    # OTOCZENIE: człowiek-1, powierzchnia-2, rzecz-4, wytwór-2, pomieszczenie-3
+    
+    # LUDZIE: osoba-1, grupa ludzi-1
+    ludzie_members = SelectivePreference()
+    ludzie_members.save()
+    osoba_1 = LexicalUnit.objects.get(base='osoba', 
+                                      sense='1',
+                                      pos='noun').synset
+    grupa_ludzi_1 = LexicalUnit.objects.get(base='grupa ludzi', 
+                                            sense='1',
+                                            pos='noun').synset
+    ludzie_members.synsets.add(osoba_1)
+    ludzie_members.synsets.add(grupa_ludzi_1)
+    ludzie, xx = PredefinedSelectionalPreference.objects.get_or_create(name='LUDZIE',
+                                                                  members=ludzie_members)
+    
+    # ISTOTY: osoba-1, istota żywa-1, grupa istot-1
+    istoty_members = SelectivePreference()
+    istoty_members.save()
+    istoty_members.synsets.add(osoba_1)
+    istota_zywa_1 = LexicalUnit.objects.get(base='istota żywa', 
+                                            sense='1',
+                                            pos='noun').synset
+    istoty_members.synsets.add(istota_zywa_1)
+    grupa_istot_1 = LexicalUnit.objects.get(base='grupa istot', 
+                                            sense='1',
+                                            pos='noun').synset
+    istoty_members.synsets.add(grupa_istot_1)
+    istoty, xx = PredefinedSelectionalPreference.objects.get_or_create(name='ISTOTY',
+                                                                  members=istoty_members)
+    
+    # PODMIOTY: LUDZIE, podmiot-3
+    podmioty_members = SelectivePreference()
+    podmioty_members.save()
+    podmioty_members.generals.add(ludzie)
+    podmiot_3 = LexicalUnit.objects.get(base='podmiot', 
+                                        sense='3',
+                                        pos='noun').synset
+    podmioty_members.synsets.add(podmiot_3)
+    podmioty, xx = PredefinedSelectionalPreference.objects.get_or_create(name='PODMIOTY',
+                                                                    members=podmioty_members)
+    
+    # DOBRA: jedzenie-2, mienie-1, przedmiot-1, wytwór-1 ==> JADŁO, mienie-1, przedmiot-1, wytwór-1
+    dobra_members = SelectivePreference()
+    dobra_members.save()
+    jedzenie_2 = LexicalUnit.objects.get(base='jedzenie', 
+                                        sense='2',
+                                        pos='noun').synset
+    dobra_members.synsets.add(jedzenie_2)
+    mienie_1 = LexicalUnit.objects.get(base='mienie', 
+                                       sense='1',
+                                       pos='noun').synset
+    dobra_members.synsets.add(mienie_1)
+    przedmiot_1 = LexicalUnit.objects.get(base='przedmiot', 
+                                          sense='1',
+                                          pos='noun').synset
+    dobra_members.synsets.add(przedmiot_1)
+    wytwor_1 = LexicalUnit.objects.get(base='wytwór', 
+                                       sense='1',
+                                       pos='noun').synset
+    dobra_members.synsets.add(wytwor_1)
+    dobra, xx = PredefinedSelectionalPreference.objects.get_or_create(name='DOBRA',
+                                                                 members=dobra_members)
+    
+    # KOMUNIKAT: informacja-1, wypowiedź-1
+    komunikat_members = SelectivePreference()
+    komunikat_members.save()
+    informacja_1 = LexicalUnit.objects.get(base='informacja', 
+                                           sense='1',
+                                           pos='noun').synset
+    komunikat_members.synsets.add(informacja_1)
+    wypowiedz_1 = LexicalUnit.objects.get(base='wypowiedź', 
+                                          sense='1',
+                                          pos='noun').synset
+    komunikat_members.synsets.add(wypowiedz_1)
+    komunikat, xx = PredefinedSelectionalPreference.objects.get_or_create(name='KOMUNIKAT',
+                                                                     members=komunikat_members)
+    
+    # KONCEPCJA: informacja-1, wytwór umysłu-1
+    koncepcja_members = SelectivePreference()
+    koncepcja_members.save()
+    koncepcja_members.synsets.add(informacja_1)
+    wytwor_umyslu_1 = LexicalUnit.objects.get(base='wytwór umysłu',
+                                              sense='1',
+                                              pos='noun').synset
+    koncepcja_members.synsets.add(wytwor_umyslu_1)
+    koncepcja, xx = PredefinedSelectionalPreference.objects.get_or_create(name='KONCEPCJA',
+                                                                     members=koncepcja_members)
+    
+    # WYTWÓR: przedmiot-1, wytwór-1
+    wytwor_members = SelectivePreference()
+    wytwor_members.save()
+    wytwor_members.synsets.add(przedmiot_1)
+    wytwor_members.synsets.add(wytwor_1)
+    wytwor, xx = PredefinedSelectionalPreference.objects.get_or_create(name='WYTWÓR',
+                                                                  members=wytwor_members)
+    
+    # JADŁO: pokarm-1, napój-1
+    jadlo_members = SelectivePreference()
+    jadlo_members.save()
+    pokarm_1 = LexicalUnit.objects.get(base='pokarm', 
+                                       sense='1',
+                                       pos='noun').synset
+    jadlo_members.synsets.add(pokarm_1)
+    napoj_1 = LexicalUnit.objects.get(base='napój', 
+                                      sense='1',
+                                      pos='noun').synset
+    jadlo_members.synsets.add(napoj_1)
+    jadlo, xx = PredefinedSelectionalPreference.objects.get_or_create(name='JADŁO',
+                                                                 members=jadlo_members)
+    
+    # MIEJSCE: miejsce-1, przestrzeń-1, obiekt-2 ==> lokal-1, budynek-1, rejon-1, obszar-1, państwo-1, jednostka administracyjna-1, woda-4
+    miejsce_members = SelectivePreference()
+    miejsce_members.save()
+    miejsce_1 = LexicalUnit.objects.get(base='miejsce', 
+                                        sense='1',
+                                        pos='noun').synset
+    miejsce_members.synsets.add(miejsce_1)
+    przestrzen_1 = LexicalUnit.objects.get(base='przestrzeń', 
+                                        sense='1',
+                                        pos='noun').synset
+    miejsce_members.synsets.add(przestrzen_1)
+    obiekt_2 = LexicalUnit.objects.get(base='obiekt', 
+                                        sense='2',
+                                        pos='noun').synset
+    miejsce_members.synsets.add(obiekt_2)
+    miejsce, xx = PredefinedSelectionalPreference.objects.get_or_create(name='MIEJSCE',
+                                                                   members=miejsce_members)
+    
+    # CZAS: chwila-1, czas-3, czas-8, godzina-3
+    czas_members = SelectivePreference()
+    czas_members.save()
+    chwila_1 = LexicalUnit.objects.get(base='chwila', 
+                                       sense='1',
+                                       pos='noun').synset
+    czas_members.synsets.add(chwila_1)
+    czas_3 = LexicalUnit.objects.get(base='czas', 
+                                     sense='3',
+                                     pos='noun').synset
+    czas_members.synsets.add(czas_3)
+    czas_8 = LexicalUnit.objects.get(base='czas', 
+                                     sense='8',
+                                     pos='noun').synset
+    czas_members.synsets.add(czas_8)
+    godzina_3 = LexicalUnit.objects.get(base='godzina', 
+                                        sense='3',
+                                        pos='noun').synset
+    czas_members.synsets.add(godzina_3)
+    czas, xx = PredefinedSelectionalPreference.objects.get_or_create(name='CZAS',
+                                                                members=czas_members)
+    
+    # OBIEKTY: osoba-1, obiekt-2, zbiór-1
+    obiekty_members = SelectivePreference()
+    obiekty_members.save()
+    obiekty_members.synsets.add(osoba_1)
+    obiekty_members.synsets.add(obiekt_2)
+    zbior_1 = LexicalUnit.objects.get(base='zbiór', 
+                                      sense='1',
+                                      pos='noun').synset
+    obiekty_members.synsets.add(zbior_1)
+    obiekty, xx = PredefinedSelectionalPreference.objects.get_or_create(name='OBIEKTY',
+                                                                   members=obiekty_members)
+    
+    # CECHA: cecha-1
+    cecha_members = SelectivePreference()
+    cecha_members.save()
+    cecha_1 = LexicalUnit.objects.get(base='cecha', 
+                                      sense='1',
+                                      pos='noun').synset
+    cecha_members.synsets.add(cecha_1)
+    cecha, xx = PredefinedSelectionalPreference.objects.get_or_create(name='CECHA',
+                                                                 members=cecha_members)
+    
+    # CZYNNOŚĆ: czynność-1
+    czynnosc_members = SelectivePreference()
+    czynnosc_members.save()
+    czynnosc_1 = LexicalUnit.objects.get(base='czynność', 
+                                         sense='1',
+                                         pos='noun').synset
+    czynnosc_members.synsets.add(czynnosc_1)
+    czynnosc, xx = PredefinedSelectionalPreference.objects.get_or_create(name='CZYNNOŚĆ',
+                                                                    members=czynnosc_members)
+    
+    # SYTUACJA ==> czynność-1, zdarzenie-2, okoliczność-1, ciąg zdarzeń-1
+    sytuacja, xx = PredefinedSelectionalPreference.objects.get_or_create(name='SYTUACJA')
+    
+    # KIEDY: CZAS, SYTUACJA
+    kiedy_members = SelectivePreference()
+    kiedy_members.save()
+    kiedy_members.generals.add(czas)
+    kiedy_members.generals.add(sytuacja)
+    kiedy, xx = PredefinedSelectionalPreference.objects.get_or_create(name='KIEDY',
+                                                                 members=kiedy_members)
+    
+    # CZEMU: CECHA, SYTUACJA, LUDZIE
+    czemu_members = SelectivePreference()
+    czemu_members.save()
+    czemu_members.generals.add(cecha)
+    czemu_members.generals.add(sytuacja)
+    czemu_members.generals.add(ludzie)
+    czemu, xx = PredefinedSelectionalPreference.objects.get_or_create(name='CZEM',
+                                                                 members=czemu_members)
+    
+    # ILOŚĆ: ilość-1, rozmiar-1, rozmiar-2, jednostka-4, wielkość-6
+    ilosc_members = SelectivePreference()
+    ilosc_members.save()
+    ilosc_1 = LexicalUnit.objects.get(base='ilość', 
+                                      sense='1',
+                                      pos='noun').synset
+    ilosc_members.synsets.add(ilosc_1)
+    rozmiar_1 = LexicalUnit.objects.get(base='rozmiar', 
+                                        sense='1',
+                                        pos='noun').synset
+    ilosc_members.synsets.add(rozmiar_1)
+    rozmiar_2 = LexicalUnit.objects.get(base='rozmiar', 
+                                        sense='2',
+                                        pos='noun').synset
+    ilosc_members.synsets.add(rozmiar_2)
+    jednostka_4 = LexicalUnit.objects.get(base='jednostka', 
+                                          sense='4',
+                                          pos='noun').synset
+    ilosc_members.synsets.add(jednostka_4)
+    wielkosc_6 = LexicalUnit.objects.get(base='wielkość', 
+                                         sense='6',
+                                         pos='noun').synset
+    ilosc_members.synsets.add(wielkosc_6)
+    ilosc, xx = PredefinedSelectionalPreference.objects.get_or_create(name='ILOŚĆ',
+                                                                 members=ilosc_members)
diff --git a/syntax/management/commands/import_relations.py b/syntax/management/commands/import_relations.py
new file mode 100644
index 0000000000000000000000000000000000000000..0513e74141760e660b637d6d3c8b99595d42210c
--- /dev/null
+++ b/syntax/management/commands/import_relations.py
@@ -0,0 +1,25 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+
+from django.core.management.base import BaseCommand
+
+from semantics.models import SelectivePreferenceRelations
+
+RELATIONS = [(-1, 'RELAT'), (14, 'meronimia'), (15, 'holonimia'), (20, 'meronimia (typu część)'), (21, 'meronimia (typu porcja)'), (22, 'meronimia (typu miejsce)'), (23, 'meronimia (typu element)'), (24, 'meronimia (typu materiał)'), (25, 'holonimia (typu część)'), (26, 'holonimia (typu porcja)'), (27, 'holonimia (typu miejsce)'), (28, 'holonimia (typu element)'), (29, 'holonimia (typu materiał)'), (51, 'nosiciel stanu/cechy'), (52, 'stan/cecha'), (61, 'synonimia międzyparadygmatyczna'), (64, 'meronimia (typu element taksonomiczny)'), (65, 'holonimia (typu element taksonomiczny)'), (108, 'fuzzynimia synsetów')]
+
+#==========================================================#
+class Command(BaseCommand):
+    args = 'none'
+    help = ''
+
+    def handle(self, **options):
+        import_relations()
+        
+def import_relations():
+    relations = []
+    for pid, name in RELATIONS:
+        r = SelectivePreferenceRelations(plwn_id=pid, name=name)
+        relations.append(r)
+        
+    SelectivePreferenceRelations.objects.bulk_create(relations)
+
diff --git a/syntax/management/commands/import_tei.py b/syntax/management/commands/import_tei.py
index 592d595065c5e58c25c02bbb3d488c7b96fbb022..2962e08f0a48a0662320ae806ec81a95e0f7db15 100644
--- a/syntax/management/commands/import_tei.py
+++ b/syntax/management/commands/import_tei.py
@@ -10,6 +10,8 @@ from importer.WalentyPreprocessXML import WalentyPreprocessTeiHandler
 from shellvalier.settings import BASE_DIR
 from connections.models import POS, Status
 from examples.models import ExampleOpinion, ExampleSource
+from syntax.management.commands.add_predefined_preferences import create_predefined_preferences
+from syntax.management.commands.import_relations import import_relations
 from syntax.models import SchemaOpinion, Aspect, InherentSie, Negativity, Predicativity, SyntacticFunction, Control, PredicativeControl, Position
 from syntax.models_phrase import (
     Case, PhraseAspect, AdverbialCategory, PhraseNegativity, PhraseInherentSie,
@@ -65,7 +67,7 @@ def import_constants():
     import_syntactic_functions()
     import_control_tags()
     import_semantic_roles()
-    import_predefined_preferences()
+    # import_predefined_preferences()
     import_preference_relations()
     import_examples_sources()
     import_examples_opinions()
@@ -74,6 +76,9 @@ def import_constants():
     import_modification_types()
     import_semantic_role_types()
 
+    create_predefined_preferences()
+    import_relations()
+
 def import_poses():
     poses = [u'unk', u'adj', u'noun', u'adv', u'verb']
     for pos_tag in poses:
@@ -184,11 +189,11 @@ def import_semantic_role_types():
         cont = RoleType(type=name)
         cont.save()
 
-def import_predefined_preferences():
-    predefs = [u'ALL', u'LUDZIE', u'ISTOTY', u'PODMIOTY', u'KOMUNIKAT', u'KONCEPCJA', u'WYTWÓR', u'JADŁO', u'CZAS', u'OBIEKTY', u'CECHA', u'CZYNNOŚĆ', u'KIEDY', u'CZEMU', u'ILOŚĆ', u'POŁOŻENIE', u'DOBRA', u'MIEJSCE', u'SYTUACJA', u'OTOCZENIE']
-    for name in predefs:
-        predef = PredefinedSelectionalPreference(key=name)
-        predef.save()
+# def import_predefined_preferences():
+#     predefs = [u'ALL', u'LUDZIE', u'ISTOTY', u'PODMIOTY', u'KOMUNIKAT', u'KONCEPCJA', u'WYTWÓR', u'JADŁO', u'CZAS', u'OBIEKTY', u'CECHA', u'CZYNNOŚĆ', u'KIEDY', u'CZEMU', u'ILOŚĆ', u'POŁOŻENIE', u'DOBRA', u'MIEJSCE', u'SYTUACJA', u'OTOCZENIE']
+#     for name in predefs:
+#         predef = PredefinedSelectionalPreference(key=name)
+#         predef.save()
 
 def import_preference_relations():
     relations = [(14, u'meronimia'), (15, u'holonimia'), (20, u'meronimia (typu część)'), (21, u'meronimia (typu porcja)'), (22, u'meronimia (typu miejsce)'), (23, u'meronimia (typu element)'), (24, u'meronimia (typu materiał)'), (25, u'holonimia (typu część)'), (26, u'holonimia (typu porcja)'), (27, u'holonimia (typu miejsce)'), (28, u'holonimia (typu element)'), (29, u'holonimia (typu materiał)'), (51, u'nosiciel stanu/cechy'), (52, u'stan/cecha'), (61, u'synonimia międzyparadygmatyczna'), (64, u'meronimia (typu element taksonomiczny)'), (65, u'holonimia (typu element taksonomiczny)'), (108, u'fuzzynimia synsetów'), (-1, u'RELAT')]
diff --git a/unifier/models.py b/unifier/models.py
index 09b7dec7b477793d9cc396e31203d73cb687cebe..1cfa92c985c25b513ea3dc96358540a80e5bcabc 100644
--- a/unifier/models.py
+++ b/unifier/models.py
@@ -2,7 +2,7 @@ from django.db import models
 
 from meanings.models import LexicalUnit, Synset
 from semantics.models import choices, PredefinedSelectionalPreference, RelationalSelectionalPreference, ArgumentRole, \
-    RoleType, Argument, Frame
+    RoleType, Argument, Frame, SelectionalPreferenceRelation
 
 
 class UnifiedFrame(models.Model):
@@ -19,7 +19,6 @@ class UnifiedFrame(models.Model):
     def __str__(self):
         return '%s: %s' % (self.opinion, ' + '.join([str(arg) for arg in self.sorted_arguments()]))
 
-
 class UnifiedFrameArgument(models.Model):
     id = models.CharField(max_length=20, primary_key=True)
 
@@ -32,7 +31,7 @@ class UnifiedFrameArgument(models.Model):
     #3 typy preferencji - wybrane przez użytkownika
     predefined = models.ManyToManyField(PredefinedSelectionalPreference)
     synsets = models.ManyToManyField(Synset)
-    relations = models.ManyToManyField(RelationalSelectionalPreference)
+    relations = models.ManyToManyField('UnifiedRelationalSelectionalPreference')
 
     #odwołanie do ramy
     unified_frame = models.ForeignKey(UnifiedFrame, related_name='unified_arguments', default=None, blank=True, null=True, on_delete=models.PROTECT)
@@ -40,6 +39,14 @@ class UnifiedFrameArgument(models.Model):
     def __str__(self):
         return str(self.role)
 
+class UnifiedRelationalSelectionalPreference(models.Model):
+    relation = models.ForeignKey(SelectionalPreferenceRelation, on_delete=models.PROTECT)
+    to = models.ForeignKey(UnifiedFrameArgument, on_delete=models.PROTECT)
+
+    def __str__(self):
+        return '%s -> %s' % (self.relation, self.to)
+
+
 class UnifiedFrame2SlowalFrameMapping(models.Model):
     unified_frame = models.ForeignKey(UnifiedFrame, related_name='unified_frame', on_delete=models.PROTECT)
     slowal_frame = models.ForeignKey(Frame, related_name='slowal_frame', on_delete=models.PROTECT)
diff --git a/unifier/urls.py b/unifier/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..2ababb7beba6b602ca645f69b3e6adf0e7622128
--- /dev/null
+++ b/unifier/urls.py
@@ -0,0 +1,11 @@
+from django.urls import path
+
+from . import views
+
+app_name = 'unifier'
+
+urlpatterns = [
+    path('save_synset_preference/', views.save_synset_preference, name='save_synset_preference'),
+    path('save_predefined_preference/', views.save_predefined_preference, name='save_predefined_preference'),
+    path('save_relational_selectional_preference/', views.save_relational_selectional_preference, name='save_relational_selectional_preference'),
+]
diff --git a/unifier/views.py b/unifier/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..d9925822a2a4cd949036e0d3d7c3f203a82fdcc4
--- /dev/null
+++ b/unifier/views.py
@@ -0,0 +1,46 @@
+from django.http import JsonResponse
+
+from common.decorators import ajax_required
+from semantics.models import RelationalSelectionalPreference
+from unifier.models import UnifiedFrameArgument, UnifiedRelationalSelectionalPreference
+
+
+@ajax_required
+def save_synset_preference(request):
+    if request.method == 'POST':
+        frame_id = request.POST['frame_id']
+        complement_id = request.POST['complement_id']
+        synset_preference_id = request.POST['synset_preference_id']
+
+        unifiedFrameArgument = UnifiedFrameArgument.objects.get(unified_frame_id=int(frame_id), id=int(complement_id))
+        unifiedFrameArgument.synsets.add(int(synset_preference_id))
+        unifiedFrameArgument.save()
+    return JsonResponse({})
+
+@ajax_required
+def save_predefined_preference(request):
+    if request.method == 'POST':
+        frame_id = request.POST['frame_id']
+        complement_id = request.POST['complement_id']
+        predefined_preference_id = request.POST['predefined_preference_id']
+
+        unifiedFrameArgument = UnifiedFrameArgument.objects.get(unified_frame_id=int(frame_id), id=int(complement_id))
+        unifiedFrameArgument.predefined.add(int(predefined_preference_id))
+        unifiedFrameArgument.save()
+    return JsonResponse({})
+
+@ajax_required
+def save_relational_selectional_preference(request):
+    if request.method == 'POST':
+        frame_id = request.POST['frame_id']
+        complement_id_from = request.POST['complement_id_from']
+        complement_id_to = request.POST['complement_id_to']
+        relation_id = request.POST['relation_id']
+
+        unifiedFrameArgument = UnifiedFrameArgument.objects.get(unified_frame_id=int(frame_id), id=int(complement_id_from))
+        relationalSelectionalPreference = UnifiedRelationalSelectionalPreference(to_id=complement_id_to, relation_id=relation_id)
+        relationalSelectionalPreference.save()
+        unifiedFrameArgument.relations.add(relationalSelectionalPreference)
+        unifiedFrameArgument.save()
+    return JsonResponse({})
+