diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..58630c02ef423cffd6dd6aafd946eb8512040c37
--- /dev/null
+++ b/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/SofiaKPWrapper.iml b/SofiaKPWrapper.iml
new file mode 100644
index 0000000000000000000000000000000000000000..c2bb79ce638cb1a18241f0b78aece402238fc4fb
--- /dev/null
+++ b/SofiaKPWrapper.iml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="sofia_kp" level="project" />
+    <orderEntry type="library" name="jdom-2.0.5" level="project" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/libs/jdom-2.0.5.jar b/libs/jdom-2.0.5.jar
new file mode 100644
index 0000000000000000000000000000000000000000..b6996c725a290b4e29a202d2b6bda39f9d7ffbfe
Binary files /dev/null and b/libs/jdom-2.0.5.jar differ
diff --git a/libs/sofia_kp.jar b/libs/sofia_kp.jar
new file mode 100644
index 0000000000000000000000000000000000000000..951a0dd73df71e5f534908cb2b03c8bb03b524c5
Binary files /dev/null and b/libs/sofia_kp.jar differ
diff --git a/src/wrapper/SmartSpaceException.java b/src/wrapper/SmartSpaceException.java
new file mode 100644
index 0000000000000000000000000000000000000000..911c3ae56b94113bd6fa671ae8cd26c4968b2e01
--- /dev/null
+++ b/src/wrapper/SmartSpaceException.java
@@ -0,0 +1,23 @@
+package wrapper;
+
+public class SmartSpaceException extends Exception {
+    public SmartSpaceException(String message) {
+        super(message);
+    }
+
+    public SmartSpaceException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public SmartSpaceException(Throwable cause) {
+        super(cause);
+    }
+
+    protected SmartSpaceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+
+    public SmartSpaceException() {
+
+    }
+}
\ No newline at end of file
diff --git a/src/wrapper/SmartSpaceKPI.java b/src/wrapper/SmartSpaceKPI.java
new file mode 100644
index 0000000000000000000000000000000000000000..151f08d8cd0b0dd4b87019fd1fc4fd5cfbec0dcc
--- /dev/null
+++ b/src/wrapper/SmartSpaceKPI.java
@@ -0,0 +1,130 @@
+package wrapper;
+
+import sofia_kp.SIBResponse;
+import sofia_kp.iKPIC_subscribeHandler2;
+import sofia_kp.KPICore;
+
+import java.util.ArrayList;
+import java.util.Vector;
+
+public class SmartSpaceKPI {
+
+    private KPICore core;
+    private ArrayList<String> subscriptionIdList;
+
+    public SmartSpaceKPI(String host, int port, String spaceName) throws SmartSpaceException {
+        core = new KPICore(host, port, spaceName);
+        subscriptionIdList = new ArrayList<String>();
+
+        SIBResponse joinResponse = core.join();
+
+        if (!joinResponse.isConfirmed())
+            throw new SmartSpaceException(joinResponse.Message);
+
+        core.disable_debug_message();
+    }
+
+    public void insert(SmartSpaceTriplet triplet) throws SmartSpaceException {
+        SIBResponse insertResponse = core.insert(triplet.getSubject(), triplet.getPredicate(), triplet.getObject(), triplet.getSubjectType(), triplet.getObjectType());
+        if (!insertResponse.isConfirmed()) {
+            String text = String.format("KPI failed to insert triplet: (%s, %s, %s, %s, %s)",
+                                        triplet.getSubject(), triplet.getPredicate(), triplet.getObject(),
+                                        triplet.getSubjectType(), triplet.getObjectType());
+
+            throw new SmartSpaceException(text + '\n' + insertResponse.Message);
+        }
+    }
+
+    public void remove(SmartSpaceTriplet triplet) throws SmartSpaceException {
+        SIBResponse removeResponse = core.remove(triplet.getSubject(), triplet.getPredicate(), triplet.getObject(), triplet.getSubjectType(), triplet.getObjectType());
+        if (!removeResponse.isConfirmed()) {
+            String text = String.format("KP failed to remove triplet: (%s, %s, %s, %s, %s)",
+                                        triplet.getSubject(), triplet.getPredicate(), triplet.getObject(),
+                                        triplet.getSubjectType(), triplet.getObjectType());
+
+            throw new SmartSpaceException(text + '\n' + removeResponse.Message);
+        }
+    }
+
+    public Vector<SmartSpaceTriplet> query(SmartSpaceTriplet triplet) throws SmartSpaceException {
+        SIBResponse queryResponse = core.queryRDF(triplet.getSubject(), triplet.getPredicate(), triplet.getObject(), triplet.getSubjectType(), triplet.getObjectType());
+
+        if (queryResponse.isConfirmed()) {
+            Vector<Vector<String>> stringVectorResult = queryResponse.query_results;
+
+            Vector<SmartSpaceTriplet> result = new Vector<SmartSpaceTriplet>();
+
+            for (Vector<String> it : stringVectorResult) {
+                result.add(new SmartSpaceTriplet(it));
+            }
+
+            return result;
+        } else {
+            throw new SmartSpaceException(queryResponse.Message);
+        }
+    }
+
+    public void update(SmartSpaceTriplet newTriplet, SmartSpaceTriplet oldTriplet) throws SmartSpaceException {
+        SIBResponse updateResponse = core.update(
+                newTriplet.getSubject(), newTriplet.getPredicate(), newTriplet.getObject(), newTriplet.getSubjectType(), newTriplet.getObjectType(),
+                oldTriplet.getSubject(), oldTriplet.getPredicate(), oldTriplet.getObject(), oldTriplet.getSubjectType(), oldTriplet.getObjectType()
+        );
+
+        if (!updateResponse.isConfirmed()) {
+            String text = String.format("KP failed to update triplet! Old triplet: (%s, %s, %s, %s, %s), new triplet (%s, %s, %s, %s, %s)",
+                    newTriplet.getSubject(), newTriplet.getPredicate(), newTriplet.getObject(), newTriplet.getSubjectType(), newTriplet.getObjectType(),
+                    oldTriplet.getSubject(), oldTriplet.getPredicate(), oldTriplet.getObject(), oldTriplet.getSubjectType(), oldTriplet.getObjectType());
+
+            throw new SmartSpaceException(text + '\n' + updateResponse.Message);
+        }
+    }
+
+    public void subscribe(SmartSpaceTriplet triplet, iKPIC_subscribeHandler2 handler) throws SmartSpaceException {
+        SIBResponse subscribeResponse = core.subscribeRDF(triplet.getSubject(), triplet.getPredicate(), triplet.getObject(), triplet.getObjectType(), handler);
+
+        if (subscribeResponse != null && subscribeResponse.isConfirmed()) {
+            subscriptionIdList.add(subscribeResponse.subscription_id);
+        } else {
+            System.err.println("Some problems with subscribing");
+            throw new SmartSpaceException(subscribeResponse != null ? subscribeResponse.Message : null);
+        }
+    }
+
+    public void leave() throws SmartSpaceException {
+
+        try {
+            unsubscribe();
+        }
+        catch (SmartSpaceException exception)
+        {
+            System.err.println(exception.getMessage());
+        }
+
+        SIBResponse leaveResponse = core.leave();
+
+        if (!leaveResponse.isConfirmed()) {
+            throw new SmartSpaceException(leaveResponse.Message);
+        }
+    }
+
+
+    private void unsubscribe() throws SmartSpaceException {
+        String exceptionMessage = "";
+
+        for (String id : subscriptionIdList) {
+            SIBResponse unsubscribeResponse = core.unsubscribe(id);
+
+            // у нас проблемы с отпиской от интеллектуального пространства
+            if (!unsubscribeResponse.isConfirmed()) {
+                exceptionMessage += id + ": " + unsubscribeResponse.Message + '\n';
+            }
+        }
+
+        subscriptionIdList.clear();
+
+        // проблемы во время отписки были, сигнализируем это
+        if (!exceptionMessage.isEmpty()) {
+            throw new SmartSpaceException(exceptionMessage);
+        }
+    }
+}
diff --git a/src/wrapper/SmartSpaceTriplet.java b/src/wrapper/SmartSpaceTriplet.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f48aecc51e61e58c4e2bf098b6220b60a513ea3
--- /dev/null
+++ b/src/wrapper/SmartSpaceTriplet.java
@@ -0,0 +1,110 @@
+package wrapper;
+
+// Class for triplets
+
+import java.util.Vector;
+
+public class SmartSpaceTriplet {
+    private String subject, predicate, object, subjectType, objectType;
+
+    public SmartSpaceTriplet(String subject, String predicate, String object) {
+        this.subject = subject;
+        this.predicate = predicate;
+        this.object = object;
+        this.subjectType = "uri";
+        this.objectType = "literal";
+    }
+
+    public SmartSpaceTriplet(String subject, String predicate, String object, String subjectType, String objectType) throws SmartSpaceException {
+
+        subjectType.toLowerCase();
+        objectType.toLowerCase();
+
+        if (!subjectType.equals("uri") || !subjectType.equals("literal"))
+            throw new SmartSpaceException("Subject type must have \"uri\" or \"literal\" type - got " + subjectType);
+
+        if (!objectType.equals("uri") || !objectType.equals("literal"))
+            throw new SmartSpaceException("Object type must have \"uri\" or \"literal\" type - got " + objectType);
+
+        this.subject = subject;
+        this.predicate = predicate;
+        this.object = object;
+        this.subjectType = subjectType;
+        this.objectType = objectType;
+    }
+
+    public SmartSpaceTriplet(Vector<String> triplet) {
+        switch (triplet.size()) {
+            case 5: {
+                this.subject = triplet.elementAt(0);
+                this.predicate = triplet.elementAt(1);
+                this.object = triplet.elementAt(2);
+                this.subjectType = triplet.elementAt(3);
+                this.objectType = triplet.elementAt(4);
+            }
+            case 4: {
+                this.subject = triplet.elementAt(0);
+                this.predicate = triplet.elementAt(1);
+                this.object = triplet.elementAt(2);
+                this.subjectType = "uri";
+                this.objectType = triplet.elementAt(3);
+            }
+        }
+    }
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public String getPredicate() {
+        return predicate;
+    }
+
+    public String getObject() {
+        return object;
+    }
+
+    public String getSubjectType() {
+        return subjectType;
+    }
+
+    public String getObjectType() {
+        return objectType;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public void setPredicate(String predicate) {
+        this.predicate = predicate;
+    }
+
+    public void setObject(String object) {
+        this.object = object;
+    }
+
+    public void setSubjectType(String subjectType) throws SmartSpaceException {
+        subjectType.toLowerCase();
+
+        if (!subjectType.equals("uri") || !subjectType.equals("literal"))
+            throw new SmartSpaceException("Subject type must have \"uri\" or \"literal\" type - got " + subjectType);
+
+
+        this.subjectType = subjectType;
+    }
+
+    public void setObjectType(String objectType) throws SmartSpaceException {
+        objectType.toLowerCase();
+
+        if (!objectType.equals("uri") || !objectType.equals("literal"))
+            throw new SmartSpaceException("Object type must have \"uri\" or \"literal\" type - got " + objectType);
+
+        this.objectType = objectType;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("subject: %s, predicate: %s, object: %s, subjectType: %s, objectType: %s", subject, predicate, object, subjectType, objectType);
+    }
+}