public static void Main(string[] args)
        {
            // http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

            // https://alesaudate.wordpress.com/2010/08/09/how-to-dynamically-select-a-certificate-alias-when-invoking-web-services/

            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201510/20151010

            try
            {
                // first lets print into console the aliases we could be choosing from
                // it should show the CA and the host alias on windows.
                // once this works. lets do an example that works with JVM keystore



                #region Certificates
                Func<string, IEnumerable<System.Security.Cryptography.X509Certificates.X509Certificate2>> Certificates = keyStoreType =>
                {
                    var a = new List<System.Security.Cryptography.X509Certificates.X509Certificate2> { };

                    try
                    {
                        // http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b27/sun/security/mscapi/SunMSCAPI.java

                        // https://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html

                        // https://social.msdn.microsoft.com/Forums/expression/en-US/52dca221-1e05-44c1-8c45-9e0d4a807853/java-keystoreload-for-windowsmy-pops-up-insert-smart-card-window?forum=windowssecurity
                        // I removed some personal certificaties at key manager (certmgr.msc) and wala!

                        //Client Authentication (1.3.6.1.5.5.7.3.2)
                        //Secure Email (1.3.6.1.5.5.7.3.4)


                        // https://www.chilkatsoft.com/p/p_280.asp
                        // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider\Microsoft Base Smart Card Crypto Provider

                        // http://stackoverflow.com/questions/27692904/how-to-avoid-smart-card-selection-popup-when-accessing-windows-my-using-java

                        // http://stackoverflow.com/questions/4552100/how-to-prevent-popups-when-loading-a-keystore
                        // http://stackoverflow.com/questions/15220976/how-to-obtain-a-users-identity-from-a-smartcard-on-windows-mscapi-with-java

                        KeyStore xKeyStore = KeyStore.getInstance(keyStoreType);
                        //Console.WriteLine(new { xKeyStore });
                        //Console.WriteLine("load... " + new { keyStoreType });
                        xKeyStore.load(null, null);
                        //Console.WriteLine("load... done");
                        //Console.WriteLine("aliases...");
                        java.util.Enumeration en = xKeyStore.aliases();
                        //Console.WriteLine("aliases... done");

                        while (en.hasMoreElements())
                        {
                            var aliasKey = (string)en.nextElement();

                            //Console.WriteLine(new { aliasKey });

                            // PCSC?
                            var c509 = xKeyStore.getCertificate(aliasKey) as java.security.cert.X509Certificate;
                            if (c509 != null)
                            {
                                System.Security.Cryptography.X509Certificates.X509Certificate2 crt = new __X509Certificate2 { FriendlyName = aliasKey, InternalElement = c509 };

                                //Console.WriteLine(new { crt.Subject, crt.SerialNumber, SimpleName = crt.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, false) });
                                //Console.WriteLine(new { aliasKey, crt.SerialNumber, SimpleName = crt.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, false), crt.Issuer });

                                a.Add(crt);

                            }
                            //if (aliasKey.equals("myKey") ) {
                            //      PrivateKey key = (PrivateKey)ks.getKey(aliasKey, "monPassword".toCharArray());
                            //      Certificate[] chain = ks.getCertificateChain(aliasKey);
                            //}
                        }

                    }
                    catch //(Exception closure)
                    {
                        throw;
                    }

                    return a;
                };
                #endregion




                Certificates("Windows-ROOT").WithEach(
                    crt =>
                    {
                        // aliasKey = peer integrity authority for cpu BFEBFBFF000306A9
                        // SimpleName = peer integrity authority for cpu BFEBFBFF000306A9
                        var SimpleName = crt.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, false);

                        if (SimpleName.StartsWith("peer integrity authority for cpu"))
                            Console.WriteLine(new { crt.FriendlyName, SimpleName, crt.SerialNumber, crt.Issuer });
                    }
                );




                Certificates("Windows-MY").GroupBy(x => x.FriendlyName).WithEach(
                    crt =>
                    {
                        //{ FriendlyName = 192.168.1.12 }

                        //{ FriendlyName = 192.168.43.12 }
                        //{ FriendlyName = 192.168.173.12 }
                        //{ FriendlyName = 192.168.42.46 }
                        //{ FriendlyName = Administrator }


                        // hide non ip certs..
                        if (!crt.Key.Contains("."))
                            return;

                        Console.WriteLine(new { FriendlyName = crt.Key });

                        //Console.WriteLine(new { crt.FriendlyName, crt.SerialNumber });
                    }
                );

                Console.WriteLine("-");

                // now lets start a ssl server and convince jvm to use the first friendly name we found..

                var xSSLContext = javax.net.ssl.SSLContext.getInstance("TLSv1.2");
                Console.WriteLine(new { xSSLContext });
                var xTrustEveryoneManager = new[] { new TrustEveryoneManager() };
                var xKeyManager = new[] { new localKeyManager() };

                xSSLContext.init(
                    // SunMSCAPI ?
                    xKeyManager,
                    xTrustEveryoneManager,
                    new java.security.SecureRandom()
                );

                var xSSLServerSocketFactory = xSSLContext.getServerSocketFactory();
                var ss443 = xSSLServerSocketFactory.createServerSocket(8443);
                Console.WriteLine(new { ss443 });

                // http://developer.android.com/reference/javax/net/ssl/SSLServerSocket.html
                var xSSLServerSocket = ss443 as javax.net.ssl.SSLServerSocket;
                xSSLServerSocket.setEnabledProtocols(new[] { "TLSv1.2", "SSLv2Hello" });


                var ok = true;
                while (ok)
                {
                    //Console.WriteLine("accept...");
                    var xSSLSocket = ss443.accept() as javax.net.ssl.SSLSocket;




                    //Console.WriteLine(new { xSSLSocket });

                    // http://security.stackexchange.com/questions/76993/now-that-it-is-2015-what-ssl-tls-cipher-suites-should-be-used-in-a-high-securit
                    // java u suck.

                    //Console.WriteLine("startHandshake...");
                    try
                    {
                        // http://developer.android.com/reference/javax/net/ssl/HandshakeCompletedEvent.html

                        Func<string> getdata = () =>
                             "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n<h1>hello world</h1>";

                        // can we await for it?
                        xSSLSocket.addHandshakeCompletedListener(
                            new xHandshakeCompletedListener
                            {
                                yield = e =>
                                {
                                    try
                                    {
                                        Console.WriteLine("xHandshakeCompletedListener " + new { e.getPeerCertificates().Length });

                                        var c = e.getPeerCertificates().FirstOrDefault() as X509Certificate;

                                        var x509 = new __X509Certificate2 { InternalElement = c };


                                        if (c != null)
                                        {

                                            getdata = () =>
                                                "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n<h1>authenticated!</h1>"
                                                + new XElement("pre", new { x509.Subject, x509.SerialNumber }.ToString()
                                                    );
                                        }
                                    }
                                    catch (Exception fault)
                                    {
                                        //Caused by: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
                                        //        at sun.security.ssl.SSLSessionImpl.getPeerCertificates(Unknown Source)
                                        //        at javax.net.ssl.HandshakeCompletedEvent.getPeerCertificates(Unknown Source)

                                        //throw;

                                        Console.WriteLine("getPeerCertificates " + new { fault.Message });
                                    }
                                }
                            }
                        );

                        xSSLSocket.startHandshake();



                        //Cipher Suites: [
                        //    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 
                        //    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 
                        //    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 
                        //    Unknown 0xcc:0x14, 
                        //Unknown 0xcc:0x13, 
                        //TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 
                        //TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 
                        //TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 
                        //TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 
                        //TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 
                        //TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 
                        //TLS_RSA_WITH_AES_128_GCM_SHA256, 
                        //TLS_RSA_WITH_AES_256_CBC_SHA, 
                        //TLS_RSA_WITH_AES_128_CBC_SHA, 
                        //SSL_RSA_WITH_3DES_EDE_CBC_SHA]

                        // http://www.e2college.com/blogs/java_security/ssl_handshake_failure_due_to_unsupported_cipher_su.html






                        // Error	573	The type 'ScriptCoreLib.Shared.BCLImplementation.System.IO.__Stream' is defined in an assembly that is not referenced. You must add a reference to assembly 'ScriptCoreLib, Version=4.6.0.0, Culture=neutral, PublicKeyToken=null'.	Z:\jsc.svn\examples\java\hybrid\Test\JVMCLRSSLServerSocket\JVMCLRSSLServerSocket\Program.cs	68	17	JVMCLRSSLServerSocket

                        var xNetworkStream = new __NetworkStream
                        {
                            InternalInputStream = xSSLSocket.getInputStream(),
                            InternalOutputStream = xSSLSocket.getOutputStream()
                        };

                        Console.WriteLine(new { xNetworkStream });

                        // http://stackoverflow.com/questions/13874387/create-app-with-sslsocket-java

                        // http://www.java2s.com/Tutorial/Java/0320__Network/CreatinganSSLServerSocket.htm
                        // http://192.168.1.12:8443/
                        // chrome does a download of NAK EXT SOH NUL STX STX ??

                        // { byte0 = 71 }
                        //var byte0 = xNetworkStream.ReadByte();

                        //{ cf = sun.security.ssl.SSLSocketFactoryImpl@93f13f }
                        //{ ssf = sun.security.ssl.SSLServerSocketFactoryImpl@15dc721 }
                        //{ ss443 = [SSL: ServerSocket[addr=0.0.0.0/0.0.0.0,localport=8443]] }
                        //{ xSSLSocket = 1747f59[SSL_NULL_WITH_NULL_NULL: Socket[addr=/192.168.1.196,port=55953,localport=8443]] }
                        //{ xNetworkStream = ScriptCoreLibJava.BCLImplementation.System.Net.Sockets.__NetworkStream@538cc2 }
                        //{ byte0 = -1 }

                        //Console.WriteLine(new { byte0 });
                        //Console.WriteLine(new { byte0 });




                        //{ Message = Java heap space, StackTrace = java.lang.OutOfMemoryError: Java heap space
                        //        at ScriptCoreLibJava.BCLImplementation.System.IO.__MemoryStream.set_Capacity(__MemoryStream.java:110)
                        //        at ScriptCoreLibJava.BCLImplementation.System.IO.__MemoryStream.InternalEnsureCapacity(__MemoryStream.java:156)
                        //        at ScriptCoreLibJava.BCLImplementation.System.IO.__MemoryStream.WriteByte(__MemoryStream.java:140)
                        //        at ScriptCoreLibJava.BCLImplementation.System.IO.__StreamReader.ReadLine(__StreamReader.java:51)
                        //        at JVMCLRSSLServerSocket.Program.main(Program.java:145)

                        var xStreamReader = new StreamReader(xNetworkStream);
                        var line0 = xStreamReader.ReadLine();
                        Console.WriteLine(new { line0 });

                        // { line0 = GET / HTTP/1.1 }


                        // http://stackoverflow.com/questions/3662837/java-no-cipher-suites-in-common-issue-when-trying-to-securely-connect-to-serve
                        // http://stackoverflow.com/questions/15076820/java-sslhandshakeexception-no-cipher-suites-in-common


                        //Implementation not found for type import :
                        //type: System.IO.StreamWriter
                        //method: Void .ctor(System.IO.Stream)
                        //var xStreamWriter = new StreamWriter(xNetworkStream);

                        var data =
                           getdata();

                        var bytes = Encoding.UTF8.GetBytes(data);

                        xNetworkStream.Write(bytes, 0, bytes.Length);


                        xNetworkStream.Close();

                    }
                    catch (Exception fault)
                    {
                        reportHansshakeFault(fault);


                    }

                    //Thread.Sleep(5000);
                }


            }
            catch (Exception err)
            {
                Console.WriteLine(
                    new
                    {
                        err.Message,
                        err.StackTrace
                    }
                );

            }

            Console.WriteLine("done");
            Console.ReadLine();
        }
        protected override void onCreate(Bundle savedInstanceState)
        {
            Console.WriteLine("enter OVROculus360Photos ApplicationActivity onCreate");

            base.onCreate(savedInstanceState);




            Console.WriteLine("about to convince NDK what the first image should be...");
            // http://www.flightradar24.com/18.39,37.3/2

            // http://paulbourke.net/geometry/transformationprojection/

            // http://krpano.com/download/
            // http://unrealoldfriends.activeboard.com/t47250341/creating-background-using-spacescape/?page=1

            //Convert CUBE to SPHERE droplet


            //kcube2sphere 1.18.4 - 64bit (build 2015-04-23)
            //loading...
            //loading azi_l.jpg...
            //loading azi_f.jpg...
            //loading azi_r.jpg...
            //loading azi_b.jpg...
            //loading azi_u.jpg...
            //loading azi_d.jpg...
            //done.
            //making sphere azi_sphere.tif...
            //done.

            //Press any key to continue . . .










            //C:\Windows\system32> x:\util\android-sdk-windows\platform-tools\adb.exe push X:\jsc.svn\examples\javascript\synergy\css\CSSAzimuthMapViz\CSSAzimuthMapViz\Textures  /sdcard/oculus/360Photos/
            //push: X:\jsc.svn\examples\javascript\synergy\css\CSSAzimuthMapViz\CSSAzimuthMapViz\Textures/azi_pz.jpg -> /sdcard/oculus/360Photos/azi_pz.jpg
            //push: X:\jsc.svn\examples\javascript\synergy\css\CSSAzimuthMapViz\CSSAzimuthMapViz\Textures/azi_py.jpg -> /sdcard/oculus/360Photos/azi_py.jpg
            //push: X:\jsc.svn\examples\javascript\synergy\css\CSSAzimuthMapViz\CSSAzimuthMapViz\Textures/azi_px.jpg -> /sdcard/oculus/360Photos/azi_px.jpg
            //push: X:\jsc.svn\examples\javascript\synergy\css\CSSAzimuthMapViz\CSSAzimuthMapViz\Textures/azi_nz.jpg -> /sdcard/oculus/360Photos/azi_nz.jpg
            //push: X:\jsc.svn\examples\javascript\synergy\css\CSSAzimuthMapViz\CSSAzimuthMapViz\Textures/azi_ny.jpg -> /sdcard/oculus/360Photos/azi_ny.jpg
            //push: X:\jsc.svn\examples\javascript\synergy\css\CSSAzimuthMapViz\CSSAzimuthMapViz\Textures/azi_nx.jpg -> /sdcard/oculus/360Photos/azi_nx.jpg
            //6 files pushed. 0 files skipped.
            //466 KB/s (969865 bytes in 2.030s)

            //C:\Windows\system32> x:\util\android-sdk-windows\platform-tools\adb.exe shell cp /sdcard/oculus/360Photos/humus.thm /sdcard/oculus/360Photos/azi.thm

            Action<string, string> copy =
                (from, to) =>
                {

                    try
                    {

                        // http://gis.stackexchange.com/questions/92907/re-project-raster-image-from-mercator-to-equirectangular

                        // https://en.wikipedia.org/wiki/List_of_map_projections
                        // Web Mercator
                        // https://xkcd.com/977/
                        // mercator?
                        var value = this.getResources().getAssets().open(from);
                        var s = new __NetworkStream { InternalInputStream = value };

                        // 1,392,914
                        //var buffer = new byte[1392914];
                        var buffer = new byte[4392914];

                        var len = s.Read(buffer, 0, buffer.Length);


                        var m = new MemoryStream();

                        m.Write(buffer, 0, len);

                        //s.CopyTo(

                        File.WriteAllBytes(to, m.ToArray());

                    }
                    catch
                    {
                        Console.WriteLine("about to convince NDK what the first image should be... fault");

                    }

                };

            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150807/ovroculus360photosndk
            copy("2_no_clouds_4k.jpg", "/sdcard/oculus/360Photos/0.jpg");
            //copy("1.jpg", "/sdcard/oculus/360Photos/1.jpg");



            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150724/invaders
            //copy("celestial-joshua-trees-milky-way-in-saline-va.jpg", "/sdcard/oculus/360Photos/2.jpg");


            //Implementation not found for type import :
            //type: System.IO.DirectoryInfo
            //method: System.IO.FileInfo[] GetFiles()
            //Did you forget to add the [Script] attribute?
            //Please double check the signature!

            //Path.get

            var emptyFiles =
                from pf in new DirectoryInfo("/sdcard/oculus/360Photos/").GetFiles()
                where pf.Extension.ToLower() == ".jpg"
                where pf.Length == 0
                select pf;

            foreach (var emptyFile in emptyFiles.ToArray())
            {
                Console.WriteLine(new { emptyFile });

                emptyFile.Delete();
            }


            Console.WriteLine("about to convince NDK what the first image should be... done");


            var intent = getIntent();
            var commandString = com.oculus.vrappframework.VrActivity.getCommandStringFromIntent(intent);
            var fromPackageNameString = com.oculus.vrappframework.VrActivity.getPackageStringFromIntent(intent);
            var uriString = com.oculus.vrappframework.VrActivity.getUriStringFromIntent(intent);

            // D/CrashAnrDetector( 3472):     #00 pc 00092ac0  /data/app/OVROculus360Photos.Activities-1/lib/arm/libmain.so (OVR::ovrMessageQueue::PostMessage(char const*, bool, bool)+8)


            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160103/oculus360photossdk
            this.appPtr = OVROculus360Photos.Activities.xMarshal.nativeSetAppInterface(
                this,
                fromPackageNameString,
                commandString,
                uriString
            );

            var args = new args
            {

            };

            var uploadLength = 0L;
            var uploadPosition = 0L;

            var sw = Stopwatch.StartNew();

            #region mDraw
            var mDraw = new DrawOnTop(this)
            {
                // yes it appears top left.

                //text = "GearVR HUD"
                text = () => sw.ElapsedMilliseconds + "ms "
                    //+ "\n " + Path.GetFileName(args.filename)
                    + "\n " + args.filename

                    + "\n " + new
                    {
                        upload = (int)(100 * (uploadPosition + 1) / (args.filesize + 1)) + "%",
                        uploadPosition,
                        args.filesize,

                        // can we capture pointer?

                        args.x,
                        args.y,
                        args.z,

                        //uploadLength
                    }.ToString().Replace(",", ",\n")

                // X:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeEquirectangularPanorama\ChromeEquirectangularPanorama\Application.cs
            };
            #endregion


            //Task.Run(

            #region sendTracking
            Action<IPAddress> sendTracking = nic =>
            {
                var port = new Random().Next(16000, 40000);

                //new IHTMLPre { "about to bind... " + new { port } }.AttachToDocument();

                // where is bind async?
                var socket = new UdpClient(
                     new IPEndPoint(nic, port)
                    );


                // who is on the other end?
                var nmessage = args.x + ":" + args.y + ":" + args.z + ":0:" + args.filename;

                var data = Encoding.UTF8.GetBytes(nmessage);      //creates a variable b of type byte


                //new IHTMLPre { "about to send... " + new { data.Length } }.AttachToDocument();

                // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPNotification\ChromeUDPNotification\Application.cs
                //Console.WriteLine("about to Send");
                // X:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeEquirectangularPanorama\ChromeEquirectangularPanorama\Application.cs
                socket.Send(
                     data,
                     data.Length,
                     hostname: "239.1.2.3",
                     port: 49834
                 );



                socket.Close();

            };
            #endregion




            //I/System.Console( 9109): 2395:1fb3 enter __UdpClient ctor
            //I/System.Console( 9109): 2395:1fb3 enter __UdpClient before this.Client
            //I/System.Console( 9109): 2395:1fb3 enter __UdpClient after this.Client { Client = ScriptCoreLibJava.BCLImplementation.System.Net.Sockets.__Socket@4f1c02b }
            //I/System.Console( 9109): 2395:1fb3 enter GetAllNetworkInterfaces
            //I/System.Console( 9109): 2395:1fb3 enter __UdpClient ctor

            string current = null;
            byte[] bytes = null;

            new Thread(
                delegate()
                {
                    // bg thread


                    // bug out 1sec.
                    Thread.Sleep(1000);
                    // await gear on

                    while (true)
                    {
                        // collect tracking from ndk
                        // broadcast to udp


                        //Thread.Sleep(1000 / 15);

                        //var a = new
                        //{
                        //    // for java do we also do the fields?
                        //    x = 0
                        //};

                        args.filename = OVROculus360Photos.Activities.xMarshal.stringFromJNI(args);

                        //E/AndroidRuntime( 7601): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference
                        //E/AndroidRuntime( 7601):        at java.io.File.fixSlashes(File.java:185)
                        //E/AndroidRuntime( 7601):        at java.io.File.<init>(File.java:134)
                        //E/AndroidRuntime( 7601):        at ScriptCoreLibJava.BCLImplementation.System.IO.__File.Exists(__File.java:57)
                        //E/AndroidRuntime( 7601):        at OVROculus360PhotosHUD.Activities.ApplicationActivity___c__DisplayClass1d._onCreate_b__1b(ApplicationActivity___c__DisplayClass1d.java:95)



                        // uplink 144Mbps
                        // 18 MBps
                        #region udp broadcast
                        // overkill at 60hz
                        NetworkInterface.GetAllNetworkInterfaces().WithEach(
                             n =>
                             {
                                 // X:\jsc.svn\examples\java\android\forms\FormsUDPJoinGroup\FormsUDPJoinGroup\ApplicationControl.cs
                                 // X:\jsc.svn\core\ScriptCoreLibJava\BCLImplementation\System\Net\NetworkInformation\NetworkInterface.cs

                                 var IPProperties = n.GetIPProperties();
                                 var PhysicalAddress = n.GetPhysicalAddress();



                                 foreach (var ip in IPProperties.UnicastAddresses)
                                 {
                                     // ipv4
                                     if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                                     {
                                         if (!IPAddress.IsLoopback(ip.Address))
                                             if (n.SupportsMulticast)
                                             {
                                                 //fWASDC(ip.Address);
                                                 //fParallax(ip.Address);
                                                 //fvertexTransform(ip.Address);
                                                 sendTracking(ip.Address);
                                             }
                                     }
                                 }




                             }
                         );



                        #endregion

                        if (args.filename != null)
                            if (File.Exists(args.filename))
                            {
                                if (current != args.filename)
                                {
                                    current = args.filename;

                                    var ff = new FileInfo(args.filename);

                                    args.filesize = ff.Length;

                                    // we are not on ui thread.
                                    // HUD thread can freeze...
                                    // mmap?
                                    bytes = File.ReadAllBytes(args.filename);

                                    // now broadcast. at 500KBps in segments.
                                    // 8MB is 16 segments then.

                                    if (bytes.Length > 0)
                                        NetworkInterface.GetAllNetworkInterfaces().WithEach(
                                              n =>
                                              {
                                                  // X:\jsc.svn\examples\java\android\forms\FormsUDPJoinGroup\FormsUDPJoinGroup\ApplicationControl.cs
                                                  // X:\jsc.svn\core\ScriptCoreLibJava\BCLImplementation\System\Net\NetworkInformation\NetworkInterface.cs

                                                  var IPProperties = n.GetIPProperties();
                                                  var PhysicalAddress = n.GetPhysicalAddress();



                                                  foreach (var ip in IPProperties.UnicastAddresses)
                                                  {
                                                      // ipv4
                                                      if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                                                      {
                                                          if (!IPAddress.IsLoopback(ip.Address))
                                                              if (n.SupportsMulticast)
                                                              {
                                                                  //fWASDC(ip.Address);
                                                                  //fParallax(ip.Address);
                                                                  //fvertexTransform(ip.Address);
                                                                  //sendTracking(ip.Address);

                                                                  var port = new Random().Next(16000, 40000);

                                                                  //new IHTMLPre { "about to bind... " + new { port } }.AttachToDocument();

                                                                  // where is bind async?
                                                                  var socket = new UdpClient(
                                                                       new IPEndPoint(ip.Address, port)
                                                                      );


                                                                  //// who is on the other end?
                                                                  //var nmessage = args.x + ":" + args.y + ":" + args.z + ":0:" + args.filename;

                                                                  //var data = Encoding.UTF8.GetBytes(nmessage);      //creates a variable b of type byte

                                                                  // http://stackoverflow.com/questions/25841/maximum-buffer-length-for-sendto

                                                                  new { }.With(
                                                                      async delegate
                                                                      {
                                                                          // reached too far?
                                                                          if (bytes.Length == 0)
                                                                              return;

                                                                          var current0 = current;

                                                                          var r = new MemoryStream(bytes);
                                                                          uploadLength = r.Length;

                                                                          var data = new byte[65507];

                                                                      next:

                                                                          if (current0 != current)
                                                                              return;

                                                                          var cc = r.Read(data, 0, data.Length);

                                                                          uploadPosition = r.Position;

                                                                          if (cc <= 0)
                                                                              return;

                                                                          //new IHTMLPre { "about to send... " + new { data.Length } }.AttachToDocument();

                                                                          // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPNotification\ChromeUDPNotification\Application.cs
                                                                          //Console.WriteLine("about to Send");
                                                                          // X:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeEquirectangularPanorama\ChromeEquirectangularPanorama\Application.cs
                                                                          await socket.SendAsync(
                                                                               data,
                                                                               cc,
                                                                               hostname: "239.1.2.3",
                                                                               port: 49000
                                                                           );

                                                                          //await Task.Delay(1000 / 15);
                                                                          //await Task.Delay(1000 / 30);

                                                                          // no corruption
                                                                          await Task.Delay(1000 / 20);

                                                                          goto next;

                                                                      }
                                                                  );

                                                                  //socket.Close();
                                                              }
                                                      }
                                                  }




                                              }
                                          );
                                }
                            }

                        if (uploadPosition < args.filesize)
                            mDraw.color = android.graphics.Color.YELLOW;
                        else
                            mDraw.color = android.graphics.Color.GREEN;

                        mDraw.postInvalidate();
                        Thread.Sleep(1000 / 30);
                        //Thread.Sleep(1000 / 2);
                        //Thread.Sleep(1000 / 15);
                    }
                }
            ).Start();

            //this.ondispatchTouchEvent += @event =>
            //{

            //    int action = @event.getAction();
            //    float x = @event.getRawX();
            //    float y = @event.getRawY();
            //    //if (action == MotionEvent.ACTION_UP)
            //    {
            //        var halfx = 2560 / 2;
            //        var halfy = 1440 / 2;

            //        mDraw.x = (int)(500 + halfx - x);
            //        mDraw.y = (int)(600 + y - halfy);
            //        mDraw.text = () => sw.ElapsedMilliseconds + "ms \n" + new { x, y, action }.ToString();
            //        //Console.WriteLine(" ::dispatchTouchEvent( " + action + ", " + x + ", " + y + " )");
            //    }

            //    // can we move hud around and record it to gif or mp4?

            //    return true;
            //};

            // X:\jsc.svn\examples\java\android\synergy\OVRVrCubeWorldSurfaceView\OVRVrCubeWorldSurfaceView\ApplicationActivity.cs
            // X:\jsc.svn\examples\java\android\AndroidLacasCameraServerActivity\AndroidLacasCameraServerActivity\ApplicationActivity.cs
            addContentView(mDraw, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));


            // "x:\util\android-sdk-windows\platform-tools\adb.exe" connect 192.168.1.126:5555
            // cmd /K x:\util\android-sdk-windows\platform-tools\adb.exe logcat -s "JniUtils"  "System.Console" "art"


            // E/JniUtils(14136): couldn't get isHybridApp, (Landroid/app/Activity;)Z

            //            I/Oculus360Photos( 9199): nativeSetAppInterface
            //I/App     ( 9199): VrAppInterface::SetActivity:
            //I/App     ( 9199): new AppLocal( 0xf51512b0 0xff8b6b80 0xeef69900 )
            //I/App     ( 9199): ----------------- AppLocal::AppLocal() -----------------
            //E/JniUtils( 9199): couldn't get getInternalCacheMemoryInBytes, (Landroid/app/Activity;)J

            //            I/JniUtils(26390): Using caller's JNIEnv
            //E/JniUtils(26390): couldn't get getInstalledPackagePath, (Ljava/lang/String;)Ljava/lang/String;

            //            I/System.Console( 3652): 0e44:0001 Searching installed packages for 'com.oculus.systemactivities'
            //I/JniUtils( 3652): ovr_GetCurrentPackageName() = OVROculus360PhotosHUD.Activities
            //I/JniUtils( 3652): ovr_GetPackageCodePath() = '/data/app/OVROculus360PhotosHUD.Activities-1/base.apk'
            //W/art     ( 3652): Attempt to remove local handle scope entry from IRT, ignoring
            //W/art     ( 3652): Attempt to remove local handle scope entry from IRT, ignoring
            //W/art     ( 3652): Attempt to remove local handle scope entry from IRT, ignoring
            //I/JniUtils( 3652): ovr_GetCurrentActivityName() = OVROculus360PhotosHUD.Activities.ApplicationActivity
            //I/JniUtils( 3652): ovr_GetCurrentPackageName() = OVROculus360PhotosHUD.Activities
            //E/JniUtils( 3652): couldn't get getLocalizedString, (Ljava/lang/String;)Ljava/lang/String;
            //I/JniUtils( 4380): ovr_GetCurrentActivityName() = com.oculus.home.HomeActivity

            // ffs
        }
        public static void Main(string[] args)
        {
            // http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

            // https://alesaudate.wordpress.com/2010/08/09/how-to-dynamically-select-a-certificate-alias-when-invoking-web-services/

            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201510/20151010

            try
            {

                Console.WriteLine(
                              new
                              {
                                  typeof(object).AssemblyQualifiedName,
                                  Environment.CurrentDirectory,

                                  // "X:\Program Files (x86)\Java\jre7\lib\security\local_policy.jar"
                                  // Location = X:\Program Files (x86)\Java\jre7\lib\rt.jar }
                                  typeof(object).Assembly.Location,

                              }
                          );


                #region useless
                // You can't do it with the system properties. You would have to write and load your own X509KeyManager and create your own SSLContext with it.

                var keyStore = java.lang.System.getProperty("javax.net.ssl.keyStore");
                Console.WriteLine(new { keyStore });
                var keyStorePassword = java.lang.System.getProperty("javax.net.ssl.keyStorePassword");
                Console.WriteLine(new { keyStorePassword });
                #endregion

                // ok lets do a server.


                // http://developer.android.com/reference/android/net/SSLCertificateSocketFactory.html

                // http://stackoverflow.com/questions/11832672/how-can-a-java-client-use-the-native-windows-my-store-to-provide-its-client-cert
                // http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/ReadDebug.html

                //java.lang.System.setProperty("javax.net.debug", "all");

                // http://stackoverflow.com/questions/7615645/ssl-handshake-alert-unrecognized-name-error-since-upgrade-to-java-1-7-0
                java.lang.System.setProperty("jsse.enableSNIExtension", "false");


                // http://www.angelfire.com/or/abhilash/site/articles/jsse-km/customKeyManager.html


                // the reason for the SSLEngine’s complaint is that you enabled only the RSA cipher, but your certificate uses DSA keys. 
                //CLRProgram.makecert(host: "192.168.1.12", port: 8443);

                // ERR_SSL_VERSION_OR_CIPHER_MISMATCH

                //var xSSLContext = javax.net.ssl.SSLContext.getInstance("SSL");

                // For 256 bit security you need to install Oracle's unlimited strength policy files.
                // http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

                //var xSSLContext = javax.net.ssl.SSLContext.getInstance("SSLv3");

                // { Message = TLSv1.3 SSLContext not available, StackTrace = java.security.NoSuchAlgorithmException: TLSv1.3 SSLContext not available
                //var xSSLContext = javax.net.ssl.SSLContext.getInstance("TLSv1.3");
                //var xSSLContext = javax.net.ssl.SSLContext.getInstance("TLSv1.2");
                //var xSSLContext = javax.net.ssl.SSLContext.getInstance("TLSv1.1");


                // { Message = TLS_RSA_WITH_AES_256_CBC_SHA256 SSLContext not available, StackTrace = java.security.NoSuchAlgorithmException: TLS_RSA_WITH_AES_256_CBC_SHA256 SSLContext not available

                var xSSLContext = javax.net.ssl.SSLContext.getInstance("TLSv1.2");


                Console.WriteLine(new { xSSLContext });




                // https://android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/javax/net/ssl/KeyManagerFactory.java
                //var localKeyManager = new[] { new localKeyManager() };
                var myTrustManagerArray = new[] { new TrustEveryoneManager() };

                // null?
                xSSLContext.init(
                    // SunMSCAPI ?
                    localKeyManager.WindowsMYKeyManagers(),

                    myTrustManagerArray, new java.security.SecureRandom());




                //var cf = javax.net.ssl.SSLSocketFactory.getDefault() as javax.net.ssl.SSLSocketFactory;
                var xSSLServerSocketFactory = xSSLContext.getServerSocketFactory();

                //{ cf = sun.security.ssl.SSLSocketFactoryImpl@1fd10fa }
                //{ ssf = sun.security.ssl.SSLServerSocketFactoryImpl@7b4ed7 }
                Console.WriteLine(new { xSSLServerSocketFactory });

                //f.

                // http://www.javased.com/?api=javax.net.ssl.SSLSocketFactory
                // http://www.java2s.com/Code/JavaAPI/javax.net.ssl/SSLSocketFactorycreateSocketStringarg0intarg1.htm
                // http://saltnlight5.blogspot.com.ee/2014/10/how-to-setup-custom-sslsocketfactorys.html

                //f.createSocket(

                // http://www.herongyang.com/JDK/SSL-Socket-Server-Example-SslReverseEchoer.html
                //javax.net.ssl.SSLServerSocket.




                // http://www.javaworld.com/article/2075291/learn-java/build-secure-network-applications-with-ssl-and-the-jsse-api.html
                // -Djavax.net.ssl.keyStore
                // -Djavax.net.ssl.keyStorePassword


                // http://stackoverflow.com/questions/20798652/java-sslserversocket-presents-wrong-certificate

                // https://searchcode.com/codesearch/view/171073/

                // http://stackoverflow.com/questions/12370351/setting-the-certificate-used-by-a-java-ssl-serversocket
                // http://stackoverflow.com/questions/22230815/java-server-ssl-with-different-storepass-and-keypass

                // http://stackoverflow.com/questions/9921548/sslsocketfactory-in-java
                // https://code.google.com/p/vellum/wiki/LocalCa

                //  hg https://bitbucket.org/mfichman/mitm



                //var ssf = javax.net.ssl.SSLServerSocketFactory.getDefault() as javax.net.ssl.SSLServerSocketFactory;

                //// http://stackoverflow.com/questions/13874387/create-app-with-sslsocket-java
                //Console.WriteLine(new { ssf });


                //{ Message = Address already in use: JVM_Bind, StackTrace = java.net.BindException: Address already in use: JVM_Bind
                //        at java.net.DualStackPlainSocketImpl.bind0(Native Method)
                //        at java.net.DualStackPlainSocketImpl.socketBind(Unknown Source)
                //        at java.net.AbstractPlainSocketImpl.bind(Unknown Source)
                //        at java.net.PlainSocketImpl.bind(Unknown Source)
                //        at java.net.ServerSocket.bind(Unknown Source)
                //        at java.net.ServerSocket.<init>(Unknown Source)
                //        at java.net.ServerSocket.<init>(Unknown Source)
                //        at javax.net.ssl.SSLServerSocket.<init>(Unknown Source)
                //        at sun.security.ssl.SSLServerSocketImpl.<init>(Unknown Source)
                //        at sun.security.ssl.SSLServerSocketFactoryImpl.createServerSocket(Unknown Source)
                //        at JVMCLRSSLServerSocket.Program.main(Program.java:53)

                //C:\Windows\system32>netstat -ab

                //Active Connections

                //  Proto  Local Address          Foreign Address        State
                //  TCP    0.0.0.0:80             red:0                  LISTENING
                // Can not obtain ownership information
                //  TCP    0.0.0.0:135            red:0                  LISTENING
                //  RpcSs
                // [svchost.exe]
                //  TCP    0.0.0.0:443            red:0                  LISTENING



                // http://stackoverflow.com/questions/22225414/create-an-ssl-channel-same-pwd-for-keystore-and-trustore

                var ss443 = xSSLServerSocketFactory.createServerSocket(8443);


                Console.WriteLine(new { ss443 });


                // http://developer.android.com/reference/javax/net/ssl/SSLServerSocket.html
                var xSSLServerSocket = ss443 as javax.net.ssl.SSLServerSocket;


                // https://www.chromium.org/Home/chromium-security/education/tls
                // http://stackoverflow.com/questions/21289293/java-7-support-of-aes-gcm-in-ssl-tls
                // http://superuser.com/questions/747377/enable-tls-1-1-and-1-2-for-clients-on-java-7
                // https://blogs.oracle.com/java-platform-group/entry/java_8_will_use_tls





                xSSLServerSocket.setEnabledProtocols(new[] { "TLSv1.2", "SSLv2Hello" });


                //  Cipher suites with SHA384 and SHA256 are available only for TLS 1.2 or later.


                // http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#ciphersuites
                // http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#ciphersuites


                var SystemSupportedCipherSuites = xSSLServerSocket.getSupportedCipherSuites();

                SystemSupportedCipherSuites.WithEach(
                    SupportedCipherSuite =>
                    {
                        Console.WriteLine(new { SupportedCipherSuite });
                    }
                );

                //if (SystemSupportedCipherSuites.Contains())

                // https://googleonlinesecurity.blogspot.com.ee/2013/11/a-roster-of-tls-cipher-suites-weaknesses.html
                // http://stackoverflow.com/questions/21289293/java-7-support-of-aes-gcm-in-ssl-tls

                // need java 8?


                //xSSLServerSocket.setEnabledCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA");


                // https://blogs.oracle.com/java-platform-group/entry/diagnosing_tls_ssl_and_https
                // https://community.oracle.com/thread/2382681?tstart=0

                //Cipher Suites: [
                //    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 
                //    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 
                //    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 
                //    Unknown 0xcc:0x14, 
                //                Unknown 0xcc:0x13, 
                //                TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 
                //                TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 
                //                TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 
                //                TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 
                //                TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 
                //                TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 
                //                TLS_RSA_WITH_AES_128_GCM_SHA256, 
                //                TLS_RSA_WITH_AES_256_CBC_SHA, 
                //                TLS_RSA_WITH_AES_128_CBC_SHA, 
                //                SSL_RSA_WITH_3DES_EDE_CBC_SHA]



                // Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 
                // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 
                // TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 
                // Unknown 0xcc:0x14, Unknown 0xcc:0x13, 
                //TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 
                //TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 
                //TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 
                //TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 
                //TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 
                //TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 
                //TLS_RSA_WITH_AES_128_GCM_SHA256, 
                //TLS_RSA_WITH_AES_256_CBC_SHA, 
                //TLS_RSA_WITH_AES_128_CBC_SHA, 
                //SSL_RSA_WITH_3DES_EDE_CBC_SHA
                //]

                var enabledCipherSuites = new[] {
                    //"TLS_DHE_DSS_WITH_AES_128_CBC_SHA256" 

                    // { Message = Unsupported ciphersuite TLS_RSA_WITH_AES_128_GCM_SHA256, StackTrace = java.lang.IllegalArgumentException: Unsupported ciphersuite TLS_RSA_WITH_AES_128_GCM_SHA256
                    //"TLS_RSA_WITH_AES_128_GCM_SHA256" 

                    //"TLS_RSA_WITH_AES_256_CBC_SHA" 
                    "TLS_RSA_WITH_AES_128_CBC_SHA"

                    //"SSL_RSA_WITH_3DES_EDE_CBC_SHA" 

                    // { Message = Unsupported ciphersuite TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, StackTrace = java.lang.IllegalArgumentException: Unsupported ciphersuite TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
                    //"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" 

                    // { Message = Unsupported ciphersuite TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, StackTrace = java.lang.IllegalArgumentException: Unsupported ciphersuite TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
                    //"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"

                    // { Message = Unsupported ciphersuite TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, StackTrace = java.lang.IllegalArgumentException: Unsupported ciphersuite TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
                    //"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
                };

                // need id?
                //xSSLServerSocket.setNeedClientAuth(true);

                ////xSSLServerSocket.setWantClientAuth(true);

                //xSSLServerSocket.setEnabledCipherSuites(enabledCipherSuites);

                var ok = true;
                while (ok)
                {
                    //Console.WriteLine("accept...");
                    var xSSLSocket = ss443.accept() as javax.net.ssl.SSLSocket;




                    //Console.WriteLine(new { xSSLSocket });

                    // http://security.stackexchange.com/questions/76993/now-that-it-is-2015-what-ssl-tls-cipher-suites-should-be-used-in-a-high-securit
                    // java u suck.

                    //Console.WriteLine("startHandshake...");
                    try
                    {
                        // http://developer.android.com/reference/javax/net/ssl/HandshakeCompletedEvent.html

                        Func<string> getdata = () =>
                             "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n<h1>hello world</h1>";

                        // can we await for it?
                        xSSLSocket.addHandshakeCompletedListener(
                            new xHandshakeCompletedListener
                            {
                                yield = e =>
                                {
                                    try
                                    {
                                        Console.WriteLine("xHandshakeCompletedListener " + new { e.getPeerCertificates().Length });

                                        var c = e.getPeerCertificates().FirstOrDefault() as X509Certificate;

                                        var x509 = new __X509Certificate2 { InternalElement = c };


                                        if (c != null)
                                        {

                                            getdata = () =>
                                                "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n<h1>authenticated!</h1>"
                                                + new XElement("pre", new { x509.Subject, x509.SerialNumber }.ToString()
                                                    );
                                        }
                                    }
                                    catch (Exception fault)
                                    {
                                        //Caused by: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
                                        //        at sun.security.ssl.SSLSessionImpl.getPeerCertificates(Unknown Source)
                                        //        at javax.net.ssl.HandshakeCompletedEvent.getPeerCertificates(Unknown Source)

                                        //throw;

                                        Console.WriteLine("getPeerCertificates " + new { fault.Message });
                                    }
                                }
                            }
                        );

                        xSSLSocket.startHandshake();



                        //Cipher Suites: [
                        //    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 
                        //    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 
                        //    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 
                        //    Unknown 0xcc:0x14, 
                        //Unknown 0xcc:0x13, 
                        //TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 
                        //TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 
                        //TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 
                        //TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 
                        //TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 
                        //TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 
                        //TLS_RSA_WITH_AES_128_GCM_SHA256, 
                        //TLS_RSA_WITH_AES_256_CBC_SHA, 
                        //TLS_RSA_WITH_AES_128_CBC_SHA, 
                        //SSL_RSA_WITH_3DES_EDE_CBC_SHA]

                        // http://www.e2college.com/blogs/java_security/ssl_handshake_failure_due_to_unsupported_cipher_su.html






                        // Error	573	The type 'ScriptCoreLib.Shared.BCLImplementation.System.IO.__Stream' is defined in an assembly that is not referenced. You must add a reference to assembly 'ScriptCoreLib, Version=4.6.0.0, Culture=neutral, PublicKeyToken=null'.	Z:\jsc.svn\examples\java\hybrid\Test\JVMCLRSSLServerSocket\JVMCLRSSLServerSocket\Program.cs	68	17	JVMCLRSSLServerSocket

                        var xNetworkStream = new __NetworkStream
                        {
                            InternalInputStream = xSSLSocket.getInputStream(),
                            InternalOutputStream = xSSLSocket.getOutputStream()
                        };

                        Console.WriteLine(new { xNetworkStream });

                        // http://stackoverflow.com/questions/13874387/create-app-with-sslsocket-java

                        // http://www.java2s.com/Tutorial/Java/0320__Network/CreatinganSSLServerSocket.htm
                        // http://192.168.1.12:8443/
                        // chrome does a download of NAK EXT SOH NUL STX STX ??

                        // { byte0 = 71 }
                        //var byte0 = xNetworkStream.ReadByte();

                        //{ cf = sun.security.ssl.SSLSocketFactoryImpl@93f13f }
                        //{ ssf = sun.security.ssl.SSLServerSocketFactoryImpl@15dc721 }
                        //{ ss443 = [SSL: ServerSocket[addr=0.0.0.0/0.0.0.0,localport=8443]] }
                        //{ xSSLSocket = 1747f59[SSL_NULL_WITH_NULL_NULL: Socket[addr=/192.168.1.196,port=55953,localport=8443]] }
                        //{ xNetworkStream = ScriptCoreLibJava.BCLImplementation.System.Net.Sockets.__NetworkStream@538cc2 }
                        //{ byte0 = -1 }

                        //Console.WriteLine(new { byte0 });
                        //Console.WriteLine(new { byte0 });




                        //{ Message = Java heap space, StackTrace = java.lang.OutOfMemoryError: Java heap space
                        //        at ScriptCoreLibJava.BCLImplementation.System.IO.__MemoryStream.set_Capacity(__MemoryStream.java:110)
                        //        at ScriptCoreLibJava.BCLImplementation.System.IO.__MemoryStream.InternalEnsureCapacity(__MemoryStream.java:156)
                        //        at ScriptCoreLibJava.BCLImplementation.System.IO.__MemoryStream.WriteByte(__MemoryStream.java:140)
                        //        at ScriptCoreLibJava.BCLImplementation.System.IO.__StreamReader.ReadLine(__StreamReader.java:51)
                        //        at JVMCLRSSLServerSocket.Program.main(Program.java:145)

                        var xStreamReader = new StreamReader(xNetworkStream);
                        var line0 = xStreamReader.ReadLine();
                        Console.WriteLine(new { line0 });

                        // { line0 = GET / HTTP/1.1 }


                        // http://stackoverflow.com/questions/3662837/java-no-cipher-suites-in-common-issue-when-trying-to-securely-connect-to-serve
                        // http://stackoverflow.com/questions/15076820/java-sslhandshakeexception-no-cipher-suites-in-common


                        //Implementation not found for type import :
                        //type: System.IO.StreamWriter
                        //method: Void .ctor(System.IO.Stream)
                        //var xStreamWriter = new StreamWriter(xNetworkStream);

                        var data =
                           getdata();

                        var bytes = Encoding.UTF8.GetBytes(data);

                        xNetworkStream.Write(bytes, 0, bytes.Length);


                        xNetworkStream.Close();

                    }
                    catch (Exception fault)
                    {
                        reportHansshakeFault(fault);


                    }

                    //Thread.Sleep(5000);
                }
            }
            catch (Exception err)
            {
                Console.WriteLine(
                    new
                    {
                        err.Message,
                        err.StackTrace
                    }
                    );

            }

            //CLRProgram.CLRMain();

            Console.WriteLine("done");
            Console.ReadLine();
        }
        public static void Main(string[] args)
        {
            // http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

            // https://alesaudate.wordpress.com/2010/08/09/how-to-dynamically-select-a-certificate-alias-when-invoking-web-services/

            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201510/20151010

            try
            {
                // first lets print into console the aliases we could be choosing from
                // it should show the CA and the host alias on windows.
                // once this works. lets do an example that works with JVM keystore



                Console.WriteLine("-");

                // now lets start a ssl server and convince jvm to use the first friendly name we found..

                var xSSLContext = javax.net.ssl.SSLContext.getInstance("TLSv1.2");
                Console.WriteLine(new { xSSLContext });
                var xTrustEveryoneManager = new[] { new TrustEveryoneManager() };
                var xKeyManager = new[] { new localKeyManager() };

                xSSLContext.init(
                    // SunMSCAPI ?
                    xKeyManager,
                    xTrustEveryoneManager,
                    new java.security.SecureRandom()
                );

                var xSSLServerSocketFactory = xSSLContext.getServerSocketFactory();
                //var ss443 = xSSLServerSocketFactory.createServerSocket(8443);

                // { Message = Address already in use: JVM_Bind, StackTrace = java.net.BindException: Address already in use: JVM_Bind
                // stop AppHostSvc

                //[svchost.exe]
                // TCP    0.0.0.0:443            red:0                  LISTENING       4

                //var ss443 = xSSLServerSocketFactory.createServerSocket(443);
                var ss443 = xSSLServerSocketFactory.createServerSocket(8443);
                Console.WriteLine(new { ss443 });

                // http://developer.android.com/reference/javax/net/ssl/SSLServerSocket.html
                var xSSLServerSocket = ss443 as javax.net.ssl.SSLServerSocket;
                xSSLServerSocket.setEnabledProtocols(new[] { "TLSv1.2", "SSLv2Hello" });


                var ok = true;
                while (ok)
                {
                    //Console.WriteLine("accept...");
                    var xSSLSocket = ss443.accept() as javax.net.ssl.SSLSocket;




                    //Console.WriteLine(new { xSSLSocket });

                    // http://security.stackexchange.com/questions/76993/now-that-it-is-2015-what-ssl-tls-cipher-suites-should-be-used-in-a-high-securit
                    // java u suck.

                    //Console.WriteLine("startHandshake...");
                    try
                    {
                        // http://developer.android.com/reference/javax/net/ssl/HandshakeCompletedEvent.html

                        Func<string> getdata = () =>
                             "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n<h1>hello world</h1>";

                        // can we await for it?
                        xSSLSocket.addHandshakeCompletedListener(
                            new xHandshakeCompletedListener
                            {
                                yield = e =>
                                {
                                    try
                                    {
                                        Console.WriteLine("xHandshakeCompletedListener " + new { e.getPeerCertificates().Length });

                                        var c = e.getPeerCertificates().FirstOrDefault() as X509Certificate;

                                        var x509 = new __X509Certificate2 { InternalElement = c };


                                        if (c != null)
                                        {

                                            getdata = () =>
                                                "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n<h1>authenticated!</h1>"
                                                + new XElement("pre", new { x509.Subject, x509.SerialNumber }.ToString()
                                                    );
                                        }
                                    }
                                    catch (Exception fault)
                                    {
                                        //Caused by: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
                                        //        at sun.security.ssl.SSLSessionImpl.getPeerCertificates(Unknown Source)
                                        //        at javax.net.ssl.HandshakeCompletedEvent.getPeerCertificates(Unknown Source)

                                        //throw;

                                        Console.WriteLine("getPeerCertificates " + new { fault.Message });
                                    }
                                }
                            }
                        );

                        xSSLSocket.startHandshake();



                        //Cipher Suites: [
                        //    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 
                        //    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 
                        //    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 
                        //    Unknown 0xcc:0x14, 
                        //Unknown 0xcc:0x13, 
                        //TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 
                        //TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 
                        //TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 
                        //TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 
                        //TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 
                        //TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 
                        //TLS_RSA_WITH_AES_128_GCM_SHA256, 
                        //TLS_RSA_WITH_AES_256_CBC_SHA, 
                        //TLS_RSA_WITH_AES_128_CBC_SHA, 
                        //SSL_RSA_WITH_3DES_EDE_CBC_SHA]

                        // http://www.e2college.com/blogs/java_security/ssl_handshake_failure_due_to_unsupported_cipher_su.html






                        // Error	573	The type 'ScriptCoreLib.Shared.BCLImplementation.System.IO.__Stream' is defined in an assembly that is not referenced. You must add a reference to assembly 'ScriptCoreLib, Version=4.6.0.0, Culture=neutral, PublicKeyToken=null'.	Z:\jsc.svn\examples\java\hybrid\Test\JVMCLRSSLServerSocket\JVMCLRSSLServerSocket\Program.cs	68	17	JVMCLRSSLServerSocket

                        var xNetworkStream = new __NetworkStream
                        {
                            InternalInputStream = xSSLSocket.getInputStream(),
                            InternalOutputStream = xSSLSocket.getOutputStream()
                        };

                        Console.WriteLine(new { xNetworkStream });

                        // http://stackoverflow.com/questions/13874387/create-app-with-sslsocket-java

                        // http://www.java2s.com/Tutorial/Java/0320__Network/CreatinganSSLServerSocket.htm
                        // http://192.168.1.12:8443/
                        // chrome does a download of NAK EXT SOH NUL STX STX ??

                        // { byte0 = 71 }
                        //var byte0 = xNetworkStream.ReadByte();

                        //{ cf = sun.security.ssl.SSLSocketFactoryImpl@93f13f }
                        //{ ssf = sun.security.ssl.SSLServerSocketFactoryImpl@15dc721 }
                        //{ ss443 = [SSL: ServerSocket[addr=0.0.0.0/0.0.0.0,localport=8443]] }
                        //{ xSSLSocket = 1747f59[SSL_NULL_WITH_NULL_NULL: Socket[addr=/192.168.1.196,port=55953,localport=8443]] }
                        //{ xNetworkStream = ScriptCoreLibJava.BCLImplementation.System.Net.Sockets.__NetworkStream@538cc2 }
                        //{ byte0 = -1 }

                        //Console.WriteLine(new { byte0 });
                        //Console.WriteLine(new { byte0 });




                        //{ Message = Java heap space, StackTrace = java.lang.OutOfMemoryError: Java heap space
                        //        at ScriptCoreLibJava.BCLImplementation.System.IO.__MemoryStream.set_Capacity(__MemoryStream.java:110)
                        //        at ScriptCoreLibJava.BCLImplementation.System.IO.__MemoryStream.InternalEnsureCapacity(__MemoryStream.java:156)
                        //        at ScriptCoreLibJava.BCLImplementation.System.IO.__MemoryStream.WriteByte(__MemoryStream.java:140)
                        //        at ScriptCoreLibJava.BCLImplementation.System.IO.__StreamReader.ReadLine(__StreamReader.java:51)
                        //        at JVMCLRSSLServerSocket.Program.main(Program.java:145)

                        var xStreamReader = new StreamReader(xNetworkStream);
                        var line0 = xStreamReader.ReadLine();
                        //Console.WriteLine(new { line0 });

                        // { line0 = GET / HTTP/1.1 }


                        // http://stackoverflow.com/questions/3662837/java-no-cipher-suites-in-common-issue-when-trying-to-securely-connect-to-serve
                        // http://stackoverflow.com/questions/15076820/java-sslhandshakeexception-no-cipher-suites-in-common


                        //Implementation not found for type import :
                        //type: System.IO.StreamWriter
                        //method: Void .ctor(System.IO.Stream)
                        //var xStreamWriter = new StreamWriter(xNetworkStream);

                        var data =
                           getdata();

                        var bytes = Encoding.UTF8.GetBytes(data);

                        xNetworkStream.Write(bytes, 0, bytes.Length);


                        xNetworkStream.Close();

                    }
                    catch (Exception fault)
                    {
                        reportHansshakeFault(fault);


                    }

                    //Thread.Sleep(5000);
                }


            }
            catch (Exception err)
            {
                Console.WriteLine(
                    new
                    {
                        err.Message,
                        err.StackTrace
                    }
                );

            }

            Console.WriteLine("done");
            Console.ReadLine();
        }