diff --git a/protocols/netconf/api/src/main/java/org/onosproject/netconf/config/NetconfDeviceConfig.java b/protocols/netconf/api/src/main/java/org/onosproject/netconf/config/NetconfDeviceConfig.java
index 28758b5..d9a3468 100644
--- a/protocols/netconf/api/src/main/java/org/onosproject/netconf/config/NetconfDeviceConfig.java
+++ b/protocols/netconf/api/src/main/java/org/onosproject/netconf/config/NetconfDeviceConfig.java
@@ -101,7 +101,7 @@
 
     /**
      * Gets the NETCONF SSH Client implementation.
-     * Expecting "apache-mina" or "ethz-ssh2"
+     * Expecting "apache-mina"
      *
      * @return sshClient
      */
@@ -192,7 +192,7 @@
 
     /**
      * Sets the NETCONF Ssh client implementation for the Device.
-     * Must be 'apache-mina' or 'ethz-ssh2'
+     * Must be 'apache-mina'
      * When specified, overrides NetconfControllerImpl.sshLibrary for this device
      *
      * @param sshimpl sshimpl as string
diff --git a/protocols/netconf/api/src/main/java/org/onosproject/netconf/config/NetconfSshClientLib.java b/protocols/netconf/api/src/main/java/org/onosproject/netconf/config/NetconfSshClientLib.java
index 8ca1e93..aeacaec 100644
--- a/protocols/netconf/api/src/main/java/org/onosproject/netconf/config/NetconfSshClientLib.java
+++ b/protocols/netconf/api/src/main/java/org/onosproject/netconf/config/NetconfSshClientLib.java
@@ -19,8 +19,7 @@
  * Enumerated list of SSH client library types.
  */
 public enum NetconfSshClientLib {
-    APACHE_MINA("apache-mina"),
-    ETHZ_SSH2("ethz-ssh2");
+    APACHE_MINA("apache-mina");
 
     private String impl;
 
diff --git a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfControllerImpl.java b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfControllerImpl.java
index 2c885e0..ab0189d 100644
--- a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfControllerImpl.java
+++ b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfControllerImpl.java
@@ -71,8 +71,6 @@
 @Service
 public class NetconfControllerImpl implements NetconfController {
 
-    private static final String ETHZ_SSH2 = "ethz-ssh2";
-
     protected static final int DEFAULT_CONNECT_TIMEOUT_SECONDS = 5;
     private static final String PROP_NETCONF_CONNECT_TIMEOUT = "netconfConnectTimeout";
     // FIXME @Property should not be static
@@ -97,7 +95,7 @@
     private static final String SSH_LIBRARY = "sshLibrary";
     private static final String APACHE_MINA_STR = "apache-mina";
     @Property(name = SSH_LIBRARY, value = APACHE_MINA_STR,
-            label = "Ssh Library instead of apache_mina (i.e. ethz-ssh2")
+            label = "Ssh client library to use")
     protected NetconfSshClientLib sshLibrary = NetconfSshClientLib.APACHE_MINA;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -351,13 +349,6 @@
         @Override
         public NetconfDevice createNetconfDevice(NetconfDeviceInfo netconfDeviceInfo)
                 throws NetconfException {
-            if (NetconfSshClientLib.ETHZ_SSH2.equals(netconfDeviceInfo.sshClientLib().orElse(null)) ||
-                    NetconfSshClientLib.ETHZ_SSH2.equals(sshLibrary)) {
-                log.info("Creating NETCONF session to {} with {}",
-                            netconfDeviceInfo.name(), NetconfSshClientLib.ETHZ_SSH2);
-                return new DefaultNetconfDevice(netconfDeviceInfo,
-                            new NetconfSessionImpl.SshNetconfSessionFactory());
-            }
             log.info("Creating NETCONF session to {} with {}",
                     netconfDeviceInfo.getDeviceId(), NetconfSshClientLib.APACHE_MINA);
             return new DefaultNetconfDevice(netconfDeviceInfo);
diff --git a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfSessionImpl.java b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfSessionImpl.java
deleted file mode 100644
index 51a8cfd..0000000
--- a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfSessionImpl.java
+++ /dev/null
@@ -1,915 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Foundation
- *
- * 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.impl;
-
-import com.google.common.annotations.Beta;
-import ch.ethz.ssh2.Connection;
-import ch.ethz.ssh2.Session;
-import ch.ethz.ssh2.channel.Channel;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import org.onosproject.netconf.NetconfSessionFactory;
-import org.onosproject.netconf.DatastoreId;
-import org.onosproject.netconf.FilteringNetconfDeviceOutputEventListener;
-import org.onosproject.netconf.NetconfDeviceInfo;
-import org.onosproject.netconf.NetconfDeviceOutputEvent;
-import org.onosproject.netconf.NetconfDeviceOutputEvent.Type;
-import org.onosproject.netconf.NetconfDeviceOutputEventListener;
-import org.onosproject.netconf.NetconfException;
-import org.onosproject.netconf.NetconfSession;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-
-/**
- * Implementation of a NETCONF session to talk to a device.
- *
- * @deprecated in 1.12.0 use {@link NetconfSessionMinaImpl}
- */
-@Deprecated
-public class NetconfSessionImpl implements NetconfSession {
-
-    private static final Logger log = LoggerFactory
-            .getLogger(NetconfSessionImpl.class);
-
-    private static final String ENDPATTERN = "]]>]]>";
-    private static final String MESSAGE_ID_STRING = "message-id";
-    private static final String HELLO = "<hello";
-    private static final String NEW_LINE = "\n";
-    private static final String END_OF_RPC_OPEN_TAG = "\">";
-    private static final String EQUAL = "=";
-    private static final String NUMBER_BETWEEN_QUOTES_MATCHER = "\"+([0-9]+)+\"";
-    private static final String RPC_OPEN = "<rpc ";
-    private static final String RPC_CLOSE = "</rpc>";
-    private static final String GET_OPEN = "<get>";
-    private static final String GET_CLOSE = "</get>";
-    private static final String WITH_DEFAULT_OPEN = "<with-defaults ";
-    private static final String WITH_DEFAULT_CLOSE = "</with-defaults>";
-    private static final String DEFAULT_OPERATION_OPEN = "<default-operation>";
-    private static final String DEFAULT_OPERATION_CLOSE = "</default-operation>";
-    private static final String SUBTREE_FILTER_OPEN = "<filter type=\"subtree\">";
-    private static final String SUBTREE_FILTER_CLOSE = "</filter>";
-    private static final String EDIT_CONFIG_OPEN = "<edit-config>";
-    private static final String EDIT_CONFIG_CLOSE = "</edit-config>";
-    private static final String TARGET_OPEN = "<target>";
-    private static final String TARGET_CLOSE = "</target>";
-    private static final String CONFIG_OPEN = "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
-    private static final String CONFIG_CLOSE = "</config>";
-    private static final String XML_HEADER =
-            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
-    private static final String NETCONF_BASE_NAMESPACE =
-            "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"";
-    private static final String NETCONF_WITH_DEFAULTS_NAMESPACE =
-            "xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\"";
-    private static final String SUBSCRIPTION_SUBTREE_FILTER_OPEN =
-            "<filter xmlns:base10=\"urn:ietf:params:xml:ns:netconf:base:1.0\" base10:type=\"subtree\">";
-
-    private static final String INTERLEAVE_CAPABILITY_STRING = "urn:ietf:params:netconf:capability:interleave:1.0";
-
-    private static final String CAPABILITY_REGEX = "<capability>\\s*(.*?)\\s*</capability>";
-    private static final Pattern CAPABILITY_REGEX_PATTERN = Pattern.compile(CAPABILITY_REGEX);
-
-    private static final String SESSION_ID_REGEX = "<session-id>\\s*(.*?)\\s*</session-id>";
-    private static final Pattern SESSION_ID_REGEX_PATTERN = Pattern.compile(SESSION_ID_REGEX);
-    private static final String HASH = "#";
-    private static final String LF = "\n";
-    private static final String LESS_THAN = "<";
-    private static final String MSGLEN_REGEX_PATTERN = "\n#\\d+\n";
-    private static final String NETCONF_10_CAPABILITY = "urn:ietf:params:netconf:base:1.0";
-    protected static final String NETCONF_11_CAPABILITY = "urn:ietf:params:netconf:base:1.1";
-
-    private String sessionID;
-    private final AtomicInteger messageIdInteger = new AtomicInteger(1);
-    private Connection netconfConnection;
-    protected final NetconfDeviceInfo deviceInfo;
-    private Session sshSession;
-    private boolean connectionActive;
-    private Iterable<String> onosCapabilities =
-            ImmutableList.of(NETCONF_10_CAPABILITY, NETCONF_11_CAPABILITY);
-
-    /* NOTE: the "serverHelloResponseOld" is deprecated in 1.10.0 and should eventually be removed */
-    @Deprecated
-    private String serverHelloResponseOld;
-    private final Set<String> deviceCapabilities = new LinkedHashSet<>();
-    private NetconfStreamHandler streamHandler;
-    private Map<Integer, CompletableFuture<String>> replies;
-    private List<String> errorReplies;
-    private boolean subscriptionConnected = false;
-    private String notificationFilterSchema = null;
-
-    private final Collection<NetconfDeviceOutputEventListener> primaryListeners =
-            new CopyOnWriteArrayList<>();
-    private final Collection<NetconfSession> children =
-            new CopyOnWriteArrayList<>();
-
-    private int connectTimeout;
-    private int replyTimeout;
-
-    public NetconfSessionImpl(NetconfDeviceInfo deviceInfo) throws NetconfException {
-        this.deviceInfo = deviceInfo;
-        this.netconfConnection = null;
-        this.sshSession = null;
-        connectionActive = false;
-        replies = new ConcurrentHashMap<>();
-        errorReplies = new ArrayList<>();
-
-        startConnection();
-    }
-
-    public NetconfSessionImpl(NetconfDeviceInfo deviceInfo, List<String> capabilities) throws NetconfException {
-        this.deviceInfo = deviceInfo;
-        this.netconfConnection = null;
-        this.sshSession = null;
-        connectionActive = false;
-        replies = new ConcurrentHashMap<>();
-        errorReplies = new ArrayList<>();
-        setOnosCapabilities(capabilities);
-        startConnection();
-
-    }
-
-    private void startConnection() throws NetconfException {
-        connectTimeout = deviceInfo.getConnectTimeoutSec().orElse(
-                                    NetconfControllerImpl.netconfConnectTimeout);
-        replyTimeout = deviceInfo.getReplyTimeoutSec().orElse(
-                                    NetconfControllerImpl.netconfReplyTimeout);
-        log.debug("Connecting to {} with timeouts C:{}, R:{}. I:connect-timeout", deviceInfo,
-                connectTimeout, replyTimeout);
-
-        if (!connectionActive) {
-            netconfConnection = new Connection(deviceInfo.ip().toString(), deviceInfo.port());
-
-            try {
-                netconfConnection.connect(null, 1000 * connectTimeout, 1000 * connectTimeout);
-            } catch (IOException e) {
-                throw new NetconfException("Cannot open a connection with device " + deviceInfo, e);
-            }
-            boolean isAuthenticated;
-            try {
-                if (deviceInfo.getKey() != null) {
-                    log.debug("Authenticating with key to device {} with username {}",
-                            deviceInfo.getDeviceId(), deviceInfo.name());
-                    isAuthenticated = netconfConnection.authenticateWithPublicKey(
-                            deviceInfo.name(), deviceInfo.getKey(),
-                            deviceInfo.password().equals("") ? null : deviceInfo.password());
-                } else {
-                    log.debug("Authenticating to device {} with username {} with password",
-                            deviceInfo.getDeviceId(), deviceInfo.name());
-                    isAuthenticated = netconfConnection.authenticateWithPassword(
-                            deviceInfo.name(), deviceInfo.password());
-                }
-            } catch (IOException e) {
-                log.error("Authentication connection to device {} failed",
-                        deviceInfo.getDeviceId(), e);
-                throw new NetconfException("Authentication connection to device " +
-                        deviceInfo.getDeviceId() + " failed", e);
-            }
-
-            connectionActive = true;
-            Preconditions.checkArgument(isAuthenticated,
-                    "Authentication to device %s with username " +
-                            "%s failed",
-                    deviceInfo.getDeviceId(), deviceInfo.name());
-            startSshSession();
-        }
-    }
-
-    private void startSshSession() throws NetconfException {
-        try {
-            sshSession = netconfConnection.openSession();
-            sshSession.startSubSystem("netconf");
-            streamHandler = new NetconfStreamThread(sshSession.getStdout(), sshSession.getStdin(),
-                    sshSession.getStderr(), deviceInfo,
-                    new NetconfSessionDelegateImpl(),
-                    replies);
-            this.addDeviceOutputListener(new FilteringNetconfDeviceOutputEventListener(deviceInfo));
-            sendHello();
-        } catch (IOException e) {
-            log.error("Failed to create ch.ethz.ssh2.Session session {} ", e.getMessage());
-            throw new NetconfException("Failed to create ch.ethz.ssh2.Session session with device" +
-                    deviceInfo, e);
-        }
-    }
-
-
-    @Beta
-    protected void startSubscriptionStream(String filterSchema) throws NetconfException {
-        boolean openNewSession = false;
-        if (!deviceCapabilities.contains(INTERLEAVE_CAPABILITY_STRING)) {
-            log.info("Device {} doesn't support interleave, creating child session", deviceInfo);
-            openNewSession = true;
-
-        } else if (subscriptionConnected &&
-                notificationFilterSchema != null &&
-                !Objects.equal(filterSchema, notificationFilterSchema)) {
-            // interleave supported and existing filter is NOT "no filtering"
-            // and was requested with different filtering schema
-            log.info("Cannot use existing session for subscription {} ({})",
-                    deviceInfo, filterSchema);
-            openNewSession = true;
-        }
-
-        if (openNewSession) {
-            log.info("Creating notification session to {} with filter {}",
-                    deviceInfo, filterSchema);
-            NetconfSession child = new NotificationSession(deviceInfo);
-
-            child.addDeviceOutputListener(new NotificationForwarder());
-
-            child.startSubscription(filterSchema);
-            children.add(child);
-            return;
-        }
-
-        // request to start interleaved notification session
-        String reply = sendRequest(createSubscriptionString(filterSchema));
-        if (!checkReply(reply)) {
-            throw new NetconfException("Subscription not successful with device "
-                    + deviceInfo + " with reply " + reply);
-        }
-        subscriptionConnected = true;
-    }
-
-    @Override
-    public void startSubscription() throws NetconfException {
-        if (!subscriptionConnected) {
-            startSubscriptionStream(null);
-        }
-        streamHandler.setEnableNotifications(true);
-    }
-
-    @Beta
-    @Override
-    public void startSubscription(String filterSchema) throws NetconfException {
-        if (!subscriptionConnected) {
-            notificationFilterSchema = filterSchema;
-            startSubscriptionStream(filterSchema);
-        }
-        streamHandler.setEnableNotifications(true);
-    }
-
-    @Beta
-    protected String createSubscriptionString(String filterSchema) {
-        StringBuilder subscriptionbuffer = new StringBuilder();
-        subscriptionbuffer.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
-        subscriptionbuffer.append("  <create-subscription\n");
-        subscriptionbuffer.append("xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n");
-        // FIXME Only subtree filtering supported at the moment.
-        if (filterSchema != null) {
-            subscriptionbuffer.append("    ");
-            subscriptionbuffer.append(SUBSCRIPTION_SUBTREE_FILTER_OPEN).append(NEW_LINE);
-            subscriptionbuffer.append(filterSchema).append(NEW_LINE);
-            subscriptionbuffer.append("    ");
-            subscriptionbuffer.append(SUBTREE_FILTER_CLOSE).append(NEW_LINE);
-        }
-        subscriptionbuffer.append("  </create-subscription>\n");
-        subscriptionbuffer.append("</rpc>\n");
-        subscriptionbuffer.append(ENDPATTERN);
-        return subscriptionbuffer.toString();
-    }
-
-    @Override
-    public void endSubscription() throws NetconfException {
-        if (subscriptionConnected) {
-            streamHandler.setEnableNotifications(false);
-        } else {
-            throw new NetconfException("Subscription does not exist.");
-        }
-    }
-
-    private void sendHello() throws NetconfException {
-        serverHelloResponseOld = sendRequest(createHelloString(), true);
-        Matcher capabilityMatcher = CAPABILITY_REGEX_PATTERN.matcher(serverHelloResponseOld);
-        while (capabilityMatcher.find()) {
-            deviceCapabilities.add(capabilityMatcher.group(1));
-        }
-        sessionID = String.valueOf(-1);
-        Matcher sessionIDMatcher = SESSION_ID_REGEX_PATTERN.matcher(serverHelloResponseOld);
-        if (sessionIDMatcher.find()) {
-            sessionID = sessionIDMatcher.group(1);
-        } else {
-            throw new NetconfException("Missing SessionID in server hello " +
-                    "reponse.");
-        }
-
-    }
-
-    private String createHelloString() {
-        StringBuilder hellobuffer = new StringBuilder();
-        hellobuffer.append(XML_HEADER);
-        hellobuffer.append("\n");
-        hellobuffer.append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
-        hellobuffer.append("  <capabilities>\n");
-        onosCapabilities.forEach(
-                cap -> hellobuffer.append("    <capability>")
-                        .append(cap)
-                        .append("</capability>\n"));
-        hellobuffer.append("  </capabilities>\n");
-        hellobuffer.append("</hello>\n");
-        hellobuffer.append(ENDPATTERN);
-        return hellobuffer.toString();
-
-    }
-
-    @Override
-    public void checkAndReestablish() throws NetconfException {
-        if (sshSession.getState() != Channel.STATE_OPEN) {
-            try {
-                log.debug("Trying to reopen the Sesion with {}", deviceInfo.getDeviceId());
-                startSshSession();
-            } catch (NetconfException | IllegalStateException e) {
-                log.debug("Trying to reopen the Connection with {}", deviceInfo.getDeviceId());
-                try {
-                    connectionActive = false;
-                    replies.clear();
-                    startConnection();
-                    if (subscriptionConnected) {
-                        log.debug("Restarting subscription with {}", deviceInfo.getDeviceId());
-                        subscriptionConnected = false;
-                        startSubscription(notificationFilterSchema);
-                    }
-                } catch (NetconfException e2) {
-                    log.error("No connection {} for device {}", netconfConnection, e.getMessage());
-                    throw new NetconfException("Cannot re-open the connection with device" + deviceInfo, e);
-                }
-            }
-        }
-    }
-
-    /**
-     * Validate and format message according to chunked framing mechanism.
-     *
-     * @param request to format
-     * @return formated message
-     */
-    private static String validateChunkedMessage(String request) {
-        if (request.endsWith(ENDPATTERN)) {
-            request = request.substring(0, request.length() - ENDPATTERN.length());
-        }
-        if (!request.startsWith(LF + HASH)) {
-            request = LF + HASH + request.length() + LF + request + LF + HASH + HASH + LF;
-        }
-        return request;
-    }
-
-    /**
-     * Validate and format netconf message.
-     *
-     * @param request to format
-     * @return formated message
-     */
-    private String validateNetconfMessage(String request) {
-        if (deviceCapabilities.contains(NETCONF_11_CAPABILITY)) {
-            request = validateChunkedMessage(request);
-        } else {
-            if (!request.contains(ENDPATTERN)) {
-                request = request + NEW_LINE + ENDPATTERN;
-            }
-        }
-        return  request;
-    }
-
-    @Override
-    public String requestSync(String request) throws NetconfException {
-        String reply = sendRequest(request);
-        checkReply(reply);
-        return reply;
-    }
-
-    @Override
-    @Deprecated
-    public CompletableFuture<String> request(String request) {
-        return streamHandler.sendMessage(request);
-    }
-
-    private CompletableFuture<String> request(String request, int messageId) {
-        return streamHandler.sendMessage(request, messageId);
-    }
-
-    private String sendRequest(String request) throws NetconfException {
-        request = validateNetconfMessage(request);
-        return sendRequest(request, false);
-    }
-
-    private String sendRequest(String request, boolean isHello) throws NetconfException {
-        checkAndReestablish();
-        int messageId = -1;
-        if (!isHello) {
-            messageId = messageIdInteger.getAndIncrement();
-        }
-        request = formatXmlHeader(request);
-        request = formatRequestMessageId(request, messageId);
-        CompletableFuture<String> futureReply = request(request, messageId);
-        String rp;
-        try {
-            log.debug("Sending request to NETCONF with timeout {} for {}",
-                    replyTimeout, deviceInfo.name());
-            rp = futureReply.get(replyTimeout, TimeUnit.SECONDS);
-            replies.remove(messageId);
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new NetconfException("Interrupted waiting for reply for request" + request, e);
-        } catch (TimeoutException e) {
-            throw new NetconfException("Timed out waiting for reply for request " +
-                    request + " after " + replyTimeout + " sec.", e);
-        } catch (ExecutionException e) {
-            log.warn("Closing session {} for {} due to unexpected Error", sessionID, deviceInfo, e);
-
-            netconfConnection.close(); //Closes the socket which should interrupt NetconfStreamThread
-            sshSession.close();
-
-            NetconfDeviceOutputEvent event = new NetconfDeviceOutputEvent(
-                    NetconfDeviceOutputEvent.Type.SESSION_CLOSED,
-                    null, "Closed due to unexpected error " + e.getCause(),
-                    Optional.of(-1), deviceInfo);
-            publishEvent(event);
-            replies.clear();
-            errorReplies.clear();
-
-            throw new NetconfException("Closing session " + sessionID + " for " + deviceInfo +
-                    " for request " + request, e);
-        }
-        log.debug("Result {} from request {} to device {}", rp, request, deviceInfo);
-        return rp.trim();
-    }
-
-    private String formatRequestMessageId(String request, int messageId) {
-        if (request.contains(MESSAGE_ID_STRING)) {
-            //FIXME if application provides his own counting of messages this fails that count
-            request = request.replaceFirst(MESSAGE_ID_STRING + EQUAL + NUMBER_BETWEEN_QUOTES_MATCHER,
-                    MESSAGE_ID_STRING + EQUAL + "\"" + messageId + "\"");
-        } else if (!request.contains(MESSAGE_ID_STRING) && !request.contains(HELLO)) {
-            //FIXME find out a better way to enforce the presence of message-id
-            request = request.replaceFirst(END_OF_RPC_OPEN_TAG, "\" " + MESSAGE_ID_STRING + EQUAL + "\""
-                    + messageId + "\"" + ">");
-        }
-        request = updateRequestLength(request);
-        return request;
-    }
-
-    private String updateRequestLength(String request) {
-        if (request.contains(LF + HASH + HASH + LF)) {
-            int oldLen = Integer.parseInt(request.split(HASH)[1].split(LF)[0]);
-            String rpcWithEnding = request.substring(request.indexOf(LESS_THAN));
-            String firstBlock = request.split(MSGLEN_REGEX_PATTERN)[1].split(LF + HASH + HASH + LF)[0];
-            int newLen = 0;
-            newLen = firstBlock.getBytes(UTF_8).length;
-            if (oldLen != newLen) {
-                return LF + HASH + newLen + LF + rpcWithEnding;
-            }
-        }
-        return request;
-    }
-
-    private String formatXmlHeader(String request) {
-        if (!request.contains(XML_HEADER)) {
-            //FIXME if application provieds his own XML header of different type there is a clash
-            if (request.startsWith(LF + HASH)) {
-                request = request.split("<")[0] + XML_HEADER + request.substring(request.split("<")[0].length());
-            } else {
-                request = XML_HEADER + "\n" + request;
-            }
-        }
-        return request;
-    }
-
-    @Override
-    public String doWrappedRpc(String request) throws NetconfException {
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append(RPC_OPEN);
-        rpc.append(MESSAGE_ID_STRING);
-        rpc.append(EQUAL);
-        rpc.append("\"");
-        rpc.append(messageIdInteger.get());
-        rpc.append("\"  ");
-        rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
-        rpc.append(request);
-        rpc.append(RPC_CLOSE).append(NEW_LINE);
-        rpc.append(ENDPATTERN);
-        String reply = sendRequest(rpc.toString());
-        checkReply(reply);
-        return reply;
-    }
-
-    @Override
-    public String get(String request) throws NetconfException {
-        return requestSync(request);
-    }
-
-    @Override
-    public String get(String filterSchema, String withDefaultsMode) throws NetconfException {
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append(RPC_OPEN);
-        rpc.append(MESSAGE_ID_STRING);
-        rpc.append(EQUAL);
-        rpc.append("\"");
-        rpc.append(messageIdInteger.get());
-        rpc.append("\"  ");
-        rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
-        rpc.append(GET_OPEN).append(NEW_LINE);
-        if (filterSchema != null) {
-            rpc.append(SUBTREE_FILTER_OPEN).append(NEW_LINE);
-            rpc.append(filterSchema).append(NEW_LINE);
-            rpc.append(SUBTREE_FILTER_CLOSE).append(NEW_LINE);
-        }
-        if (withDefaultsMode != null) {
-            rpc.append(WITH_DEFAULT_OPEN).append(NETCONF_WITH_DEFAULTS_NAMESPACE).append(">");
-            rpc.append(withDefaultsMode).append(WITH_DEFAULT_CLOSE).append(NEW_LINE);
-        }
-        rpc.append(GET_CLOSE).append(NEW_LINE);
-        rpc.append(RPC_CLOSE).append(NEW_LINE);
-        rpc.append(ENDPATTERN);
-        String reply = sendRequest(rpc.toString());
-        checkReply(reply);
-        return reply;
-    }
-
-    @Override
-    public String getConfig(DatastoreId netconfTargetConfig) throws NetconfException {
-        return getConfig(netconfTargetConfig, null);
-    }
-
-    @Override
-    public String getConfig(DatastoreId netconfTargetConfig,
-                            String configurationSchema) throws NetconfException {
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append("<rpc ");
-        rpc.append(MESSAGE_ID_STRING);
-        rpc.append(EQUAL);
-        rpc.append("\"");
-        rpc.append(messageIdInteger.get());
-        rpc.append("\"  ");
-        rpc.append("xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
-        rpc.append("<get-config>\n");
-        rpc.append("<source>\n");
-        rpc.append("<").append(netconfTargetConfig).append("/>");
-        rpc.append("</source>");
-        if (configurationSchema != null) {
-            rpc.append("<filter type=\"subtree\">\n");
-            rpc.append(configurationSchema).append("\n");
-            rpc.append("</filter>\n");
-        }
-        rpc.append("</get-config>\n");
-        rpc.append("</rpc>\n");
-        rpc.append(ENDPATTERN);
-        String reply = sendRequest(rpc.toString());
-        return checkReply(reply) ? reply : "ERROR " + reply;
-    }
-
-    @Override
-    public boolean editConfig(String newConfiguration) throws NetconfException {
-        if (!newConfiguration.endsWith(ENDPATTERN)) {
-            newConfiguration = newConfiguration + ENDPATTERN;
-        }
-        return checkReply(sendRequest(newConfiguration));
-    }
-
-    @Override
-    public boolean editConfig(DatastoreId netconfTargetConfig, String mode, String newConfiguration)
-            throws NetconfException {
-        newConfiguration = newConfiguration.trim();
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append(RPC_OPEN);
-        rpc.append(MESSAGE_ID_STRING);
-        rpc.append(EQUAL);
-        rpc.append("\"");
-        rpc.append(messageIdInteger.get());
-        rpc.append("\"  ");
-        rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
-        rpc.append(EDIT_CONFIG_OPEN).append("\n");
-        rpc.append(TARGET_OPEN);
-        rpc.append("<").append(netconfTargetConfig).append("/>");
-        rpc.append(TARGET_CLOSE).append("\n");
-        if (mode != null) {
-            rpc.append(DEFAULT_OPERATION_OPEN);
-            rpc.append(mode);
-            rpc.append(DEFAULT_OPERATION_CLOSE).append("\n");
-        }
-        rpc.append(CONFIG_OPEN).append("\n");
-        rpc.append(newConfiguration);
-        rpc.append(CONFIG_CLOSE).append("\n");
-        rpc.append(EDIT_CONFIG_CLOSE).append("\n");
-        rpc.append(RPC_CLOSE);
-        rpc.append(ENDPATTERN);
-        log.debug(rpc.toString());
-        String reply = sendRequest(rpc.toString());
-        return checkReply(reply);
-    }
-
-    @Override
-    public boolean copyConfig(DatastoreId destination,
-                              DatastoreId source)
-            throws NetconfException {
-        return bareCopyConfig(destination.asXml(), source.asXml());
-    }
-
-    @Override
-    public boolean copyConfig(DatastoreId netconfTargetConfig,
-                              String newConfiguration)
-            throws NetconfException {
-        return bareCopyConfig(netconfTargetConfig.asXml(),
-                normalizeCopyConfigParam(newConfiguration));
-    }
-
-    @Override
-    public boolean copyConfig(String netconfTargetConfig,
-                              String newConfiguration) throws NetconfException {
-        return bareCopyConfig(normalizeCopyConfigParam(netconfTargetConfig),
-                normalizeCopyConfigParam(newConfiguration));
-    }
-
-    /**
-     * Normalize String parameter passed to copy-config API.
-     * <p>
-     * Provided for backward compatibility purpose
-     *
-     * @param input passed to copyConfig API
-     * @return XML likely to be suitable for copy-config source or target
-     */
-    private static CharSequence normalizeCopyConfigParam(String input) {
-        input = input.trim();
-        if (input.startsWith("<url")) {
-            return input;
-        } else if (!input.startsWith("<")) {
-            // assume it is a datastore name
-            return DatastoreId.datastore(input).asXml();
-        } else if (!input.startsWith("<config>")) {
-            return "<config>" + input + "</config>";
-        }
-        return input;
-    }
-
-    private boolean bareCopyConfig(CharSequence target,
-                                   CharSequence source)
-            throws NetconfException {
-
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append(RPC_OPEN);
-        rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
-        rpc.append("<copy-config>");
-        rpc.append("<target>");
-        rpc.append(target);
-        rpc.append("</target>");
-        rpc.append("<source>");
-        rpc.append(source);
-        rpc.append("</source>");
-        rpc.append("</copy-config>");
-        rpc.append("</rpc>");
-        rpc.append(ENDPATTERN);
-        return checkReply(sendRequest(rpc.toString()));
-    }
-
-    @Override
-    public boolean deleteConfig(DatastoreId netconfTargetConfig) throws NetconfException {
-        if (netconfTargetConfig.equals(DatastoreId.RUNNING)) {
-            log.warn("Target configuration for delete operation can't be \"running\"",
-                    netconfTargetConfig);
-            return false;
-        }
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append("<rpc>");
-        rpc.append("<delete-config>");
-        rpc.append("<target>");
-        rpc.append("<").append(netconfTargetConfig).append("/>");
-        rpc.append("</target>");
-        rpc.append("</delete-config>");
-        rpc.append("</rpc>");
-        rpc.append(ENDPATTERN);
-        return checkReply(sendRequest(rpc.toString()));
-    }
-
-    @Override
-    public boolean lock(DatastoreId configType) throws NetconfException {
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
-        rpc.append("<lock>");
-        rpc.append("<target>");
-        rpc.append("<");
-        rpc.append(configType.id());
-        rpc.append("/>");
-        rpc.append("</target>");
-        rpc.append("</lock>");
-        rpc.append("</rpc>");
-        rpc.append(ENDPATTERN);
-        String lockReply = sendRequest(rpc.toString());
-        return checkReply(lockReply);
-    }
-
-    @Override
-    public boolean unlock(DatastoreId configType) throws NetconfException {
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
-        rpc.append("<unlock>");
-        rpc.append("<target>");
-        rpc.append("<");
-        rpc.append(configType.id());
-        rpc.append("/>");
-        rpc.append("</target>");
-        rpc.append("</unlock>");
-        rpc.append("</rpc>");
-        rpc.append(ENDPATTERN);
-        String unlockReply = sendRequest(rpc.toString());
-        return checkReply(unlockReply);
-    }
-
-    @Override
-    public boolean close() throws NetconfException {
-        return close(false);
-    }
-
-    private boolean close(boolean force) throws NetconfException {
-        StringBuilder rpc = new StringBuilder();
-        rpc.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">");
-        if (force) {
-            rpc.append("<kill-session/>");
-        } else {
-            rpc.append("<close-session/>");
-        }
-        rpc.append("</rpc>");
-        rpc.append(ENDPATTERN);
-        return checkReply(sendRequest(rpc.toString())) || close(true);
-    }
-
-    @Override
-    public String getSessionId() {
-        return sessionID;
-    }
-
-    @Override
-    public Set<String> getDeviceCapabilitiesSet() {
-        return Collections.unmodifiableSet(deviceCapabilities);
-    }
-
-    @Override
-    public void setOnosCapabilities(Iterable<String> capabilities) {
-        onosCapabilities = capabilities;
-    }
-
-    @Override
-    public void addDeviceOutputListener(NetconfDeviceOutputEventListener listener) {
-        streamHandler.addDeviceEventListener(listener);
-        primaryListeners.add(listener);
-    }
-
-    @Override
-    public int timeoutConnectSec() {
-        return connectTimeout;
-    }
-
-    @Override
-    public int timeoutReplySec() {
-        return replyTimeout;
-    }
-
-    /**
-     * Idle timeout is not settable on ETZ_SSH - the valuse used is the connect timeout.
-     */
-    @Override
-    public int timeoutIdleSec() {
-        return connectTimeout;
-    }
-
-    @Override
-    public void removeDeviceOutputListener(NetconfDeviceOutputEventListener listener) {
-        primaryListeners.remove(listener);
-        streamHandler.removeDeviceEventListener(listener);
-    }
-
-    private boolean checkReply(String reply) throws NetconfException {
-        if (reply != null) {
-            if (!reply.contains("<rpc-error>")) {
-                log.debug("Device {} sent reply {}", deviceInfo, reply);
-                return true;
-            } else if (reply.contains("<ok/>")
-                    || (reply.contains("<rpc-error>")
-                    && reply.contains("warning"))) {
-                log.debug("Device {} sent reply {}", deviceInfo, reply);
-                return true;
-            }
-        }
-        log.warn("Device {} has error in reply {}", deviceInfo, reply);
-        return false;
-    }
-
-    protected void publishEvent(NetconfDeviceOutputEvent event) {
-        primaryListeners.forEach(lsnr -> {
-            if (lsnr.isRelevant(event)) {
-                lsnr.event(event);
-            }
-        });
-    }
-
-    static class NotificationSession extends NetconfSessionImpl {
-
-        private String notificationFilter;
-
-        NotificationSession(NetconfDeviceInfo deviceInfo)
-                throws NetconfException {
-            super(deviceInfo);
-        }
-
-        @Override
-        protected void startSubscriptionStream(String filterSchema)
-                throws NetconfException {
-
-            notificationFilter = filterSchema;
-            requestSync(createSubscriptionString(filterSchema));
-        }
-
-        @Override
-        public String toString() {
-            return MoreObjects.toStringHelper(getClass())
-                    .add("deviceInfo", deviceInfo)
-                    .add("sessionID", getSessionId())
-                    .add("notificationFilter", notificationFilter)
-                    .toString();
-        }
-    }
-
-    /**
-     * Listener attached to child session for notification streaming.
-     *
-     * Forwards all notification event from child session to primary session
-     * listeners.
-     */
-    private final class NotificationForwarder
-            implements NetconfDeviceOutputEventListener {
-
-        @Override
-        public boolean isRelevant(NetconfDeviceOutputEvent event) {
-            return event.type() == Type.DEVICE_NOTIFICATION;
-        }
-
-        @Override
-        public void event(NetconfDeviceOutputEvent event) {
-            publishEvent(event);
-        }
-    }
-
-    public class NetconfSessionDelegateImpl implements NetconfSessionDelegate {
-
-        @Override
-        public void notify(NetconfDeviceOutputEvent event) {
-            Optional<Integer> messageId = event.getMessageID();
-            log.debug("messageID {}, waiting replies messageIDs {}", messageId,
-                    replies.keySet());
-            if (!messageId.isPresent()) {
-                errorReplies.add(event.getMessagePayload());
-                log.error("Device {} sent error reply {}",
-                        event.getDeviceInfo(), event.getMessagePayload());
-                return;
-            }
-            CompletableFuture<String> completedReply =
-                    replies.get(messageId.get());
-            if (completedReply != null) {
-                completedReply.complete(event.getMessagePayload());
-            }
-        }
-    }
-
-    public static class SshNetconfSessionFactory implements NetconfSessionFactory {
-
-        @Override
-        public NetconfSession createNetconfSession(NetconfDeviceInfo netconfDeviceInfo) throws NetconfException {
-            return new NetconfSessionImpl(netconfDeviceInfo);
-        }
-    }
-}
diff --git a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfStreamThread.java b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfStreamThread.java
index 12eedfa..343db0d 100644
--- a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfStreamThread.java
+++ b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfStreamThread.java
@@ -62,13 +62,10 @@
     // pattern to verify whole Chunked-Message format
     private static final Pattern CHUNKED_FRAMING_PATTERN =
             Pattern.compile("(\\n#([1-9][0-9]*)\\n(.+))+\\n##\\n", Pattern.DOTALL);
-    private static final String MSGLEN_PART_REGEX_PATTERN = "\\d+\n";
     private static final String CHUNKED_END_REGEX_PATTERN = "\n##\n";
     // pattern to parse each chunk-size in ChunkedMessage chunk
     private static final Pattern CHUNKED_SIZE_PATTERN = Pattern.compile("\\n#([1-9][0-9]*)\\n");
-    private static final String HASH = "#";
     private static final char HASH_CHAR = '#';
-    private static final String LF = "\n";
     private static final char LF_CHAR = '\n';
 
     private OutputStreamWriter outputStream;
diff --git a/protocols/netconf/ctl/src/test/java/org/onosproject/netconf/ctl/impl/NetconfControllerImplTest.java b/protocols/netconf/ctl/src/test/java/org/onosproject/netconf/ctl/impl/NetconfControllerImplTest.java
index d77c222..b350688 100644
--- a/protocols/netconf/ctl/src/test/java/org/onosproject/netconf/ctl/impl/NetconfControllerImplTest.java
+++ b/protocols/netconf/ctl/src/test/java/org/onosproject/netconf/ctl/impl/NetconfControllerImplTest.java
@@ -132,7 +132,7 @@
         //Creating mock devices
         deviceInfo1 = new NetconfDeviceInfo("device1", "001", IpAddress.valueOf(DEVICE_1_IP), DEVICE_1_PORT);
         deviceInfo2 = new NetconfDeviceInfo("device2", "002", IpAddress.valueOf(DEVICE_2_IP), DEVICE_2_PORT);
-        deviceInfo2.setSshClientLib(Optional.of(NetconfSshClientLib.ETHZ_SSH2));
+        deviceInfo2.setSshClientLib(Optional.of(NetconfSshClientLib.APACHE_MINA));
         badDeviceInfo3 = new NetconfDeviceInfo("device3", "003", IpAddress.valueOf(BAD_DEVICE_IP), BAD_DEVICE_PORT);
         deviceInfoIpV6 = new NetconfDeviceInfo("deviceIpv6", "004", IpAddress.valueOf(DEVICE_IPV6), IPV6_DEVICE_PORT);
 
@@ -147,7 +147,7 @@
                 "  \"" + NetconfDeviceConfig.CONNECT_TIMEOUT + "\":" + DEVICE_10_CONNECT_TIMEOUT + ",\n" +
                 "  \"" + NetconfDeviceConfig.REPLY_TIMEOUT + "\":" + DEVICE_10_REPLY_TIMEOUT + ",\n" +
                 "  \"" + NetconfDeviceConfig.IDLE_TIMEOUT + "\":" + DEVICE_10_IDLE_TIMEOUT + ",\n" +
-                "  \"" + NetconfDeviceConfig.SSHCLIENT + "\":\"" + NetconfSshClientLib.ETHZ_SSH2.toString() + "\"\n" +
+                "  \"" + NetconfDeviceConfig.SSHCLIENT + "\":\"" + NetconfSshClientLib.APACHE_MINA.toString() + "\"\n" +
                 "}";
         InputStream jsonStream = new ByteArrayInputStream(jsonMessage.getBytes());
         JsonNode jsonNode = mapper.readTree(jsonStream);
@@ -218,7 +218,7 @@
                      2, ctrl.netconfConnectTimeout);
         assertEquals("Incorrect NetConf session timeout",
                      1, ctrl.netconfReplyTimeout);
-        assertEquals("ethz-ssh2", ctrl.sshLibrary.toString());
+        assertEquals(NetconfSshClientLib.APACHE_MINA.toString(), ctrl.sshLibrary.toString());
     }
 
     /**
@@ -308,7 +308,7 @@
                 DEVICE_10_IDLE_TIMEOUT);
         assertEquals("Incorrect device fetched - sshClient",
                 fetchedDevice10.getDeviceInfo().sshClientLib().get(),
-                NetconfSshClientLib.ETHZ_SSH2);
+                NetconfSshClientLib.APACHE_MINA);
     }
 
     /**
@@ -485,7 +485,7 @@
             } else if (key.equals("netconfReplyTimeout")) {
                 return "1";
             } else if (key.equals("sshLibrary")) {
-                return "ethz-ssh2";
+                return NetconfSshClientLib.APACHE_MINA.toString();
             }
             return null;
         }
diff --git a/protocols/netconf/ctl/src/test/java/org/onosproject/netconf/ctl/impl/NetconfSessionImplTest.java b/protocols/netconf/ctl/src/test/java/org/onosproject/netconf/ctl/impl/NetconfSessionImplTest.java
deleted file mode 100644
index 51bf91c..0000000
--- a/protocols/netconf/ctl/src/test/java/org/onosproject/netconf/ctl/impl/NetconfSessionImplTest.java
+++ /dev/null
@@ -1,768 +0,0 @@
-/*
- * Copyright 2017-present Open Networking Foundation
- *
- * 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.impl;
-
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.junit.Assert.assertFalse;
-import static org.onosproject.netconf.DatastoreId.CANDIDATE;
-import static org.onosproject.netconf.DatastoreId.RUNNING;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Optional;
-import java.util.OptionalInt;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.regex.Pattern;
-
-import com.google.common.collect.ImmutableList;
-import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.server.Command;
-import org.apache.sshd.server.SshServer;
-import org.apache.sshd.server.auth.password.PasswordAuthenticator;
-import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
-import org.apache.sshd.server.session.ServerSession;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.junit.TestTools;
-import org.onlab.packet.Ip4Address;
-import org.onosproject.netconf.DatastoreId;
-import org.onosproject.netconf.NetconfController;
-import org.onosproject.netconf.NetconfDeviceInfo;
-import org.onosproject.netconf.NetconfException;
-import org.onosproject.netconf.NetconfSession;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-/**
- * Unit tests for NetconfSession.
- * <p>
- * Sets up an SSH Server with Apache SSHD and connects to it using 2 clients
- * Truly verifies that the NETCONF flows are compliant with a NETCONF server.
- */
-public class NetconfSessionImplTest {
-    private static final Logger log = LoggerFactory
-            .getLogger(NetconfSessionImplTest.class);
-
-    private static final String TEST_USERNAME = "netconf";
-    private static final String TEST_PASSWORD = "netconf123";
-    private static final String TEST_HOSTNAME = "127.0.0.1";
-
-    private static final String TEST_SERFILE =
-            System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + "testkey.ser";
-
-    private static final String SAMPLE_REQUEST =
-            "<some-yang-element xmlns=\"some-namespace\">"
-                    + "<some-child-element/>"
-                    + "</some-yang-element>";
-
-    private static final String EDIT_CONFIG_REQUEST =
-            "<?xml version=\"1.0\" encoding=\"UTF-8\"?><rpc message-id=\"6\"  "
-                    + "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
-                    + "<edit-config>\n"
-                    + "<target><running/></target>\n"
-                    + "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
-                    + "<some-yang-element xmlns=\"some-namespace\">"
-                    + "<some-child-element/></some-yang-element></config>\n"
-                    + "</edit-config>\n"
-                    + "</rpc>]]>]]>";
-
-    private static NetconfSession session1;
-    private static NetconfSession session2;
-    private static NetconfSession session3;
-    private static NetconfSession session4;
-    private static SshServer sshServerNetconf;
-
-    @BeforeClass
-    public static void setUp() throws Exception {
-        int portNumber = TestTools.findAvailablePort(50830);
-        sshServerNetconf = SshServer.setUpDefaultServer();
-        sshServerNetconf.setPasswordAuthenticator(
-                new PasswordAuthenticator() {
-                    @Override
-                    public boolean authenticate(
-                            String username,
-                            String password,
-                            ServerSession session) {
-                        return TEST_USERNAME.equals(username) && TEST_PASSWORD.equals(password);
-                    }
-                });
-        sshServerNetconf.setPort(portNumber);
-        SimpleGeneratorHostKeyProvider provider = new SimpleGeneratorHostKeyProvider();
-        provider.setFile(new File(TEST_SERFILE));
-        sshServerNetconf.setKeyPairProvider(provider);
-        sshServerNetconf.setSubsystemFactories(
-                Arrays.<NamedFactory<Command>>asList(new NetconfSshdTestSubsystem.Factory()));
-        sshServerNetconf.open();
-        log.info("SSH Server opened on port {}", portNumber);
-
-        NetconfController netconfCtl = new NetconfControllerImpl();
-        NetconfControllerImpl.netconfConnectTimeout = NetconfControllerImpl.DEFAULT_CONNECT_TIMEOUT_SECONDS;
-        NetconfControllerImpl.netconfIdleTimeout = NetconfControllerImpl.DEFAULT_IDLE_TIMEOUT_SECONDS;
-        NetconfControllerImpl.netconfReplyTimeout = NetconfControllerImpl.DEFAULT_REPLY_TIMEOUT_SECONDS;
-
-        NetconfDeviceInfo deviceInfo1 = new NetconfDeviceInfo(
-                TEST_USERNAME, TEST_PASSWORD, Ip4Address.valueOf(TEST_HOSTNAME), portNumber);
-
-        session1 = new NetconfSessionImpl(deviceInfo1, ImmutableList.of("urn:ietf:params:netconf:base:1.0"));
-        log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session1.getSessionId());
-        assertTrue("Incorrect sessionId", !session1.getSessionId().equalsIgnoreCase("-1"));
-        assertTrue("Incorrect sessionId", !session1.getSessionId().equalsIgnoreCase("0"));
-        assertThat(session1.getDeviceCapabilitiesSet(), containsInAnyOrder(
-                NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES.toArray()));
-
-        NetconfDeviceInfo deviceInfo2 = new NetconfDeviceInfo(
-                TEST_USERNAME, TEST_PASSWORD, Ip4Address.valueOf(TEST_HOSTNAME), portNumber);
-        deviceInfo2.setConnectTimeoutSec(OptionalInt.of(11));
-        deviceInfo2.setReplyTimeoutSec(OptionalInt.of(10));
-        deviceInfo2.setIdleTimeoutSec(OptionalInt.of(12));
-        session2 = new NetconfSessionMinaImpl(deviceInfo2, ImmutableList.of("urn:ietf:params:netconf:base:1.0"));
-        log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session2.getSessionId());
-        assertTrue("Incorrect sessionId", !session2.getSessionId().equalsIgnoreCase("-1"));
-        assertTrue("Incorrect sessionId", !session2.getSessionId().equalsIgnoreCase("0"));
-        assertThat(session2.getDeviceCapabilitiesSet(), containsInAnyOrder(
-                NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES.toArray()));
-        session3 = new NetconfSessionImpl(deviceInfo1);
-        log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session3.getSessionId());
-        assertTrue("Incorrect sessionId", !session3.getSessionId().equalsIgnoreCase("-1"));
-        assertTrue("Incorrect sessionId", !session3.getSessionId().equalsIgnoreCase("0"));
-        assertThat(session3.getDeviceCapabilitiesSet(), containsInAnyOrder(
-                NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES_1_1.toArray()));
-        session4 = new NetconfSessionImpl(deviceInfo1);
-        log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session4.getSessionId());
-        assertTrue("Incorrect sessionId", !session4.getSessionId().equalsIgnoreCase("-1"));
-        assertTrue("Incorrect sessionId", !session4.getSessionId().equalsIgnoreCase("0"));
-        assertThat(session4.getDeviceCapabilitiesSet(), containsInAnyOrder(
-                NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES_1_1.toArray()));
-    }
-
-    @AfterClass
-    public static void tearDown() throws Exception {
-        if (session1 != null) {
-            session1.close();
-        }
-        if (session2 != null) {
-            session2.close();
-        }
-        if (session3 != null) {
-            session3.close();
-        }
-        if (session4 != null) {
-            session4.close();
-        }
-
-        sshServerNetconf.stop();
-        NetconfControllerImpl.netconfConnectTimeout = NetconfControllerImpl.DEFAULT_CONNECT_TIMEOUT_SECONDS;
-        NetconfControllerImpl.netconfIdleTimeout = NetconfControllerImpl.DEFAULT_IDLE_TIMEOUT_SECONDS;
-        NetconfControllerImpl.netconfReplyTimeout = NetconfControllerImpl.DEFAULT_REPLY_TIMEOUT_SECONDS;
-    }
-
-    @Test
-    public void testEditConfigRequest() {
-        log.info("Starting edit-config async");
-        assertNotNull("Incorrect sessionId", session1.getSessionId());
-        try {
-            assertTrue("NETCONF edit-config command failed",
-                    session1.editConfig(DatastoreId.RUNNING,
-                            null, SAMPLE_REQUEST));
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF edit-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing edit-config async");
-    }
-
-    @Test
-    public void testEditConfigRequestWithChunkedFraming() {
-        log.info("Starting edit-config async");
-        assertNotNull("Incorrect sessionId", session3.getSessionId());
-        try {
-            assertTrue("NETCONF edit-config command failed",
-                    session3.editConfig(DatastoreId.RUNNING,
-                            null, SAMPLE_REQUEST));
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF edit-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing edit-config async");
-    }
-
-    @Test
-    public void testEditConfigRequestWithOnlyNewConfiguration() {
-        log.info("Starting edit-config async");
-        assertNotNull("Incorrect sessionId", session1.getSessionId());
-        try {
-            assertTrue("NETCONF edit-config command failed",
-                    session1.editConfig(NetconfSessionMinaImplTest.EDIT_CONFIG_REQUEST));
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF edit-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing edit-config async");
-    }
-
-    @Test
-    public void testEditConfigRequestWithOnlyNewConfigurationWithChunkedFraming() {
-        log.info("Starting edit-config async");
-        assertNotNull("Incorrect sessionId", session3.getSessionId());
-        try {
-            assertTrue("NETCONF edit-config command failed",
-                    session3.editConfig(NetconfSessionMinaImplTest.EDIT_CONFIG_REQUEST));
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF edit-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing edit-config async");
-    }
-
-    @Test
-    public void testDeleteConfigRequestWithRunningTargetConfiguration() {
-        log.info("Starting delete-config async");
-        assertNotNull("Incorrect sessionId", session1.getSessionId());
-        try {
-            assertFalse("NETCONF delete-config command failed",
-                    session1.deleteConfig(DatastoreId.RUNNING));
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF delete-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing delete-config async");
-    }
-
-    @Test
-    public void testDeleteConfigRequestWithRunningTargetConfigurationWithChunkedFraming() {
-        log.info("Starting delete-config async");
-        assertNotNull("Incorrect sessionId", session3.getSessionId());
-        try {
-            assertFalse("NETCONF delete-config command failed",
-                    session3.deleteConfig(DatastoreId.RUNNING));
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF delete-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing delete-config async");
-    }
-
-    @Test
-    public void testCopyConfigRequest() {
-        log.info("Starting copy-config async");
-        assertNotNull("Incorrect sessionId", session1.getSessionId());
-        try {
-            assertTrue("NETCONF copy-config command failed",
-                    session1.copyConfig(DatastoreId.RUNNING,
-                            DatastoreId.CANDIDATE));
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF copy-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing copy-config async");
-    }
-
-    @Test
-    public void testCopyConfigRequestWithChunkedFraming() {
-        log.info("Starting copy-config async");
-        assertNotNull("Incorrect sessionId", session3.getSessionId());
-        try {
-            assertTrue("NETCONF copy-config command failed",
-                    session3.copyConfig(DatastoreId.RUNNING,
-                            DatastoreId.CANDIDATE));
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF copy-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing copy-config async");
-    }
-
-    @Test
-    public void testCopyConfigXml() {
-        log.info("Starting copy-config XML async");
-        assertNotNull("Incorrect sessionId", session1.getSessionId());
-        try {
-            assertTrue("NETCONF copy-config command failed",
-                    session1.copyConfig(DatastoreId.RUNNING,
-                            "<configuration><device-specific/></configuration>"));
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF copy-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing copy-config XML async");
-    }
-
-    @Test
-    public void testCopyConfigXmlWithChunkedFraming() {
-        log.info("Starting copy-config XML async");
-        assertNotNull("Incorrect sessionId", session3.getSessionId());
-        try {
-            assertTrue("NETCONF copy-config command failed",
-                    session3.copyConfig(DatastoreId.RUNNING,
-                            "<configuration><device-specific/></configuration>"));
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF copy-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing copy-config XML async");
-    }
-
-    // remove test when ready to dump bare XML String API.
-    @Test
-    public void testCopyConfigBareXml() {
-        log.info("Starting copy-config bare XML async");
-        assertNotNull("Incorrect sessionId", session1.getSessionId());
-        try {
-            assertTrue("NETCONF copy-config command failed",
-                    session1.copyConfig(DatastoreId.RUNNING,
-                            "<config>"
-                                    + "<configuration><device-specific/></configuration>"
-                                    + "</config>"));
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF copy-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing copy-config bare XML async");
-    }
-
-    @Test
-    public void testCopyConfigBareXmlWithChunkedFraming() {
-        log.info("Starting copy-config bare XML async");
-        assertNotNull("Incorrect sessionId", session3.getSessionId());
-        try {
-            assertTrue("NETCONF copy-config command failed",
-                    session3.copyConfig(DatastoreId.RUNNING,
-                            "<config>"
-                                    + "<configuration><device-specific/></configuration>"
-                                    + "</config>"));
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF copy-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing copy-config bare XML async");
-    }
-
-    @Test
-    public void testGetConfigRequest() {
-        log.info("Starting get-config async");
-        assertNotNull("Incorrect sessionId", session1.getSessionId());
-        try {
-            assertTrue("NETCONF get-config running command failed. ",
-                    NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session1.getConfig(RUNNING,
-                            SAMPLE_REQUEST)).matches());
-
-            assertTrue("NETCONF get-config candidate command failed. ",
-                    NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session1.getConfig(CANDIDATE,
-                            SAMPLE_REQUEST)).matches());
-
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF get-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing get-config async");
-    }
-
-    @Test
-    public void testGetConfigRequestWithChunkedFraming() {
-        log.info("Starting get-config async");
-        assertNotNull("Incorrect sessionId", session3.getSessionId());
-        try {
-            assertTrue("NETCONF get-config running command failed. ",
-                    NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session3.getConfig(RUNNING,
-                            SAMPLE_REQUEST)).matches());
-
-            assertTrue("NETCONF get-config candidate command failed. ",
-                    NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session3.getConfig(CANDIDATE,
-                            SAMPLE_REQUEST)).matches());
-
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF get-config test failed: " + e.getMessage());
-        }
-        log.info("Finishing get-config async");
-    }
-
-    @Test
-    public void testGetRequest() {
-        log.info("Starting get async");
-        assertNotNull("Incorrect sessionId", session1.getSessionId());
-        try {
-            assertTrue("NETCONF get running command failed. ",
-                    NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session1.get(SAMPLE_REQUEST,
-                            null)).matches());
-
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF get test failed: " + e.getMessage());
-        }
-        log.info("Finishing get async");
-    }
-
-    @Test
-    public void testGetRequestWithChunkedFraming() {
-        log.info("Starting get async");
-        assertNotNull("Incorrect sessionId", session3.getSessionId());
-        try {
-            assertTrue("NETCONF get running command failed. ",
-                    NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session3.get(SAMPLE_REQUEST, null)).matches());
-
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF get test failed: " + e.getMessage());
-        }
-        log.info("Finishing get async");
-    }
-
-    @Test
-    public void testLockRequest() {
-        log.info("Starting lock async");
-        assertNotNull("Incorrect sessionId", session1.getSessionId());
-        try {
-            assertTrue("NETCONF lock request failed", session1.lock());
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF lock test failed: " + e.getMessage());
-        }
-        log.info("Finishing lock async");
-    }
-
-    @Test
-    public void testLockRequestWithChunkedFraming() {
-        log.info("Starting lock async");
-        assertNotNull("Incorrect sessionId", session3.getSessionId());
-        try {
-            assertTrue("NETCONF lock request failed", session3.lock());
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF lock test failed: " + e.getMessage());
-        }
-        log.info("Finishing lock async");
-    }
-
-    @Test
-    public void testUnLockRequest() {
-        log.info("Starting unlock async");
-        assertNotNull("Incorrect sessionId", session1.getSessionId());
-        try {
-            assertTrue("NETCONF unlock request failed", session1.unlock());
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF unlock test failed: " + e.getMessage());
-        }
-        log.info("Finishing unlock async");
-    }
-
-    @Test
-    public void testUnLockRequestWithChunkedFraming() {
-        log.info("Starting unlock async");
-        assertNotNull("Incorrect sessionId", session3.getSessionId());
-        try {
-            assertTrue("NETCONF unlock request failed", session3.unlock());
-        } catch (NetconfException e) {
-            e.printStackTrace();
-            fail("NETCONF unlock test failed: " + e.getMessage());
-        }
-        log.info("Finishing unlock async");
-    }
-
-
-    @Test
-    public void testConcurrentSameSessionAccess() throws InterruptedException {
-        NCCopyConfigCallable testCopyConfig1 = new NCCopyConfigCallable(session1, RUNNING, "candidate");
-        NCCopyConfigCallable testCopyConfig2 = new NCCopyConfigCallable(session1, RUNNING, "startup");
-
-        FutureTask<Boolean> futureCopyConfig1 = new FutureTask<>(testCopyConfig1);
-        FutureTask<Boolean> futureCopyConfig2 = new FutureTask<>(testCopyConfig2);
-
-        ExecutorService executor = Executors.newFixedThreadPool(2);
-        log.info("Starting concurrent execution of copy-config through same session");
-        executor.execute(futureCopyConfig1);
-        executor.execute(futureCopyConfig2);
-
-        int count = 0;
-        while (count < 10) {
-            if (futureCopyConfig1.isDone() && futureCopyConfig2.isDone()) {
-                executor.shutdown();
-                log.info("Finished concurrent same session execution");
-                return;
-            }
-            Thread.sleep(100L);
-            count++;
-        }
-        fail("NETCONF test failed to complete.");
-    }
-
-    @Test
-    public void testConcurrentSameSessionAccessWithChunkedFraming() throws InterruptedException {
-        NCCopyConfigCallable testCopyConfig1 = new NCCopyConfigCallable(session3, RUNNING, "candidate");
-        NCCopyConfigCallable testCopyConfig2 = new NCCopyConfigCallable(session3, RUNNING, "startup");
-
-        FutureTask<Boolean> futureCopyConfig1 = new FutureTask<>(testCopyConfig1);
-        FutureTask<Boolean> futureCopyConfig2 = new FutureTask<>(testCopyConfig2);
-
-        ExecutorService executor = Executors.newFixedThreadPool(2);
-        log.info("Starting concurrent execution of copy-config through same session");
-        executor.execute(futureCopyConfig1);
-        executor.execute(futureCopyConfig2);
-
-        int count = 0;
-        while (count < 10) {
-            if (futureCopyConfig1.isDone() && futureCopyConfig2.isDone()) {
-                executor.shutdown();
-                log.info("Finished concurrent same session execution");
-                return;
-            }
-            Thread.sleep(100L);
-            count++;
-        }
-        fail("NETCONF test failed to complete.");
-    }
-
-    @Test
-    public void test2SessionAccess() throws InterruptedException {
-        NCCopyConfigCallable testCopySession1 = new NCCopyConfigCallable(session1, RUNNING, "candidate");
-        NCCopyConfigCallable testCopySession2 = new NCCopyConfigCallable(session2, RUNNING, "candidate");
-
-        FutureTask<Boolean> futureCopySession1 = new FutureTask<>(testCopySession1);
-        FutureTask<Boolean> futureCopySession2 = new FutureTask<>(testCopySession2);
-
-        ExecutorService executor = Executors.newFixedThreadPool(2);
-        log.info("Starting concurrent execution of copy-config through 2 different sessions");
-        executor.execute(futureCopySession1);
-        executor.execute(futureCopySession2);
-
-        int count = 0;
-        while (count < 10) {
-            if (futureCopySession1.isDone() && futureCopySession2.isDone()) {
-                executor.shutdown();
-                log.info("Finished concurrent 2 session execution");
-                return;
-            }
-            Thread.sleep(100L);
-            count++;
-        }
-        fail("NETCONF test failed to complete.");
-    }
-
-    @Test
-    public void test2SessionAccessWithChunkedFraming() throws InterruptedException {
-        NCCopyConfigCallable testCopySession1 = new NCCopyConfigCallable(session3, RUNNING, "candidate");
-        NCCopyConfigCallable testCopySession2 = new NCCopyConfigCallable(session4, RUNNING, "candidate");
-
-        FutureTask<Boolean> futureCopySession1 = new FutureTask<>(testCopySession1);
-        FutureTask<Boolean> futureCopySession2 = new FutureTask<>(testCopySession2);
-
-        ExecutorService executor = Executors.newFixedThreadPool(2);
-        log.info("Starting concurrent execution of copy-config through 2 different sessions");
-        executor.execute(futureCopySession1);
-        executor.execute(futureCopySession2);
-
-        int count = 0;
-        while (count < 10) {
-            if (futureCopySession1.isDone() && futureCopySession2.isDone()) {
-                executor.shutdown();
-                log.info("Finished concurrent 2 session execution");
-                return;
-            }
-            Thread.sleep(100L);
-            count++;
-        }
-        fail("NETCONF test failed to complete.");
-    }
-
-    @Test
-    public void testSessionTimeouts() {
-        assertTrue("SSH Client wrong", session1 instanceof NetconfSessionImpl);
-        assertEquals("Timeout wrong", 5, session1.timeoutConnectSec());
-        assertEquals("Timeout wrong", 5, session1.timeoutReplySec());
-        assertEquals("Timeout wrong", 5, session1.timeoutIdleSec());
-
-        assertTrue("SSH Client wrong", session2 instanceof NetconfSessionMinaImpl);
-        assertEquals("Timeout wrong", 11, session2.timeoutConnectSec());
-        assertEquals("Timeout wrong", 10, session2.timeoutReplySec());
-        assertEquals("Timeout wrong", 12, session2.timeoutIdleSec());
-    }
-
-    public static String getTestHelloReply(Optional<Long> sessionId, boolean useChunkedFraming) {
-        if (useChunkedFraming) {
-            return getTestHelloReply(NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES_1_1, sessionId);
-        } else {
-            return getTestHelloReply(NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES, sessionId);
-        }
-    }
-
-    public static String getTestHelloReply(Collection<String> capabilities, Optional<Long> sessionId) {
-        StringBuffer sb = new StringBuffer();
-
-        sb.append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">");
-        sb.append("<capabilities>");
-        capabilities.forEach(capability -> {
-            sb.append("<capability>").append(capability).append("</capability>");
-        });
-        sb.append("</capabilities>");
-        if (sessionId.isPresent()) {
-            sb.append("<session-id>");
-            sb.append(sessionId.get().toString());
-            sb.append("</session-id>");
-        }
-        sb.append("</hello>");
-
-        return sb.toString();
-    }
-
-    public static String getOkReply(Optional<Integer> messageId) {
-        StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-        sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
-        if (messageId.isPresent()) {
-            sb.append("message-id=\"");
-            sb.append(String.valueOf(messageId.get()));
-            sb.append("\">");
-        }
-        sb.append("<ok/>");
-        sb.append("</rpc-reply>");
-        return sb.toString();
-    }
-
-    public static String getGetReply(Optional<Integer> messageId) {
-        StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-        sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
-        if (messageId.isPresent()) {
-            sb.append("message-id=\"");
-            sb.append(String.valueOf(messageId.get()));
-            sb.append("\">");
-        }
-        sb.append("<data>\n");
-        sb.append(SAMPLE_REQUEST);
-        sb.append("</data>\n");
-        sb.append("</rpc-reply>");
-        return sb.toString();
-    }
-
-    public static final Pattern HELLO_REQ_PATTERN =
-            Pattern.compile("(<\\?xml).*"
-                            + "(<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
-                            + "( *)(<capabilities>)\\R?"
-                            + "( *)(<capability>urn:ietf:params:netconf:base:1.0</capability>)\\R?"
-                            + "( *)(</capabilities>)\\R?"
-                            + "(</hello>)\\R? *",
-                    Pattern.DOTALL);
-
-    public static final Pattern HELLO_REQ_PATTERN_1_1 =
-            Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
-                            + "(<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
-                            + "( *)(<capabilities>)\\R?"
-                            + "( *)(<capability>urn:ietf:params:netconf:base:1.0</capability>)\\R?"
-                            + "( *)(<capability>urn:ietf:params:netconf:base:1.1</capability>)\\R?"
-                            + "( *)(</capabilities>)\\R?"
-                            + "(</hello>)\\R? *",
-                    Pattern.DOTALL);
-
-    public static final Pattern EDIT_CONFIG_REQ_PATTERN =
-            Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
-                    + "(<rpc message-id=\")[0-9]*(\") *(xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
-                    + "(<edit-config>)\\R?"
-                    + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
-                    + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
-                    + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
-                    + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
-                    + ".*"
-                    + "(</config>)\\R?(</edit-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
-
-
-    public static final Pattern LOCK_REQ_PATTERN =
-            Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
-                    + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
-                    + "message-id=\")[0-9]*(\">)\\R?"
-                    + "(<lock>)\\R?"
-                    + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
-                    + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
-                    + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
-                    + "(</lock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
-
-    public static final Pattern UNLOCK_REQ_PATTERN =
-            Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
-                    + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
-                    + "message-id=\")[0-9]*(\">)\\R?"
-                    + "(<unlock>)\\R?"
-                    + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
-                    + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
-                    + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
-                    + "(</unlock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
-
-    public static final Pattern COPY_CONFIG_REQ_PATTERN =
-            Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
-                    + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\")[0-9]*(\">)\\R?"
-                    + "(<copy-config>)\\R?"
-                    + "(<target>\\R?"
-                    + "("
-                    + "(<" + DatastoreId.CANDIDATE.toString() + "/>)|"
-                    + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
-                    + "(<" + DatastoreId.STARTUP.toString() + "/>)"
-                    + ")\\R?"
-                    + "</target>)\\R?"
-                    + "(<source>)\\R?"
-                    + "("
-                    + "(<config>)(.*)(</config>)|"
-                    + "(<" + DatastoreId.CANDIDATE.toString() + "/>)|"
-                    + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
-                    + "(<" + DatastoreId.STARTUP.toString() + "/>)"
-                    + ")\\R?"
-                    + "(</source>)\\R?"
-                    + "(</copy-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
-
-    public static final Pattern GET_CONFIG_REQ_PATTERN =
-            Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
-                    + "(<rpc message-id=\")[0-9]*(\"  xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
-                    + "(<get-config>)\\R?" + "(<source>)\\R?((<"
-                    + DatastoreId.CANDIDATE.toString()
-                    + "/>)|(<" + DatastoreId.RUNNING.toString()
-                    + "/>)|(<" + DatastoreId.STARTUP.toString()
-                    + "/>))\\R?(</source>)\\R?"
-                    + "(<filter type=\"subtree\">).*(</filter>)\\R?"
-                    + "(</get-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
-
-
-
-    public static final Pattern GET_REQ_PATTERN =
-            Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
-                    + "(<rpc message-id=\")[0-9]*(\"  xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
-                    + "(<get>)\\R?"
-                    + "(<filter type=\"subtree\">).*(</filter>)\\R?"
-                    + "(</get>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
-
-    public class NCCopyConfigCallable implements Callable<Boolean> {
-        private NetconfSession session;
-        private DatastoreId target;
-        private String source;
-
-        public NCCopyConfigCallable(NetconfSession session, DatastoreId target, String source) {
-            this.session = session;
-            this.target = target;
-            this.source = source;
-        }
-
-        @Override
-        public Boolean call() throws Exception {
-            return session.copyConfig(target, source);
-        }
-    }
-}
diff --git a/protocols/netconf/ctl/src/test/java/org/onosproject/netconf/ctl/impl/NetconfSshdTestSubsystem.java b/protocols/netconf/ctl/src/test/java/org/onosproject/netconf/ctl/impl/NetconfSshdTestSubsystem.java
index 27e4247..be0c916 100644
--- a/protocols/netconf/ctl/src/test/java/org/onosproject/netconf/ctl/impl/NetconfSshdTestSubsystem.java
+++ b/protocols/netconf/ctl/src/test/java/org/onosproject/netconf/ctl/impl/NetconfSshdTestSubsystem.java
@@ -30,6 +30,7 @@
 import java.util.Optional;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
+import java.util.regex.Pattern;
 
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.sshd.common.NamedFactory;
@@ -39,6 +40,7 @@
 import org.apache.sshd.server.ExitCallback;
 import org.apache.sshd.server.SessionAware;
 import org.apache.sshd.server.session.ServerSession;
+import org.onosproject.netconf.DatastoreId;
 import org.onosproject.netconf.ctl.impl.NetconfStreamThread.NetconfMessageState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -71,7 +73,7 @@
          *                        <B>Note:</B> the service will <U>not</U> be shutdown when the
          *                        subsystem is closed - unless it is the ad-hoc service, which will be
          *                        shutdown regardless
-         * @see Factory(ExecutorService, boolean)}
+         * @see #Factory(ExecutorService, boolean)
          */
         public Factory(ExecutorService executorService) {
             this(executorService, false);
@@ -133,6 +135,92 @@
     private NetconfMessageState state;
     private PrintWriter outputStream;
 
+    private static final String SAMPLE_REQUEST =
+    "<some-yang-element xmlns=\"some-namespace\">"
+            + "<some-child-element/>"
+            + "</some-yang-element>";
+    public static final Pattern GET_REQ_PATTERN =
+    Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
+            + "(<rpc message-id=\")[0-9]*(\"  xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
+            + "(<get>)\\R?"
+            + "(<filter type=\"subtree\">).*(</filter>)\\R?"
+            + "(</get>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
+    public static final Pattern GET_CONFIG_REQ_PATTERN =
+    Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
+            + "(<rpc message-id=\")[0-9]*(\"  xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
+            + "(<get-config>)\\R?" + "(<source>)\\R?((<"
+            + DatastoreId.CANDIDATE.toString()
+            + "/>)|(<" + DatastoreId.RUNNING.toString()
+            + "/>)|(<" + DatastoreId.STARTUP.toString()
+            + "/>))\\R?(</source>)\\R?"
+            + "(<filter type=\"subtree\">).*(</filter>)\\R?"
+            + "(</get-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
+    public static final Pattern COPY_CONFIG_REQ_PATTERN =
+    Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
+            + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\")[0-9]*(\">)\\R?"
+            + "(<copy-config>)\\R?"
+            + "(<target>\\R?"
+            + "("
+            + "(<" + DatastoreId.CANDIDATE.toString() + "/>)|"
+            + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
+            + "(<" + DatastoreId.STARTUP.toString() + "/>)"
+            + ")\\R?"
+            + "</target>)\\R?"
+            + "(<source>)\\R?"
+            + "("
+            + "(<config>)(.*)(</config>)|"
+            + "(<" + DatastoreId.CANDIDATE.toString() + "/>)|"
+            + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
+            + "(<" + DatastoreId.STARTUP.toString() + "/>)"
+            + ")\\R?"
+            + "(</source>)\\R?"
+            + "(</copy-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
+    public static final Pattern UNLOCK_REQ_PATTERN =
+    Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
+            + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
+            + "message-id=\")[0-9]*(\">)\\R?"
+            + "(<unlock>)\\R?"
+            + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
+            + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
+            + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
+            + "(</unlock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
+    public static final Pattern LOCK_REQ_PATTERN =
+    Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
+            + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
+            + "message-id=\")[0-9]*(\">)\\R?"
+            + "(<lock>)\\R?"
+            + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
+            + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
+            + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
+            + "(</lock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
+    public static final Pattern EDIT_CONFIG_REQ_PATTERN =
+    Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
+            + "(<rpc message-id=\")[0-9]*(\") *(xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
+            + "(<edit-config>)\\R?"
+            + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
+            + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
+            + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
+            + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
+            + ".*"
+            + "(</config>)\\R?(</edit-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
+    public static final Pattern HELLO_REQ_PATTERN_1_1 =
+    Pattern.compile("(<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>)\\R?"
+                    + "(<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
+                    + "( *)(<capabilities>)\\R?"
+                    + "( *)(<capability>urn:ietf:params:netconf:base:1.0</capability>)\\R?"
+                    + "( *)(<capability>urn:ietf:params:netconf:base:1.1</capability>)\\R?"
+                    + "( *)(</capabilities>)\\R?"
+                    + "(</hello>)\\R? *",
+            Pattern.DOTALL);
+    public static final Pattern HELLO_REQ_PATTERN =
+    Pattern.compile("(<\\?xml).*"
+                    + "(<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
+                    + "( *)(<capabilities>)\\R?"
+                    + "( *)(<capability>urn:ietf:params:netconf:base:1.0</capability>)\\R?"
+                    + "( *)(</capabilities>)\\R?"
+                    + "(</hello>)\\R? *",
+            Pattern.DOTALL);
+
     public NetconfSshdTestSubsystem() {
         this(null);
     }
@@ -200,25 +288,25 @@
                                 session.getSessionId(), messageId, deviceRequest);
                         synchronized (outputStream) {
 
-                            if (NetconfSessionImplTest.HELLO_REQ_PATTERN.matcher(deviceRequest).matches()) {
+                            if (HELLO_REQ_PATTERN.matcher(deviceRequest).matches()) {
 
                                 String helloReply =
-                                        NetconfSessionImplTest.getTestHelloReply(Optional.of(ByteBuffer.wrap(
+                                        getTestHelloReply(Optional.of(ByteBuffer.wrap(
                                                 session.getSessionId()).asLongBuffer().get()), false);
                                 outputStream.write(helloReply + END_PATTERN);
                                 outputStream.flush();
-                            } else if (NetconfSessionImplTest.HELLO_REQ_PATTERN_1_1.matcher(deviceRequest).matches()) {
+                            } else if (HELLO_REQ_PATTERN_1_1.matcher(deviceRequest).matches()) {
 
                                 String helloReply =
-                                        NetconfSessionImplTest.getTestHelloReply(Optional.of(ByteBuffer.wrap(
+                                        getTestHelloReply(Optional.of(ByteBuffer.wrap(
                                                 session.getSessionId()).asLongBuffer().get()), true);
                                 outputStream.write(helloReply + END_PATTERN);
                                 outputStream.flush();
                             } else {
-                                Pair replyClosedPair = dealWithRequest(deviceRequest, messageId);
-                                String reply = (String) replyClosedPair.getLeft();
+                                Pair<String, Boolean> replyClosedPair = dealWithRequest(deviceRequest, messageId);
+                                String reply = replyClosedPair.getLeft();
                                 if (reply != null) {
-                                    Boolean newSockedClosed = (Boolean) replyClosedPair.getRight();
+                                    Boolean newSockedClosed = replyClosedPair.getRight();
                                     socketClosed = newSockedClosed.booleanValue();
                                     outputStream.write(reply + END_PATTERN);
                                     outputStream.flush();
@@ -241,17 +329,17 @@
 
                         synchronized (outputStream) {
 
-                            if (NetconfSessionImplTest.HELLO_REQ_PATTERN.matcher(deviceRequest).matches()) {
+                            if (HELLO_REQ_PATTERN.matcher(deviceRequest).matches()) {
                                 String helloReply =
-                                        NetconfSessionImplTest.getTestHelloReply(Optional.of(ByteBuffer.wrap(
+                                        getTestHelloReply(Optional.of(ByteBuffer.wrap(
                                                 session.getSessionId()).asLongBuffer().get()), true);
                                 outputStream.write(helloReply + END_PATTERN);
                                 outputStream.flush();
                             } else {
-                                Pair replyClosedPair = dealWithRequest(deviceRequest, messageId);
-                                String reply = (String) replyClosedPair.getLeft();
+                                Pair<String, Boolean> replyClosedPair = dealWithRequest(deviceRequest, messageId);
+                                String reply = replyClosedPair.getLeft();
                                 if (reply != null) {
-                                    Boolean newSockedClosed = (Boolean) replyClosedPair.getRight();
+                                    Boolean newSockedClosed = replyClosedPair.getRight();
                                     socketClosed = newSockedClosed.booleanValue();
                                     outputStream.write(formatChunkedMessage(reply));
                                     outputStream.flush();
@@ -307,17 +395,17 @@
     }
 
     private Pair<String, Boolean> dealWithRequest(String deviceRequest, Optional<Integer> messageId) {
-        if (NetconfSessionImplTest.EDIT_CONFIG_REQ_PATTERN.matcher(deviceRequest).matches()
-                || NetconfSessionImplTest.COPY_CONFIG_REQ_PATTERN.matcher(deviceRequest).matches()
-                || NetconfSessionImplTest.LOCK_REQ_PATTERN.matcher(deviceRequest).matches()
-                || NetconfSessionImplTest.UNLOCK_REQ_PATTERN.matcher(deviceRequest).matches()) {
-            return Pair.of(NetconfSessionImplTest.getOkReply(messageId), false);
+        if (EDIT_CONFIG_REQ_PATTERN.matcher(deviceRequest).matches()
+                || COPY_CONFIG_REQ_PATTERN.matcher(deviceRequest).matches()
+                || LOCK_REQ_PATTERN.matcher(deviceRequest).matches()
+                || UNLOCK_REQ_PATTERN.matcher(deviceRequest).matches()) {
+            return Pair.of(getOkReply(messageId), false);
 
-        } else if (NetconfSessionImplTest.GET_CONFIG_REQ_PATTERN.matcher(deviceRequest).matches()
-                || NetconfSessionImplTest.GET_REQ_PATTERN.matcher(deviceRequest).matches()) {
-            return Pair.of(NetconfSessionImplTest.getGetReply(messageId), false);
+        } else if (GET_CONFIG_REQ_PATTERN.matcher(deviceRequest).matches()
+                || GET_REQ_PATTERN.matcher(deviceRequest).matches()) {
+            return Pair.of(getGetReply(messageId), false);
         } else if (deviceRequest.contains(CLOSE_SESSION)) {
-            return Pair.of(NetconfSessionImplTest.getOkReply(messageId), true);
+            return Pair.of(getOkReply(messageId), true);
         } else {
             log.error("Unexpected NETCONF message structure on session {} : {}",
                     ByteBuffer.wrap(
@@ -415,4 +503,59 @@
     protected void process(Buffer buffer) throws IOException {
         log.warn("Receieved buffer:" + buffer);
     }
-}
\ No newline at end of file
+
+    public static String getTestHelloReply(Collection<String> capabilities, Optional<Long> sessionId) {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">");
+        sb.append("<capabilities>");
+        capabilities.forEach(capability -> {
+            sb.append("<capability>").append(capability).append("</capability>");
+        });
+        sb.append("</capabilities>");
+        if (sessionId.isPresent()) {
+            sb.append("<session-id>");
+            sb.append(sessionId.get().toString());
+            sb.append("</session-id>");
+        }
+        sb.append("</hello>");
+
+        return sb.toString();
+    }
+
+    public static String getTestHelloReply(Optional<Long> sessionId, boolean useChunkedFraming) {
+        if (useChunkedFraming) {
+            return getTestHelloReply(NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES_1_1, sessionId);
+        } else {
+            return getTestHelloReply(NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES, sessionId);
+        }
+    }
+
+    public static String getGetReply(Optional<Integer> messageId) {
+        StringBuilder sb = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+        sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
+        if (messageId.isPresent()) {
+            sb.append("message-id=\"");
+            sb.append(String.valueOf(messageId.get()));
+            sb.append("\">");
+        }
+        sb.append("<data>\n");
+        sb.append(SAMPLE_REQUEST);
+        sb.append("</data>\n");
+        sb.append("</rpc-reply>");
+        return sb.toString();
+    }
+
+    public static String getOkReply(Optional<Integer> messageId) {
+        StringBuilder sb = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+        sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
+        if (messageId.isPresent()) {
+            sb.append("message-id=\"");
+            sb.append(String.valueOf(messageId.get()));
+            sb.append("\">");
+        }
+        sb.append("<ok/>");
+        sb.append("</rpc-reply>");
+        return sb.toString();
+    }
+}
