diff --git a/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfSessionImpl.java b/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfSessionImpl.java
new file mode 100644
index 0000000..8619abc
--- /dev/null
+++ b/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfSessionImpl.java
@@ -0,0 +1,396 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.netconf.ctl;
+
+import ch.ethz.ssh2.Connection;
+import ch.ethz.ssh2.Session;
+import com.google.common.base.Preconditions;
+import org.onosproject.netconf.NetconfDeviceInfo;
+import org.onosproject.netconf.NetconfSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Implementation of a NETCONF session to talk to a device.
+ */
+public class NetconfSessionImpl implements NetconfSession {
+
+    public static final Logger log = LoggerFactory
+            .getLogger(NetconfSessionImpl.class);
+    private static final int CONNECTION_TIMEOUT = 0;
+
+
+    private Connection netconfConnection;
+    private NetconfDeviceInfo deviceInfo;
+    private Session sshSession;
+    private boolean connectionActive;
+    private BufferedReader bufferReader = null;
+    private PrintWriter out = null;
+    private int messageID = 0;
+
+    private List<String> deviceCapabilities =
+            new ArrayList<>(
+                    Arrays.asList("urn:ietf:params:netconf:base:1.0"));
+
+    private String serverCapabilities;
+    private String endpattern = "]]>]]>";
+
+
+    public NetconfSessionImpl(NetconfDeviceInfo deviceInfo) throws IOException {
+        this.deviceInfo = deviceInfo;
+        connectionActive = false;
+        startConnection();
+    }
+
+
+    private void startConnection() throws IOException {
+        if (!connectionActive) {
+            netconfConnection = new Connection(deviceInfo.ip().toString(), deviceInfo.port());
+            netconfConnection.connect(null, CONNECTION_TIMEOUT, 0);
+            boolean isAuthenticated;
+            try {
+                if (deviceInfo.getKeyFile() != null) {
+                    isAuthenticated = netconfConnection.authenticateWithPublicKey(
+                            deviceInfo.name(), deviceInfo.getKeyFile(),
+                            deviceInfo.password());
+                } else {
+                    log.info("authenticate with username {} and password {}",
+                             deviceInfo.name(), deviceInfo.password());
+                    isAuthenticated = netconfConnection.authenticateWithPassword(
+                            deviceInfo.name(), deviceInfo.password());
+                }
+            } catch (IOException e) {
+                throw new IOException("Authentication connection failed:" +
+                                              e.getMessage());
+            }
+
+            connectionActive = true;
+            Preconditions.checkArgument(isAuthenticated,
+                                        "Authentication password and username failed");
+            startSshSession();
+        }
+    }
+
+    private void startSshSession() throws IOException {
+        try {
+            sshSession = netconfConnection.openSession();
+            sshSession.startSubSystem("netconf");
+            bufferReader = new BufferedReader(new InputStreamReader(
+                    sshSession.getStdout()));
+            out = new PrintWriter(sshSession.getStdin());
+            sendHello();
+        } catch (IOException e) {
+            throw new IOException("Failed to create ch.ethz.ssh2.Session session:" +
+                                          e.getMessage());
+        }
+    }
+
+    private void sendHello() throws IOException {
+        serverCapabilities = doRequest(createHelloString());
+    }
+
+    private String createHelloString() {
+        StringBuilder hellobuffer = new StringBuilder();
+        hellobuffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+        hellobuffer.append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
+        hellobuffer.append("  <capabilities>\n");
+        deviceCapabilities.forEach(
+                cap -> hellobuffer.append("    <capability>" + cap + "</capability>\n"));
+        hellobuffer.append("  </capabilities>\n");
+        hellobuffer.append("</hello>\n");
+        hellobuffer.append(endpattern);
+        return hellobuffer.toString();
+
+    }
+
+    @Override
+    public String doRPC(String request) {
+        String reply = "ERROR";
+        try {
+            reply = doRequest(request);
+            if (checkReply(reply)) {
+                return reply;
+            } else {
+                return "ERROR " + reply;
+            }
+        } catch (IOException e) {
+            log.error("Problem in the reading from the SSH connection " + e);
+        }
+        return reply;
+    }
+
+    private String doRequest(String request) throws IOException {
+        log.info("sshState " + sshSession.getState() + "request" + request);
+        if (sshSession.getState() != 2) {
+            try {
+                startSshSession();
+            } catch (IOException e) {
+                log.info("the connection had to be reopened");
+                startConnection();
+            }
+            sendHello();
+        }
+        log.info("sshState after" + sshSession.getState());
+        out.print(request);
+        out.flush();
+        messageID++;
+        return readOne();
+    }
+
+    @Override
+    public String get(String request) {
+        return doRPC(request);
+    }
+
+    @Override
+    public String getConfig(String targetConfiguration) {
+        return getConfig(targetConfiguration, null);
+    }
+
+    @Override
+    public String getConfig(String targetConfiguration, String configurationSchema) {
+        StringBuilder rpc = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+        rpc.append("<rpc message-id=\"" + messageID + "\"  "
+                           + "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
+        rpc.append("<get-config>\n");
+        rpc.append("<source>\n");
+        rpc.append("<" + targetConfiguration + "/>");
+        rpc.append("</source>");
+        if (configurationSchema != null) {
+            rpc.append("<filter type=\"subtree\">\n");
+            rpc.append(configurationSchema + "\n");
+            rpc.append("</filter>\n");
+        }
+        rpc.append("</get-config>\n");
+        rpc.append("</rpc>\n");
+        rpc.append(endpattern);
+        String reply = null;
+        try {
+            reply = doRequest(rpc.toString());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return checkReply(reply) ? reply : null;
+    }
+
+    @Override
+    public boolean editConfig(String newConfiguration) {
+        newConfiguration = newConfiguration + endpattern;
+        String reply = null;
+        try {
+            reply = doRequest(newConfiguration);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return checkReply(reply);
+    }
+
+    @Override
+    public boolean copyConfig(String targetConfiguration, String newConfiguration) {
+        newConfiguration = newConfiguration.trim();
+        if (!newConfiguration.startsWith("<configuration>")) {
+            newConfiguration = "<configuration>" + newConfiguration
+                    + "</configuration>";
+        }
+        StringBuilder rpc = new StringBuilder("<?xml version=\"1.0\" " +
+                                                      "encoding=\"UTF-8\"?>");
+        rpc.append("<rpc>");
+        rpc.append("<copy-config>");
+        rpc.append("<target>");
+        rpc.append("<" + targetConfiguration + "/>");
+        rpc.append("</target>");
+        rpc.append("<source>");
+        rpc.append("<" + newConfiguration + "/>");
+        rpc.append("</source>");
+        rpc.append("</copy-config>");
+        rpc.append("</rpc>");
+        rpc.append(endpattern);
+        String reply = null;
+        try {
+            reply = doRequest(rpc.toString());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return checkReply(reply);
+    }
+
+    @Override
+    public boolean deleteConfig(String targetConfiguration) {
+        if (targetConfiguration.equals("running")) {
+            log.warn("Target configuration for delete operation can't be \"running\"",
+                     targetConfiguration);
+            return false;
+        }
+        StringBuilder rpc = new StringBuilder("<?xml version=\"1.0\" " +
+                                                      "encoding=\"UTF-8\"?>");
+        rpc.append("<rpc>");
+        rpc.append("<delete-config>");
+        rpc.append("<target>");
+        rpc.append("<" + targetConfiguration + "/>");
+        rpc.append("</target>");
+        rpc.append("</delete-config>");
+        rpc.append("</rpc>");
+        rpc.append(endpattern);
+        String reply = null;
+        try {
+            reply = doRequest(rpc.toString());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return checkReply(reply);
+    }
+
+    @Override
+    public boolean lock() {
+        StringBuilder rpc = new StringBuilder("<?xml version=\"1.0\" " +
+                                                      "encoding=\"UTF-8\"?>");
+        rpc.append("<rpc>");
+        rpc.append("<lock>");
+        rpc.append("<target>");
+        rpc.append("<candidate/>");
+        rpc.append("</target>");
+        rpc.append("</lock>");
+        rpc.append("</rpc>");
+        rpc.append(endpattern);
+        String reply = null;
+        try {
+            reply = doRequest(rpc.toString());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return checkReply(reply);
+    }
+
+    @Override
+    public boolean unlock() {
+        StringBuilder rpc = new StringBuilder("<?xml version=\"1.0\" " +
+                                                      "encoding=\"UTF-8\"?>");
+        rpc.append("<rpc>");
+        rpc.append("<unlock>");
+        rpc.append("<target>");
+        rpc.append("<candidate/>");
+        rpc.append("</target>");
+        rpc.append("</unlock>");
+        rpc.append("</rpc>");
+        rpc.append(endpattern);
+        String reply = null;
+        try {
+            reply = doRequest(rpc.toString());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return checkReply(reply);
+    }
+
+    @Override
+    public boolean close() {
+        return close(false);
+    }
+
+    private boolean close(boolean force) {
+        StringBuilder rpc = new StringBuilder();
+        rpc.append("<rpc>");
+        if (force) {
+            rpc.append("<kill-configuration/>");
+        } else {
+            rpc.append("<close-configuration/>");
+        }
+        rpc.append("<close-configuration/>");
+        rpc.append("</rpc>");
+        rpc.append(endpattern);
+        return checkReply(rpc.toString()) ? true : close(true);
+    }
+
+    @Override
+    public String getSessionId() {
+        if (serverCapabilities.contains("<session-id>")) {
+            String[] outer = serverCapabilities.split("<session-id>");
+            Preconditions.checkArgument(outer.length != 1,
+                                        "Error in retrieving the session id");
+            String[] value = outer[1].split("</session-id>");
+            Preconditions.checkArgument(value.length != 1,
+                                        "Error in retrieving the session id");
+            return value[0];
+        } else {
+            return String.valueOf(-1);
+        }
+    }
+
+    @Override
+    public String getServerCapabilities() {
+        return serverCapabilities;
+    }
+
+    @Override
+    public void setDeviceCapabilities(List<String> capabilities) {
+        deviceCapabilities = capabilities;
+    }
+
+    private boolean checkReply(String reply) {
+        if (reply != null) {
+            if (!reply.contains("<rpc-error>")) {
+                return true;
+            } else if (reply.contains("<ok/>")
+                    || (reply.contains("<rpc-error>")
+                    && reply.contains("warning"))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private String readOne() throws IOException {
+        //TODO try a simple string
+        final StringWriter reply = new StringWriter();
+        while (true) {
+            int charRead = bufferReader.read();
+            if (charRead == -1) {
+                throw new IOException("Session closed");
+            }
+
+            for (int i = 0; i < endpattern.length(); i++) {
+                if (charRead == endpattern.charAt(i)) {
+                    if (i < endpattern.length() - 1) {
+                        charRead = bufferReader.read();
+                    } else {
+                        return reply.getBuffer().toString();
+                    }
+                } else {
+                    String s = endpattern.substring(0, i);
+                    for (int j = 0; i < s.length(); j++) {
+                        reply.write(s.charAt(j));
+                    }
+                    reply.write(charRead);
+                    break;
+                }
+            }
+        }
+    }
+
+}
