Remove deprecated NetconfSessionImpl

Change-Id: I92d9407ff4bc0c25ca7b998cc4f387c3f40f9ace
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();
+    }
+}