/// <summary>
        /// Bind RPC server.
        /// </summary>
        /// <param name="swnClient">SWN rpc client</param>
        /// <param name="networkAddress">RPC network address</param>
        /// <param name="domainName">Domain name</param>
        /// <param name="userName">User name</param>
        /// <param name="password">Password</param>
        /// <param name="securityPackage">Security package</param>
        /// <param name="authLevel">Authentication level</param>
        /// <param name="timeout">Timeout</param>
        /// <param name="serverComputerName">ServerComputerName</param>
        /// <returns>Return true if success, otherwise return false</returns>
        public static bool BindServer(SwnClient swnClient, IPAddress networkAddress, string domainName, string userName, string password,
            SecurityPackageType securityPackage, RpceAuthenticationLevel authLevel, TimeSpan timeout,string serverComputerName = null)
        {
            AccountCredential accountCredential = new AccountCredential(domainName, userName, password);
            string cifsServicePrincipalName = string.Empty;
            if (!string.IsNullOrEmpty(serverComputerName))
            {
                cifsServicePrincipalName = "cifs/" + serverComputerName;
            }
            else
            {
                IPHostEntry hostEntry = null;
                try
                {
                    hostEntry = Dns.GetHostEntry(networkAddress);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Failed to resolve network address {0} with exception: {1}", networkAddress.ToString(), ex.Message));
                }

                if (hostEntry != null && !string.IsNullOrEmpty(hostEntry.HostName))
                {
                    cifsServicePrincipalName = "cifs/" + hostEntry.HostName;
                }
                else
                {
                    throw new Exception("Failed to get HostName from network address " + networkAddress.ToString());
                }
            }
            ClientSecurityContext securityContext =
                new SspiClientSecurityContext(
                    securityPackage,
                    accountCredential,
                    cifsServicePrincipalName,
                    ClientSecurityContextAttribute.Connection
                        | ClientSecurityContextAttribute.DceStyle
                        | ClientSecurityContextAttribute.Integrity
                        | ClientSecurityContextAttribute.ReplayDetect
                        | ClientSecurityContextAttribute.SequenceDetect
                        | ClientSecurityContextAttribute.UseSessionKey,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

            try
            {
                //Bind
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Start to Bind RPC to {0}.", networkAddress.ToString());
                swnClient.SwnBind(networkAddress.ToString(), accountCredential, securityContext, authLevel, timeout);
            }
            catch (Exception ex)
            {
                BaseTestSite.Log.Add(LogEntryKind.Debug,
                    "Bind server {0} failed. Exception: {1}",
                    networkAddress.ToString(),
                    ex.Message);
                swnClient.SwnUnbind(timeout);
                return false;
            }

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Bind server {0} successfully.", networkAddress.ToString());
            return true;
        }
        static void Main(string[] args)
        {
            SwnClient client = new SwnClient();
            string serverName = "GeneralFS";
            string serverAddr = "192.168.1.200";
            string resourceName = "GeneralFS";
            string clientName = Guid.NewGuid().ToString();

            int retVar = 0;
            TimeSpan timeOut = new TimeSpan(0, 0, 10);
            AccountCredential accountCredential = new AccountCredential("contoso.com", "Administrator", "Password01!");
            NlmpClientCredential nlmpCredential = new NlmpClientCredential(serverName, "contoso.com", "Administrator", "Password01!");
            ClientSecurityContext securityContext = new NlmpClientSecurityContext(nlmpCredential);

            //Bind to server
            client.SwnBind(serverName, accountCredential, securityContext,
                RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, timeOut);

            //Get interface list
            WITNESS_INTERFACE_LIST interfaceList;
            try
            {
                retVar = client.WitnessGetInterfaceList(out interfaceList);
                Console.WriteLine("Call WitnessGetInterfaceList: " + retVar);
            }
            catch (TimeoutException)
            {
                client.SwnUnbind(timeOut);
                return;
            }

            string swnServerName = "";

            foreach (var info in interfaceList.InterfaceInfo)
            {
                if ((info.Flags & (uint)SwnNodeFlagsValue.INTERFACE_WITNESS) != 0)
                {
                    if ((info.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0)
                    {
                        swnServerName = (new IPAddress(info.IPV4)).ToString();
                    }
                    else if ((info.Flags & (uint)SwnNodeFlagsValue.IPv6) != 0)
                    {
                        byte[] ipv6 = new byte[16];
                        Buffer.BlockCopy(info.IPV6, 0, ipv6, 0, 16);
                        swnServerName = (new IPAddress(ipv6)).ToString();
                    }
                    else
                    {
                        throw new ArgumentException();
                    }
                    break;
                }
            }

            SwnClient client2 = new SwnClient();
            client2.SwnBind(swnServerName, accountCredential, securityContext,
                RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, timeOut);

            //Registration
            IntPtr pContext;
            retVar = client2.WitnessRegister(SwnVersion.SWN_VERSION_1, resourceName, serverAddr, clientName, out pContext);
            Console.WriteLine("Call WitnessRegister: " + retVar);

            uint callId = 0;
            try
            {
                RESP_ASYNC_NOTIFY respNotify;
                callId = client2.WitnessAsyncNotify(pContext);
                Console.WriteLine("Call WitnessAsyncNotify: " + callId);

                retVar = client2.WitnessAsyncNotifyExpect(callId, out respNotify);
                Console.WriteLine("Call WitnessAsyncNotify: " + retVar);
                Console.WriteLine("NumberOfMessages: " + respNotify.NumberOfMessages);
                Console.WriteLine("Length: " + respNotify.Length);
                PrintNotification(respNotify);

                callId = client2.WitnessAsyncNotify(pContext);
                Console.WriteLine("Call WitnessAsyncNotify: " + callId);

                retVar = client2.WitnessAsyncNotifyExpect(callId, out respNotify);
                Console.WriteLine("Call WitnessAsyncNotify: " + retVar);
                Console.WriteLine("NumberOfMessages: " + respNotify.NumberOfMessages);
                Console.WriteLine("Length: " + respNotify.Length);
                PrintNotification(respNotify);
            }
            catch (TimeoutException)
            {
                Console.WriteLine("Throw a TimeoutException.");
            }

            //UnRegistration
            retVar = client2.WitnessUnRegister(pContext);
            Console.WriteLine("Call WitnessUnRegister: " + retVar);

            client2.SwnUnbind(timeOut);
            client.SwnUnbind(timeOut);

            Console.ReadKey();
        }