diff --git a/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/Foo.java b/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/Foo.java
deleted file mode 100644
index e0f6b3d..0000000
--- a/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/Foo.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.onosproject.netconf.ctl;
-
-/**
- * Created by tom on 10/19/15.
- */
-public class Foo {
-}
diff --git a/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java b/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java
new file mode 100644
index 0000000..a572a2b
--- /dev/null
+++ b/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java
@@ -0,0 +1,143 @@
+/*
+ * 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 org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfDevice;
+import org.onosproject.netconf.NetconfDeviceInfo;
+import org.onosproject.netconf.NetconfDeviceListener;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+/**
+ * The implementation of NetconfController.
+ */
+@Component(immediate = true)
+@Service
+public class NetconfControllerImpl implements NetconfController {
+
+    public static final Logger log = LoggerFactory
+            .getLogger(NetconfControllerImpl.class);
+
+    public Map<DeviceId, NetconfDevice> netconfDeviceMap = new ConcurrentHashMap<>();
+
+    protected Set<NetconfDeviceListener> netconfDeviceListeners = new CopyOnWriteArraySet<>();
+
+    @Activate
+    public void activate(ComponentContext context) {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        netconfDeviceMap.clear();
+        log.info("Stopped");
+    }
+
+    @Override
+    public void addDeviceListener(NetconfDeviceListener listener) {
+        if (!netconfDeviceListeners.contains(listener)) {
+            netconfDeviceListeners.add(listener);
+        }
+    }
+
+    @Override
+    public void removeDeviceListener(NetconfDeviceListener listener) {
+        netconfDeviceListeners.remove(listener);
+    }
+
+    @Override
+    public NetconfDevice getNetconfDevice(DeviceId deviceInfo) {
+        return netconfDeviceMap.get(deviceInfo);
+    }
+
+    @Override
+    public NetconfDevice getNetconfDevice(IpAddress ip, int port) {
+        NetconfDevice device = null;
+        for (DeviceId info : netconfDeviceMap.keySet()) {
+            if (IpAddress.valueOf(info.uri().getHost()).equals(ip) &&
+                    info.uri().getPort() == port) {
+                return netconfDeviceMap.get(info);
+            }
+        }
+        return device;
+    }
+
+    @Override
+    public NetconfDevice connectDevice(NetconfDeviceInfo deviceInfo) {
+        if (netconfDeviceMap.containsKey(deviceInfo.getDeviceId())) {
+            log.warn("Device {} is already present");
+            return netconfDeviceMap.get(deviceInfo.getDeviceId());
+        } else {
+            log.info("Creating NETCONF device {}", deviceInfo);
+            return createDevice(deviceInfo);
+        }
+    }
+
+    @Override
+    public void removeDevice(NetconfDeviceInfo deviceInfo) {
+        if (netconfDeviceMap.containsKey(deviceInfo.getDeviceId())) {
+            log.warn("Device {} is not present");
+        } else {
+            stopDevice(deviceInfo);
+        }
+    }
+
+    private NetconfDevice createDevice(NetconfDeviceInfo deviceInfo) {
+        NetconfDevice netconfDevice = null;
+        try {
+            netconfDevice = new NetconfDeviceImpl(deviceInfo);
+            for (NetconfDeviceListener l : netconfDeviceListeners) {
+                l.deviceAdded(deviceInfo);
+            }
+            netconfDeviceMap.put(deviceInfo.getDeviceId(), netconfDevice);
+        } catch (IOException e) {
+            throw new IllegalStateException("Cannot create NETCONF device " +
+                                                    "with device Info: " +
+                                                    deviceInfo + " \n" + e);
+        }
+        return netconfDevice;
+    }
+
+    private void stopDevice(NetconfDeviceInfo deviceInfo) {
+        netconfDeviceMap.get(deviceInfo.getDeviceId()).disconnect();
+        netconfDeviceMap.remove(deviceInfo.getDeviceId());
+        for (NetconfDeviceListener l : netconfDeviceListeners) {
+            l.deviceRemoved(deviceInfo);
+        }
+    }
+
+    @Override
+    public Map<DeviceId, NetconfDevice> getDevicesMap() {
+        return netconfDeviceMap;
+    }
+
+
+}
diff --git a/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfDeviceImpl.java b/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfDeviceImpl.java
new file mode 100644
index 0000000..3141aaf
--- /dev/null
+++ b/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfDeviceImpl.java
@@ -0,0 +1,66 @@
+/*
+ * 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 org.onosproject.netconf.NetconfDevice;
+import org.onosproject.netconf.NetconfDeviceInfo;
+import org.onosproject.netconf.NetconfSession;
+
+import java.io.IOException;
+
+/**
+ * Implementation of a NETCONF device.
+ */
+public class NetconfDeviceImpl implements NetconfDevice {
+
+    private NetconfDeviceInfo netconfDeviceInfo;
+    private boolean deviceState = false;
+    private NetconfSession netconfSession;
+    //private String config;
+
+    public NetconfDeviceImpl(NetconfDeviceInfo deviceInfo) throws IOException {
+        netconfDeviceInfo = deviceInfo;
+        try {
+            netconfSession = new NetconfSessionImpl(netconfDeviceInfo);
+        } catch (IOException e) {
+            throw new IOException("Cannot create connection and session", e);
+        }
+        deviceState = true;
+        //config = netconfSession.getConfig("running");
+    }
+
+    @Override
+    public boolean isActive() {
+        return deviceState;
+    }
+
+    @Override
+    public NetconfSession getSession() {
+        return netconfSession;
+    }
+
+    @Override
+    public void disconnect() {
+        deviceState = false;
+        netconfSession.close();
+    }
+
+    @Override
+    public NetconfDeviceInfo getDeviceInfo() {
+        return netconfDeviceInfo;
+    }
+}
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;
+                }
+            }
+        }
+    }
+
+}
