You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by de...@apache.org on 2013/12/23 10:12:55 UTC

[01/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Updated Branches:
  refs/heads/4.3 105e27b73 -> 4f3611f9c


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/test/doc/freerdp-debug-log.txt
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/freerdp-debug-log.txt b/services/console-proxy-rdp/rdpconsole/src/test/doc/freerdp-debug-log.txt
new file mode 100755
index 0000000..d3101d6
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/test/doc/freerdp-debug-log.txt
@@ -0,0 +1,772 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+connected to 192.168.1.3:3389
+NEGOTIATE_MESSAGE (length = 40)
+0000 4e 54 4c 4d 53 53 50 00 01 00 00 00 b7 82 08 e2 NTLMSSP.........
+0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+0020 06 01 b1 1d 00 00 00 0f                         ........
+
+VERSION =
+{
+	ProductMajorVersion: 6
+	ProductMinorVersion: 1
+	ProductBuild: 7601
+	Reserved: 0x000000
+	NTLMRevisionCurrent: 0x0F
+ntlm_generate_client_challenge: ClientChallenge (random bytes): 
+0000 01 02 03 04 05 06 07 08                         ........
+
+CHALLENGE_MESSAGE (length = 238)
+0000 4e 54 4c 4d 53 53 50 00 02 00 00 00 1e 00 1e 00 NTLMSSP.........
+0010 38 00 00 00 35 82 8a e2 4a 25 50 a5 11 9b d6 16 8...5...J%P.....
+0020 00 00 00 00 00 00 00 00 98 00 98 00 56 00 00 00 ............V...
+0030 06 03 d7 24 00 00 00 0f 57 00 49 00 4e 00 2d 00 ...$....W.I.N.-.
+0040 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 L.O.4.1.9.B.2.L.
+0050 53 00 52 00 30 00 02 00 1e 00 57 00 49 00 4e 00 S.R.0.....W.I.N.
+0060 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 -.L.O.4.1.9.B.2.
+0070 4c 00 53 00 52 00 30 00 01 00 1e 00 57 00 49 00 L.S.R.0.....W.I.
+0080 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 N.-.L.O.4.1.9.B.
+0090 32 00 4c 00 53 00 52 00 30 00 04 00 1e 00 57 00 2.L.S.R.0.....W.
+00a0 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 I.N.-.L.O.4.1.9.
+00b0 42 00 32 00 4c 00 53 00 52 00 30 00 03 00 1e 00 B.2.L.S.R.0.....
+00c0 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+00d0 39 00 42 00 32 00 4c 00 53 00 52 00 30 00 07 00 9.B.2.L.S.R.0...
+00e0 08 00 a0 e8 85 2c e4 c9 ce 01 00 00 00 00       .....,........
+
+negotiateFlags "0xE28A8235"{
+	NTLMSSP_NEGOTIATE_56 (0),
+	NTLMSSP_NEGOTIATE_KEY_EXCH (1),
+	NTLMSSP_NEGOTIATE_128 (2),
+	NTLMSSP_NEGOTIATE_VERSION (6),
+	NTLMSSP_NEGOTIATE_TARGET_INFO (8),
+	NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY (12),
+	NTLMSSP_TARGET_TYPE_SERVER (14),
+	NTLMSSP_NEGOTIATE_ALWAYS_SIGN (16),
+	NTLMSSP_NEGOTIATE_NTLM (22),
+	NTLMSSP_NEGOTIATE_SEAL (26),
+	NTLMSSP_NEGOTIATE_SIGN (27),
+	NTLMSSP_REQUEST_TARGET (29),
+	NTLMSSP_NEGOTIATE_UNICODE (31),
+}
+VERSION =
+{
+	ProductMajorVersion: 6
+	ProductMinorVersion: 3
+	ProductBuild: 9431
+	Reserved: 0x000000
+	NTLMRevisionCurrent: 0x0F
+TargetName (Len: 30 MaxLen: 30 BufferOffset: 56)
+0000 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0010 39 00 42 00 32 00 4c 00 53 00 52 00 30 00       9.B.2.L.S.R.0.
+
+TargetInfo (Len: 152 MaxLen: 152 BufferOffset: 86)
+0000 02 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 4f 00 ....W.I.N.-.L.O.
+0010 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 52 00 4.1.9.B.2.L.S.R.
+0020 30 00 01 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 0.....W.I.N.-.L.
+0030 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 O.4.1.9.B.2.L.S.
+0040 52 00 30 00 04 00 1e 00 57 00 49 00 4e 00 2d 00 R.0.....W.I.N.-.
+0050 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 L.O.4.1.9.B.2.L.
+0060 53 00 52 00 30 00 03 00 1e 00 57 00 49 00 4e 00 S.R.0.....W.I.N.
+0070 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 -.L.O.4.1.9.B.2.
+0080 4c 00 53 00 52 00 30 00 07 00 08 00 a0 e8 85 2c L.S.R.0........,
+0090 e4 c9 ce 01 00 00 00 00                         ........
+
+ChallengeTargetInfo (152):
+AV_PAIRs =
+{
+	MsvAvNbDomainName AvId: 2 AvLen: 30
+0000 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0010 39 00 42 00 32 00 4c 00 53 00 52 00 30 00       9.B.2.L.S.R.0.
+	MsvAvNbComputerName AvId: 1 AvLen: 30
+0000 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0010 39 00 42 00 32 00 4c 00 53 00 52 00 30 00       9.B.2.L.S.R.0.
+	MsvAvDnsDomainName AvId: 4 AvLen: 30
+0000 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0010 39 00 42 00 32 00 4c 00 53 00 52 00 30 00       9.B.2.L.S.R.0.
+	MsvAvDnsComputerName AvId: 3 AvLen: 30
+0000 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0010 39 00 42 00 32 00 4c 00 53 00 52 00 30 00       9.B.2.L.S.R.0.
+	MsvAvTimestamp AvId: 7 AvLen: 8
+0000 a0 e8 85 2c e4 c9 ce 01                         ...,....
+}
+ntlm_generate_timestamp: timestamp
+0000 a0 e8 85 2c e4 c9 ce 01                         ...,....
+
+ntlm_generate_timestamp: ChallengeTimestamp
+0000 a0 e8 85 2c e4 c9 ce 01                         ...,....
+
+NTOWFv1W: Password:
+0000 52 00 32 00 50 00 72 00 65 00 76 00 69 00 65 00 R.2.P.r.e.v.i.e.
+0010 77 00 21 00                                     w.!.
+
+NTOWFv1W: NtHash (MD4(Password)):
+0000 25 f3 39 c9 86 b5 c2 6f dc ab 91 34 93 a2 18 2a %.9....o...4...*
+
+NTOWFv2W: NtHashV1 (NTOWFv1W(Password)):
+0000 25 f3 39 c9 86 b5 c2 6f dc ab 91 34 93 a2 18 2a %.9....o...4...*
+
+NTOWFv2W: User:
+0000 41 00 64 00 6d 00 69 00 6e 00 69 00 73 00 74 00 A.d.m.i.n.i.s.t.
+0010 72 00 61 00 74 00 6f 00 72 00                   r.a.t.o.r.
+
+NTOWFv2W: Domain:
+0000 77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 00 w.o.r.k.g.r.o.u.
+0010 70 00                                           p.
+
+NTOWFv2W: buffer (User+Domain):
+0000 41 00 44 00 4d 00 49 00 4e 00 49 00 53 00 54 00 A.D.M.I.N.I.S.T.
+0010 52 00 41 00 54 00 4f 00 52 00 77 00 6f 00 72 00 R.A.T.O.R.w.o.r.
+0020 6b 00 67 00 72 00 6f 00 75 00 70 00             k.g.r.o.u.p.
+
+NTOWFv2W: NtHash (HMAC_MD5(NtHashV1, User+Domain)):
+0000 5f cc 4c 48 74 6b 94 ce b7 ae f1 0d c9 11 22 8f _.LHtk........".
+
+ntlm_compute_ntlm_v2_hash: hash (NTOWFv2W(Password, User, Domain)):
+0000 5f cc 4c 48 74 6b 94 ce b7 ae f1 0d c9 11 22 8f _.LHtk........".
+
+ntlm_compute_lm_v2_response: ntlm_v2_hash:
+0000 5f cc 4c 48 74 6b 94 ce b7 ae f1 0d c9 11 22 8f _.LHtk........".
+
+ntlm_compute_lm_v2_response: value (ServerChallenge + ClientChallenge):
+0000 4a 25 50 a5 11 9b d6 16 01 02 03 04 05 06 07 08 J%P.............
+
+ntlm_compute_lm_v2_response: response (HMAC_MD5(ntlm_v2_hash, value) + ClientChallenge):
+0000 7c c0 fd 08 c5 14 05 34 f3 12 9e 3e a3 09 bc c6 |......4...>....
+0010 01 02 03 04 05 06 07 08                         ........
+
+NTOWFv1W: Password:
+0000 52 00 32 00 50 00 72 00 65 00 76 00 69 00 65 00 R.2.P.r.e.v.i.e.
+0010 77 00 21 00                                     w.!.
+
+NTOWFv1W: NtHash (MD4(Password)):
+0000 25 f3 39 c9 86 b5 c2 6f dc ab 91 34 93 a2 18 2a %.9....o...4...*
+
+NTOWFv2W: NtHashV1 (NTOWFv1W(Password)):
+0000 25 f3 39 c9 86 b5 c2 6f dc ab 91 34 93 a2 18 2a %.9....o...4...*
+
+NTOWFv2W: User:
+0000 41 00 64 00 6d 00 69 00 6e 00 69 00 73 00 74 00 A.d.m.i.n.i.s.t.
+0010 72 00 61 00 74 00 6f 00 72 00                   r.a.t.o.r.
+
+NTOWFv2W: Domain:
+0000 77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 00 w.o.r.k.g.r.o.u.
+0010 70 00                                           p.
+
+NTOWFv2W: buffer (User+Domain):
+0000 41 00 44 00 4d 00 49 00 4e 00 49 00 53 00 54 00 A.D.M.I.N.I.S.T.
+0010 52 00 41 00 54 00 4f 00 52 00 77 00 6f 00 72 00 R.A.T.O.R.w.o.r.
+0020 6b 00 67 00 72 00 6f 00 75 00 70 00             k.g.r.o.u.p.
+
+NTOWFv2W: NtHash (HMAC_MD5(NtHashV1, User+Domain)):
+0000 5f cc 4c 48 74 6b 94 ce b7 ae f1 0d c9 11 22 8f _.LHtk........".
+
+ntlm_compute_ntlm_v2_hash: hash (NTOWFv2W(Password, User, Domain)):
+0000 5f cc 4c 48 74 6b 94 ce b7 ae f1 0d c9 11 22 8f _.LHtk........".
+
+ntlm_compute_ntlm_v2_response: Password (length = 20)
+0000 52 00 32 00 50 00 72 00 65 00 76 00 69 00 65 00 R.2.P.r.e.v.i.e.
+0010 77 00 21 00                                     w.!.
+
+ntlm_compute_ntlm_v2_response: Username (length = 26)
+0000 41 00 64 00 6d 00 69 00 6e 00 69 00 73 00 74 00 A.d.m.i.n.i.s.t.
+0010 72 00 61 00 74 00 6f 00 72 00                   r.a.t.o.r.
+
+ntlm_compute_ntlm_v2_response: Domain (length = 18)
+0000 77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 00 w.o.r.k.g.r.o.u.
+0010 70 00                                           p.
+
+ntlm_compute_ntlm_v2_response: Workstation (length = 12)
+0000 61 00 70 00 6f 00 6c 00 6c 00 6f 00             a.p.o.l.l.o.
+
+ntlm_compute_ntlm_v2_response: TargetInfo (length = 234)
+0000 02 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 4f 00 ....W.I.N.-.L.O.
+0010 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 52 00 4.1.9.B.2.L.S.R.
+0020 30 00 01 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 0.....W.I.N.-.L.
+0030 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 O.4.1.9.B.2.L.S.
+0040 52 00 30 00 04 00 1e 00 57 00 49 00 4e 00 2d 00 R.0.....W.I.N.-.
+0050 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 L.O.4.1.9.B.2.L.
+0060 53 00 52 00 30 00 03 00 1e 00 57 00 49 00 4e 00 S.R.0.....W.I.N.
+0070 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 -.L.O.4.1.9.B.2.
+0080 4c 00 53 00 52 00 30 00 07 00 08 00 a0 e8 85 2c L.S.R.0........,
+0090 e4 c9 ce 01 06 00 04 00 02 00 00 00 0a 00 10 00 ................
+00a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+00b0 09 00 26 00 54 00 45 00 52 00 4d 00 53 00 52 00 ..&.T.E.R.M.S.R.
+00c0 56 00 2f 00 31 00 39 00 32 00 2e 00 31 00 36 00 V./.1.9.2...1.6.
+00d0 38 00 2e 00 31 00 2e 00 33 00 00 00 00 00 00 00 8...1...3.......
+00e0 00 00 00 00 00 00 00 00 00 00                   ..........
+
+ntlm_compute_ntlm_v2_response: ntlm_v2_hash (ntlm_compute_ntlm_v2_hash(context, (char*) ntlm_v2_hash))
+0000 5f cc 4c 48 74 6b 94 ce b7 ae f1 0d c9 11 22 8f _.LHtk........".
+
+ntlm_compute_ntlm_v2_response: ntlm_v2_temp (0x0101 + reserved 6 bytes + Timestamp + ClientChallenge + TargetInfo)
+0000 01 01 00 00 00 00 00 00 a0 e8 85 2c e4 c9 ce 01 ...........,....
+0010 01 02 03 04 05 06 07 08 00 00 00 00 02 00 1e 00 ................
+0020 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0030 39 00 42 00 32 00 4c 00 53 00 52 00 30 00 01 00 9.B.2.L.S.R.0...
+0040 1e 00 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 ..W.I.N.-.L.O.4.
+0050 31 00 39 00 42 00 32 00 4c 00 53 00 52 00 30 00 1.9.B.2.L.S.R.0.
+0060 04 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 4f 00 ....W.I.N.-.L.O.
+0070 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 52 00 4.1.9.B.2.L.S.R.
+0080 30 00 03 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 0.....W.I.N.-.L.
+0090 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 O.4.1.9.B.2.L.S.
+00a0 52 00 30 00 07 00 08 00 a0 e8 85 2c e4 c9 ce 01 R.0........,....
+00b0 06 00 04 00 02 00 00 00 0a 00 10 00 00 00 00 00 ................
+00c0 00 00 00 00 00 00 00 00 00 00 00 00 09 00 26 00 ..............&.
+00d0 54 00 45 00 52 00 4d 00 53 00 52 00 56 00 2f 00 T.E.R.M.S.R.V./.
+00e0 31 00 39 00 32 00 2e 00 31 00 36 00 38 00 2e 00 1.9.2...1.6.8...
+00f0 31 00 2e 00 33 00 00 00 00 00 00 00 00 00 00 00 1...3...........
+0100 00 00 00 00 00 00                               ......
+
+ntlm_compute_ntlm_v2_response: ntlm_v2_chal (ServerChallenge + ntlm_v2_temp)
+0000 4a 25 50 a5 11 9b d6 16 01 01 00 00 00 00 00 00 J%P.............
+0010 a0 e8 85 2c e4 c9 ce 01 01 02 03 04 05 06 07 08 ...,............
+0020 00 00 00 00 02 00 1e 00 57 00 49 00 4e 00 2d 00 ........W.I.N.-.
+0030 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 L.O.4.1.9.B.2.L.
+0040 53 00 52 00 30 00 01 00 1e 00 57 00 49 00 4e 00 S.R.0.....W.I.N.
+0050 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 -.L.O.4.1.9.B.2.
+0060 4c 00 53 00 52 00 30 00 04 00 1e 00 57 00 49 00 L.S.R.0.....W.I.
+0070 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 N.-.L.O.4.1.9.B.
+0080 32 00 4c 00 53 00 52 00 30 00 03 00 1e 00 57 00 2.L.S.R.0.....W.
+0090 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 I.N.-.L.O.4.1.9.
+00a0 42 00 32 00 4c 00 53 00 52 00 30 00 07 00 08 00 B.2.L.S.R.0.....
+00b0 a0 e8 85 2c e4 c9 ce 01 06 00 04 00 02 00 00 00 ...,............
+00c0 0a 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+00d0 00 00 00 00 09 00 26 00 54 00 45 00 52 00 4d 00 ......&.T.E.R.M.
+00e0 53 00 52 00 56 00 2f 00 31 00 39 00 32 00 2e 00 S.R.V./.1.9.2...
+00f0 31 00 36 00 38 00 2e 00 31 00 2e 00 33 00 00 00 1.6.8...1...3...
+0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00       ..............
+
+ntlm_compute_ntlm_v2_response: nt_proof_str ( HMAC_MD5(ntlm_v2_hash, ntlm_v2_temp_chal))
+0000 19 4b eb ad da 24 d5 96 85 2e 24 94 d6 4a b8 5e .K...$....$..J.^
+
+ntlm_compute_ntlm_v2_response: NtChallengeResponse ( nt_proof_str + ntlm_v2_temp)
+0000 19 4b eb ad da 24 d5 96 85 2e 24 94 d6 4a b8 5e .K...$....$..J.^
+0010 01 01 00 00 00 00 00 00 a0 e8 85 2c e4 c9 ce 01 ...........,....
+0020 01 02 03 04 05 06 07 08 00 00 00 00 02 00 1e 00 ................
+0030 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0040 39 00 42 00 32 00 4c 00 53 00 52 00 30 00 01 00 9.B.2.L.S.R.0...
+0050 1e 00 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 ..W.I.N.-.L.O.4.
+0060 31 00 39 00 42 00 32 00 4c 00 53 00 52 00 30 00 1.9.B.2.L.S.R.0.
+0070 04 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 4f 00 ....W.I.N.-.L.O.
+0080 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 52 00 4.1.9.B.2.L.S.R.
+0090 30 00 03 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 0.....W.I.N.-.L.
+00a0 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 O.4.1.9.B.2.L.S.
+00b0 52 00 30 00 07 00 08 00 a0 e8 85 2c e4 c9 ce 01 R.0........,....
+00c0 06 00 04 00 02 00 00 00 0a 00 10 00 00 00 00 00 ................
+00d0 00 00 00 00 00 00 00 00 00 00 00 00 09 00 26 00 ..............&.
+00e0 54 00 45 00 52 00 4d 00 53 00 52 00 56 00 2f 00 T.E.R.M.S.R.V./.
+00f0 31 00 39 00 32 00 2e 00 31 00 36 00 38 00 2e 00 1.9.2...1.6.8...
+0100 31 00 2e 00 33 00 00 00 00 00 00 00 00 00 00 00 1...3...........
+0110 00 00 00 00 00 00                               ......
+
+ntlm_compute_ntlm_v2_response: SessionBaseKey ( HMAC_MD5(ntlm_v2_hash, nt_proof_str)
+0000 8e 0f dd 12 4c 3b 11 7f 22 b9 4b 59 52 bc a7 18 ....L;..".KYR...
+
+ntlm_generate_key_exchange_key: KeyExchangeKey (SessionBaseKey): 
+0000 8e 0f dd 12 4c 3b 11 7f 22 b9 4b 59 52 bc a7 18 ....L;..".KYR...
+
+ntlm_generate_random_session_key: RandomSessionKey (random bytes): 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_exported_session_key: ExportedSessionKey (RandomSessionKey): 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_rc4k: key, 
+0000 8e 0f dd 12 4c 3b 11 7f 22 b9 4b 59 52 bc a7 18 ....L;..".KYR...
+
+ntlm_rc4k: plaintext 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_rc4k: ciphertext (RC4K(key, plaintext)) 
+0000 e4 e9 c2 ad 41 02 2f 3c f9 4c 72 84 c5 2a 7c 6f ....A./<.Lr..*|o
+
+ntlm_encrypt_random_session_key: KeyExchangeKey: 
+0000 8e 0f dd 12 4c 3b 11 7f 22 b9 4b 59 52 bc a7 18 ....L;..".KYR...
+
+ntlm_encrypt_random_session_key: RandomSessionKey: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_encrypt_random_session_key: EncryptedRandomSessionKey (RC4K(KeyExchangeKey, RandomSessionKey)): 
+0000 e4 e9 c2 ad 41 02 2f 3c f9 4c 72 84 c5 2a 7c 6f ....A./<.Lr..*|o
+
+ntlm_generate_signing_key: exported_session_key: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_signing_key: sign_magic: 
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 63 session key to c
+0010 6c 69 65 6e 74 2d 74 6f 2d 73 65 72 76 65 72 20 lient-to-server 
+0020 73 69 67 6e 69 6e 67 20 6b 65 79 20 6d 61 67 69 signing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: value ( exported_session_key + sign_magic ): 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+0010 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 63 session key to c
+0020 6c 69 65 6e 74 2d 74 6f 2d 73 65 72 76 65 72 20 lient-to-server 
+0030 73 69 67 6e 69 6e 67 20 6b 65 79 20 6d 61 67 69 signing key magi
+0040 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: signing_key (MD5(value)): 
+0000 f6 ae 96 cb 05 e2 ab 54 f6 dd 59 f3 c9 d9 a0 43 .......T..Y....C
+
+ntlm_generate_client_signing_key: ExportedSessionKey: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_client_signing_key: client_sign_magic: ":session key to client-to-server signing key magic constant"
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 63 session key to c
+0010 6c 69 65 6e 74 2d 74 6f 2d 73 65 72 76 65 72 20 lient-to-server 
+0020 73 69 67 6e 69 6e 67 20 6b 65 79 20 6d 61 67 69 signing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_client_signing_key: ClientSigningKey ( ntlm_generate_signing_key(context->ExportedSessionKey, &sign_magic, context->ClientSigningKey))
+0000 f6 ae 96 cb 05 e2 ab 54 f6 dd 59 f3 c9 d9 a0 43 .......T..Y....C
+
+ntlm_generate_signing_key: exported_session_key: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_signing_key: sign_magic: 
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 73 session key to s
+0010 65 72 76 65 72 2d 74 6f 2d 63 6c 69 65 6e 74 20 erver-to-client 
+0020 73 69 67 6e 69 6e 67 20 6b 65 79 20 6d 61 67 69 signing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: value ( exported_session_key + sign_magic ): 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+0010 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 73 session key to s
+0020 65 72 76 65 72 2d 74 6f 2d 63 6c 69 65 6e 74 20 erver-to-client 
+0030 73 69 67 6e 69 6e 67 20 6b 65 79 20 6d 61 67 69 signing key magi
+0040 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: signing_key (MD5(value)): 
+0000 b6 58 c5 98 7a 25 f8 6e d8 e5 6c e9 3e 3c c0 88 .X..z%.n..l.><..
+
+ntlm_generate_server_signing_key: ExportedSessionKey: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_server_signing_key: server_sign_magic: ":session key to server-to-client signing key magic constant"
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 73 session key to s
+0010 65 72 76 65 72 2d 74 6f 2d 63 6c 69 65 6e 74 20 erver-to-client 
+0020 73 69 67 6e 69 6e 67 20 6b 65 79 20 6d 61 67 69 signing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_server_signing_key: ServerSigningKey (ntlm_generate_signing_key(context->ExportedSessionKey, &sign_magic, context->ServerSigningKey))
+0000 b6 58 c5 98 7a 25 f8 6e d8 e5 6c e9 3e 3c c0 88 .X..z%.n..l.><..
+
+ntlm_generate_signing_key: exported_session_key: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_signing_key: sign_magic: 
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 63 session key to c
+0010 6c 69 65 6e 74 2d 74 6f 2d 73 65 72 76 65 72 20 lient-to-server 
+0020 73 65 61 6c 69 6e 67 20 6b 65 79 20 6d 61 67 69 sealing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: value ( exported_session_key + sign_magic ): 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+0010 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 63 session key to c
+0020 6c 69 65 6e 74 2d 74 6f 2d 73 65 72 76 65 72 20 lient-to-server 
+0030 73 65 61 6c 69 6e 67 20 6b 65 79 20 6d 61 67 69 sealing key magi
+0040 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: signing_key (MD5(value)): 
+0000 58 19 44 c2 7a c6 34 45 e4 b8 2b 55 b9 0b 1f b5 X.D.z.4E..+U....
+
+ntlm_generate_client_sealing_key: ExportedSessionKey: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_client_sealing_key: client_seal_magic: ":session key to client-to-server sealing key magic constant"
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 63 session key to c
+0010 6c 69 65 6e 74 2d 74 6f 2d 73 65 72 76 65 72 20 lient-to-server 
+0020 73 65 61 6c 69 6e 67 20 6b 65 79 20 6d 61 67 69 sealing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_client_sealing_key: ClientSealingKey (ntlm_generate_signing_key(context->ExportedSessionKey, &seal_magic, context->ClientSealingKey))
+0000 58 19 44 c2 7a c6 34 45 e4 b8 2b 55 b9 0b 1f b5 X.D.z.4E..+U....
+
+ntlm_generate_signing_key: exported_session_key: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_signing_key: sign_magic: 
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 73 session key to s
+0010 65 72 76 65 72 2d 74 6f 2d 63 6c 69 65 6e 74 20 erver-to-client 
+0020 73 65 61 6c 69 6e 67 20 6b 65 79 20 6d 61 67 69 sealing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: value ( exported_session_key + sign_magic ): 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+0010 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 73 session key to s
+0020 65 72 76 65 72 2d 74 6f 2d 63 6c 69 65 6e 74 20 erver-to-client 
+0030 73 65 61 6c 69 6e 67 20 6b 65 79 20 6d 61 67 69 sealing key magi
+0040 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: signing_key (MD5(value)): 
+0000 92 3a 73 5c 92 a7 04 34 be 9a a2 9f ed c1 e6 13 .:s\...4........
+
+ntlm_generate_server_sealing_key: ExportedSessionKey: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_server_sealing_key: server_seal_magic: ":session key to server-to-client sealing key magic constant"
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 73 session key to s
+0010 65 72 76 65 72 2d 74 6f 2d 63 6c 69 65 6e 74 20 erver-to-client 
+0020 73 65 61 6c 69 6e 67 20 6b 65 79 20 6d 61 67 69 sealing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_server_sealing_key: ServerSealingKey (ntlm_generate_signing_key(context->ExportedSessionKey, &seal_magic, context->ServerSealingKey))
+0000 92 3a 73 5c 92 a7 04 34 be 9a a2 9f ed c1 e6 13 .:s\...4........
+
+ntlm_init_rc4_seal_states: SendSigningKey (ClientSigningKey)
+0000 f6 ae 96 cb 05 e2 ab 54 f6 dd 59 f3 c9 d9 a0 43 .......T..Y....C
+
+ntlm_init_rc4_seal_states: RecvSigningKey (ServerSigningKey)
+0000 b6 58 c5 98 7a 25 f8 6e d8 e5 6c e9 3e 3c c0 88 .X..z%.n..l.><..
+
+ntlm_init_rc4_seal_states: SendSealingKey (ServerSealingKey)
+0000 92 3a 73 5c 92 a7 04 34 be 9a a2 9f ed c1 e6 13 .:s\...4........
+
+ntlm_init_rc4_seal_states: RecvSealingKey (ClientSealingKey)
+0000 58 19 44 c2 7a c6 34 45 e4 b8 2b 55 b9 0b 1f b5 X.D.z.4E..+U....
+
+ntlm_init_rc4_seal_states: SendRc4Seal = 0xb6a28da0 (RC4_set_key(&context->SendRc4Seal, 16, context->ClientSealingKey))
+ntlm_init_rc4_seal_states: RecvRc4Seal = 0xb6a291a8 (RC4_set_key(&context->RecvRc4Seal, 16, context->ServerSealingKey))
+ntlm_read_ChallengeMessage: ClientChallenge
+0000 01 02 03 04 05 06 07 08                         ........
+
+ntlm_read_ChallengeMessage: ServerChallenge
+0000 4a 25 50 a5 11 9b d6 16                         J%P.....
+
+ntlm_read_ChallengeMessage: SessionBaseKey
+0000 8e 0f dd 12 4c 3b 11 7f 22 b9 4b 59 52 bc a7 18 ....L;..".KYR...
+
+ntlm_read_ChallengeMessage: KeyExchangeKey
+0000 8e 0f dd 12 4c 3b 11 7f 22 b9 4b 59 52 bc a7 18 ....L;..".KYR...
+
+ntlm_read_ChallengeMessage: ExportedSessionKey
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_read_ChallengeMessage: RandomSessionKey
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_read_ChallengeMessage: ClientSigningKey
+0000 f6 ae 96 cb 05 e2 ab 54 f6 dd 59 f3 c9 d9 a0 43 .......T..Y....C
+
+ntlm_read_ChallengeMessage: ClientSealingKey
+0000 58 19 44 c2 7a c6 34 45 e4 b8 2b 55 b9 0b 1f b5 X.D.z.4E..+U....
+
+ntlm_read_ChallengeMessage: ServerSigningKey
+0000 b6 58 c5 98 7a 25 f8 6e d8 e5 6c e9 3e 3c c0 88 .X..z%.n..l.><..
+
+ntlm_read_ChallengeMessage: ServerSealingKey
+0000 92 3a 73 5c 92 a7 04 34 be 9a a2 9f ed c1 e6 13 .:s\...4........
+
+ntlm_read_ChallengeMessage: Timestamp
+0000 a0 e8 85 2c e4 c9 ce 01                         ...,....
+
+ntlm_compute_message_integrity_check: ExportedSessionKey
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_compute_message_integrity_check: NegotiateMessage
+0000 4e 54 4c 4d 53 53 50 00 01 00 00 00 b7 82 08 e2 NTLMSSP.........
+0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+0020 06 01 b1 1d 00 00 00 0f                         ........
+
+ntlm_compute_message_integrity_check: ChallengeMessage
+0000 4e 54 4c 4d 53 53 50 00 02 00 00 00 1e 00 1e 00 NTLMSSP.........
+0010 38 00 00 00 35 82 8a e2 4a 25 50 a5 11 9b d6 16 8...5...J%P.....
+0020 00 00 00 00 00 00 00 00 98 00 98 00 56 00 00 00 ............V...
+0030 06 03 d7 24 00 00 00 0f 57 00 49 00 4e 00 2d 00 ...$....W.I.N.-.
+0040 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 L.O.4.1.9.B.2.L.
+0050 53 00 52 00 30 00 02 00 1e 00 57 00 49 00 4e 00 S.R.0.....W.I.N.
+0060 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 -.L.O.4.1.9.B.2.
+0070 4c 00 53 00 52 00 30 00 01 00 1e 00 57 00 49 00 L.S.R.0.....W.I.
+0080 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 N.-.L.O.4.1.9.B.
+0090 32 00 4c 00 53 00 52 00 30 00 04 00 1e 00 57 00 2.L.S.R.0.....W.
+00a0 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 I.N.-.L.O.4.1.9.
+00b0 42 00 32 00 4c 00 53 00 52 00 30 00 03 00 1e 00 B.2.L.S.R.0.....
+00c0 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+00d0 39 00 42 00 32 00 4c 00 53 00 52 00 30 00 07 00 9.B.2.L.S.R.0...
+00e0 08 00 a0 e8 85 2c e4 c9 ce 01 00 00 00 00       .....,........
+
+ntlm_compute_message_integrity_check: AuthenticateMessage
+0000 4e 54 4c 4d 53 53 50 00 03 00 00 00 18 00 18 00 NTLMSSP.........
+0010 90 00 00 00 16 01 16 01 a8 00 00 00 12 00 12 00 ................
+0020 58 00 00 00 1a 00 1a 00 6a 00 00 00 0c 00 0c 00 X.......j.......
+0030 84 00 00 00 10 00 10 00 be 01 00 00 35 b2 88 e2 ............5...
+0040 06 01 b1 1d 00 00 00 0f 00 00 00 00 00 00 00 00 ................
+0050 00 00 00 00 00 00 00 00 77 00 6f 00 72 00 6b 00 ........w.o.r.k.
+0060 67 00 72 00 6f 00 75 00 70 00 41 00 64 00 6d 00 g.r.o.u.p.A.d.m.
+0070 69 00 6e 00 69 00 73 00 74 00 72 00 61 00 74 00 i.n.i.s.t.r.a.t.
+0080 6f 00 72 00 61 00 70 00 6f 00 6c 00 6c 00 6f 00 o.r.a.p.o.l.l.o.
+0090 7c c0 fd 08 c5 14 05 34 f3 12 9e 3e a3 09 bc c6 |......4...>....
+00a0 01 02 03 04 05 06 07 08 19 4b eb ad da 24 d5 96 .........K...$..
+00b0 85 2e 24 94 d6 4a b8 5e 01 01 00 00 00 00 00 00 ..$..J.^........
+00c0 a0 e8 85 2c e4 c9 ce 01 01 02 03 04 05 06 07 08 ...,............
+00d0 00 00 00 00 02 00 1e 00 57 00 49 00 4e 00 2d 00 ........W.I.N.-.
+00e0 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 L.O.4.1.9.B.2.L.
+00f0 53 00 52 00 30 00 01 00 1e 00 57 00 49 00 4e 00 S.R.0.....W.I.N.
+0100 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 -.L.O.4.1.9.B.2.
+0110 4c 00 53 00 52 00 30 00 04 00 1e 00 57 00 49 00 L.S.R.0.....W.I.
+0120 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 N.-.L.O.4.1.9.B.
+0130 32 00 4c 00 53 00 52 00 30 00 03 00 1e 00 57 00 2.L.S.R.0.....W.
+0140 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 I.N.-.L.O.4.1.9.
+0150 42 00 32 00 4c 00 53 00 52 00 30 00 07 00 08 00 B.2.L.S.R.0.....
+0160 a0 e8 85 2c e4 c9 ce 01 06 00 04 00 02 00 00 00 ...,............
+0170 0a 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+0180 00 00 00 00 09 00 26 00 54 00 45 00 52 00 4d 00 ......&.T.E.R.M.
+0190 53 00 52 00 56 00 2f 00 31 00 39 00 32 00 2e 00 S.R.V./.1.9.2...
+01a0 31 00 36 00 38 00 2e 00 31 00 2e 00 33 00 00 00 1.6.8...1...3...
+01b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e4 e9 ................
+01c0 c2 ad 41 02 2f 3c f9 4c 72 84 c5 2a 7c 6f       ..A./<.Lr..*|o
+
+ntlm_compute_message_integrity_check: MessageIntegrityCheck (HMAC_MD5(ExportedSessionKey + NegotiateMessage + ChallengeMessage + AuthenticateMessage))
+0000 d9 e9 bc 9b 6f a5 f9 c8 70 16 10 20 f8 f1 61 42 ....o...p.. ..aB
+
+credssp_encrypt_public_key_echo: Server public key (length = 270):
+recv_seq_num: 0
+Public key before encryption:
+0000 30 82 01 0a 02 82 01 01 00 a8 56 65 d3 ce 8a 54 0.........Ve...T
+0010 4d 9d b0 84 31 19 71 7f dd 42 fb 2a 7a 72 13 a1 M...1.q..B.*zr..
+0020 b9 72 bb d3 08 ad 7d 6c 15 65 03 d1 c4 54 c5 33 .r....}l.e...T.3
+0030 6b 7d 69 89 5e fe e0 01 c0 7e 9b cb 5d 65 36 cd k}i.^....~..]e6.
+0040 77 5d f3 7a 5b 29 44 72 d5 38 e2 cf b1 c7 78 9b w].z[)Dr.8....x.
+0050 58 b9 17 7c b7 d6 c7 c7 bf 90 4e 7c 39 93 cb 2e X..|......N|9...
+0060 e0 c2 33 2d a5 7e e0 7b b6 f9 91 32 b7 d4 85 b7 ..3-.~.{...2....
+0070 35 2d 2b 00 6d f8 ea 8c 97 5f 51 1d 68 04 3c 79 5-+.m...._Q.h.<y
+0080 14 71 a7 c7 d7 70 7a e0 ba 12 69 c8 d3 d9 4e ab .q...pz...i...N.
+0090 51 47 a3 ec 99 d4 88 ca da c2 7f 79 4b 66 ed 87 QG.........yKf..
+00a0 be c2 5f ea cf e1 b5 f0 3d 9b f2 19 c3 e0 e1 7a .._.....=......z
+00b0 45 71 12 3d 72 1d 6f 2b 1c 46 68 c0 8f 4f ce 3a Eq.=r.o+.Fh..O.:
+00c0 c5 cd 22 65 2d 43 b0 5c dd 89 ae be 70 59 5e 0c .."e-C.\....pY^.
+00d0 bd f5 46 82 1e e4 86 95 7b 60 ae 45 50 c2 54 08 ..F.....{`.EP.T.
+00e0 49 9a 9e fb b2 b6 78 e5 2f 9c 5a d0 8a 03 77 68 I.....x./.Z...wh
+00f0 30 93 78 6d 90 6d 50 fa a7 65 fe 59 33 27 4e 4b 0.xm.mP..e.Y3'NK
+0100 f8 38 44 3a 12 f4 07 a0 8d 02 03 01 00 01       .8D:..........
+credssp_encrypt_public_key_echo: Signature for decryption:
+0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ntlm_EncryptMessage: data:
+0000 30 82 01 0a 02 82 01 01 00 a8 56 65 d3 ce 8a 54 0.........Ve...T
+0010 4d 9d b0 84 31 19 71 7f dd 42 fb 2a 7a 72 13 a1 M...1.q..B.*zr..
+0020 b9 72 bb d3 08 ad 7d 6c 15 65 03 d1 c4 54 c5 33 .r....}l.e...T.3
+0030 6b 7d 69 89 5e fe e0 01 c0 7e 9b cb 5d 65 36 cd k}i.^....~..]e6.
+0040 77 5d f3 7a 5b 29 44 72 d5 38 e2 cf b1 c7 78 9b w].z[)Dr.8....x.
+0050 58 b9 17 7c b7 d6 c7 c7 bf 90 4e 7c 39 93 cb 2e X..|......N|9...
+0060 e0 c2 33 2d a5 7e e0 7b b6 f9 91 32 b7 d4 85 b7 ..3-.~.{...2....
+0070 35 2d 2b 00 6d f8 ea 8c 97 5f 51 1d 68 04 3c 79 5-+.m...._Q.h.<y
+0080 14 71 a7 c7 d7 70 7a e0 ba 12 69 c8 d3 d9 4e ab .q...pz...i...N.
+0090 51 47 a3 ec 99 d4 88 ca da c2 7f 79 4b 66 ed 87 QG.........yKf..
+00a0 be c2 5f ea cf e1 b5 f0 3d 9b f2 19 c3 e0 e1 7a .._.....=......z
+00b0 45 71 12 3d 72 1d 6f 2b 1c 46 68 c0 8f 4f ce 3a Eq.=r.o+.Fh..O.:
+00c0 c5 cd 22 65 2d 43 b0 5c dd 89 ae be 70 59 5e 0c .."e-C.\....pY^.
+00d0 bd f5 46 82 1e e4 86 95 7b 60 ae 45 50 c2 54 08 ..F.....{`.EP.T.
+00e0 49 9a 9e fb b2 b6 78 e5 2f 9c 5a d0 8a 03 77 68 I.....x./.Z...wh
+00f0 30 93 78 6d 90 6d 50 fa a7 65 fe 59 33 27 4e 4b 0.xm.mP..e.Y3'NK
+0100 f8 38 44 3a 12 f4 07 a0 8d 02 03 01 00 01       .8D:..........
+
+ntlm_EncryptMessage: digest (HMAC_MD5(SendSigningKey, seq_num + data)), seq_num: 0
+0000 bf e8 70 ad ac d8 5b a8 33 1a 74 1f 6c ec c9 b3 ..p...[.3.t.l...
+
+ntlm_EncryptMessage: Data Buffer before encryption (length = 270)
+0000 30 82 01 0a 02 82 01 01 00 a8 56 65 d3 ce 8a 54 0.........Ve...T
+0010 4d 9d b0 84 31 19 71 7f dd 42 fb 2a 7a 72 13 a1 M...1.q..B.*zr..
+0020 b9 72 bb d3 08 ad 7d 6c 15 65 03 d1 c4 54 c5 33 .r....}l.e...T.3
+0030 6b 7d 69 89 5e fe e0 01 c0 7e 9b cb 5d 65 36 cd k}i.^....~..]e6.
+0040 77 5d f3 7a 5b 29 44 72 d5 38 e2 cf b1 c7 78 9b w].z[)Dr.8....x.
+0050 58 b9 17 7c b7 d6 c7 c7 bf 90 4e 7c 39 93 cb 2e X..|......N|9...
+0060 e0 c2 33 2d a5 7e e0 7b b6 f9 91 32 b7 d4 85 b7 ..3-.~.{...2....
+0070 35 2d 2b 00 6d f8 ea 8c 97 5f 51 1d 68 04 3c 79 5-+.m...._Q.h.<y
+0080 14 71 a7 c7 d7 70 7a e0 ba 12 69 c8 d3 d9 4e ab .q...pz...i...N.
+0090 51 47 a3 ec 99 d4 88 ca da c2 7f 79 4b 66 ed 87 QG.........yKf..
+00a0 be c2 5f ea cf e1 b5 f0 3d 9b f2 19 c3 e0 e1 7a .._.....=......z
+00b0 45 71 12 3d 72 1d 6f 2b 1c 46 68 c0 8f 4f ce 3a Eq.=r.o+.Fh..O.:
+00c0 c5 cd 22 65 2d 43 b0 5c dd 89 ae be 70 59 5e 0c .."e-C.\....pY^.
+00d0 bd f5 46 82 1e e4 86 95 7b 60 ae 45 50 c2 54 08 ..F.....{`.EP.T.
+00e0 49 9a 9e fb b2 b6 78 e5 2f 9c 5a d0 8a 03 77 68 I.....x./.Z...wh
+00f0 30 93 78 6d 90 6d 50 fa a7 65 fe 59 33 27 4e 4b 0.xm.mP..e.Y3'NK
+0100 f8 38 44 3a 12 f4 07 a0 8d 02 03 01 00 01       .8D:..........
+
+ntlm_EncryptMessage: SendRc4Seal = 0xe
+ntlm_EncryptMessage: Encrypted Data Buffer (RC4(&context->SendRc4Seal, length, data, data_buffer->pvBuffer))
+0000 15 f7 f2 54 da a9 e5 ad 85 04 67 4d 0b cb f9 b1 ...T......gM....
+0010 f8 02 8a 77 c2 63 ab d5 74 23 9f 9d 5d 1f d3 b3 ...w.c..t#..]...
+0020 a0 ac 16 8a 4b 08 f5 47 70 58 10 b4 e7 87 b3 4b ....K..GpX.....K
+0030 c9 a2 d5 d1 ca 0f d4 e3 8d 76 5a 60 28 f8 06 5d .........vZ`(..]
+0040 e4 7e 21 c8 bb ac e5 79 85 30 9b 88 13 2f 8f fc .~!....y.0.../..
+0050 04 52 fe 87 94 cf cb 49 4a da 6f dd ee 57 a5 e4 .R.....IJ.o..W..
+0060 4d 0e 5c 3d 0b 63 1f f6 3d 1b ae 5a f6 42 2a 46 M.\=.c..=..Z.B*F
+0070 fa 42 71 67 46 02 71 ea 51 98 f7 d4 43 bf 8e e8 .BqgF.q.Q...C...
+0080 3c c8 fa 79 9d 8c fc c2 42 c9 bb d0 ab 81 c4 53 <..y....B......S
+0090 fd 41 da ab 0f 25 79 5f bd a3 8c d3 f5 1b ab 20 .A...%y_....... 
+00a0 d1 f4 d8 81 9c 18 4a a4 77 ee e1 51 ee 2a c1 94 ......J.w..Q.*..
+00b0 37 c5 06 7a 3f 0f 25 5b 4e 6a dc 0b 62 6f 12 83 7..z?.%[Nj..bo..
+00c0 03 ae 4e ce 2b 6e d4 d5 23 27 f6 a6 38 67 ec 95 ..N.+n..#'..8g..
+00d0 82 c6 ba d4 f6 e6 22 7d b9 e4 81 97 24 ff 40 b2 ......"}....$.@.
+00e0 42 3c 11 24 d0 3a 96 d9 c1 13 d6 62 45 21 60 5b B<.$.:.....bE!`[
+00f0 7b 2b 62 44 f7 40 93 29 5b 44 b7 da 9c a6 a9 3b {+bD.@.)[D.....;
+0100 e1 3b 9d 31 f2 21 53 0f b3 70 55 84 2c b4       .;.1.!S..pU.,.
+
+ntlm_EncryptMessage: Checksum ( RC4(&context->SendRc4Seal, 8, digest, checksum), first 8 bytes of digest only!):
+0000 72 76 1e 57 49 b5 0f ad                         rv.WI...
+ntlm_EncryptMessage: signature (version + checksum + seq_num)
+0000 01 00 00 00 72 76 1e 57 49 b5 0f ad 00 00 00 00 ....rv.WI.......
+
+ntlm_EncryptMessage: SendSeqNum (after increase): 1, SeqNo: 0.
+credssp_encrypt_public_key_echo: Server public key (length = 270):
+recv_seq_num: 0
+Public key after encryption:
+0000 15 f7 f2 54 da a9 e5 ad 85 04 67 4d 0b cb f9 b1 ...T......gM....
+0010 f8 02 8a 77 c2 63 ab d5 74 23 9f 9d 5d 1f d3 b3 ...w.c..t#..]...
+0020 a0 ac 16 8a 4b 08 f5 47 70 58 10 b4 e7 87 b3 4b ....K..GpX.....K
+0030 c9 a2 d5 d1 ca 0f d4 e3 8d 76 5a 60 28 f8 06 5d .........vZ`(..]
+0040 e4 7e 21 c8 bb ac e5 79 85 30 9b 88 13 2f 8f fc .~!....y.0.../..
+0050 04 52 fe 87 94 cf cb 49 4a da 6f dd ee 57 a5 e4 .R.....IJ.o..W..
+0060 4d 0e 5c 3d 0b 63 1f f6 3d 1b ae 5a f6 42 2a 46 M.\=.c..=..Z.B*F
+0070 fa 42 71 67 46 02 71 ea 51 98 f7 d4 43 bf 8e e8 .BqgF.q.Q...C...
+0080 3c c8 fa 79 9d 8c fc c2 42 c9 bb d0 ab 81 c4 53 <..y....B......S
+0090 fd 41 da ab 0f 25 79 5f bd a3 8c d3 f5 1b ab 20 .A...%y_....... 
+00a0 d1 f4 d8 81 9c 18 4a a4 77 ee e1 51 ee 2a c1 94 ......J.w..Q.*..
+00b0 37 c5 06 7a 3f 0f 25 5b 4e 6a dc 0b 62 6f 12 83 7..z?.%[Nj..bo..
+00c0 03 ae 4e ce 2b 6e d4 d5 23 27 f6 a6 38 67 ec 95 ..N.+n..#'..8g..
+00d0 82 c6 ba d4 f6 e6 22 7d b9 e4 81 97 24 ff 40 b2 ......"}....$.@.
+00e0 42 3c 11 24 d0 3a 96 d9 c1 13 d6 62 45 21 60 5b B<.$.:.....bE!`[
+00f0 7b 2b 62 44 f7 40 93 29 5b 44 b7 da 9c a6 a9 3b {+bD.@.)[D.....;
+0100 e1 3b 9d 31 f2 21 53 0f b3 70 55 84 2c b4       .;.1.!S..pU.,.
+credssp_decrypt_public_key_echo: Server public key (length = 270):
+recv_seq_num: 0
+Public key before decryption:
+0000 03 12 dd ea 47 b3 ff e1 66 08 f6 6b a0 62 42 67 ....G...f..k.bBg
+0010 bf 3d 59 60 ef 52 b0 26 95 ed 84 48 44 bb 8d 65 .=Y`.R.&...HD..e
+0020 cf e4 8e 6f 69 ae ed 44 bb 49 1d 2a 40 29 2b 13 ...oi..D.I.*@)+.
+0030 42 1c eb b1 6c 8a 3b 80 d1 70 fd dd 79 e4 93 0b B...l.;..p..y...
+0040 47 bd 3a 7e 31 66 4b 65 8d 5c 2a cd c2 09 7a 3b G.:~1fKe.\*...z;
+0050 b2 fd 09 52 09 47 05 a4 6f 32 d1 76 b2 d4 59 e0 ...R.G..o2.v..Y.
+0060 85 f1 36 7d 76 50 21 0e 20 22 83 1a 08 c0 85 5d ..6}vP!. ".....]
+0070 4f 5c 77 68 32 95 a9 a2 59 69 ea 19 34 08 ed 76 O\wh2...Yi..4..v
+0080 a3 58 37 f2 0a 0c ba 4d bb 6f 82 94 d3 87 de c9 .X7....M.o......
+0090 8f ef 34 2d 8f d0 0c 91 59 fd ea 6b cb bd a2 20 ..4-....Y..k... 
+00a0 ed b9 76 d3 64 1b b3 3b f5 9b 61 d7 ab 26 9b 0d ..v.d..;..a..&..
+00b0 a0 ea bf ad 2c ad 63 65 c6 70 c4 e5 8d 40 aa 08 ....,.ce.p...@..
+00c0 45 66 e2 4d c9 46 00 33 43 e0 ba d6 80 29 21 5e Ef.M.F.3C....)!^
+00d0 d1 9a bc 44 fa 4d 46 f9 25 80 40 b5 27 dd c5 02 ...D.MF.%.@.'...
+00e0 f8 a4 9a cb cf 3f ef c7 cd 71 45 a5 35 b1 21 14 .....?...qE.5.!.
+00f0 39 57 f8 0a 24 98 ea 15 e1 e3 cb 9d f2 4e ef 89 9W..$........N..
+0100 97 c0 b2 96 9a 1e ad d0 9a 99 62 9f 13 2e       ..........b...
+credssp_decrypt_public_key_echo: Signature for decryption:
+0000 01 00 00 00 25 f8 2d 1e 4e 6a ec 4f 00 00 00 00 ....%.-.Nj.O....
+ntlm_DecryptMessage: Data Buffer before decryption (length = 270)
+0000 03 12 dd ea 47 b3 ff e1 66 08 f6 6b a0 62 42 67 ....G...f..k.bBg
+0010 bf 3d 59 60 ef 52 b0 26 95 ed 84 48 44 bb 8d 65 .=Y`.R.&...HD..e
+0020 cf e4 8e 6f 69 ae ed 44 bb 49 1d 2a 40 29 2b 13 ...oi..D.I.*@)+.
+0030 42 1c eb b1 6c 8a 3b 80 d1 70 fd dd 79 e4 93 0b B...l.;..p..y...
+0040 47 bd 3a 7e 31 66 4b 65 8d 5c 2a cd c2 09 7a 3b G.:~1fKe.\*...z;
+0050 b2 fd 09 52 09 47 05 a4 6f 32 d1 76 b2 d4 59 e0 ...R.G..o2.v..Y.
+0060 85 f1 36 7d 76 50 21 0e 20 22 83 1a 08 c0 85 5d ..6}vP!. ".....]
+0070 4f 5c 77 68 32 95 a9 a2 59 69 ea 19 34 08 ed 76 O\wh2...Yi..4..v
+0080 a3 58 37 f2 0a 0c ba 4d bb 6f 82 94 d3 87 de c9 .X7....M.o......
+0090 8f ef 34 2d 8f d0 0c 91 59 fd ea 6b cb bd a2 20 ..4-....Y..k... 
+00a0 ed b9 76 d3 64 1b b3 3b f5 9b 61 d7 ab 26 9b 0d ..v.d..;..a..&..
+00b0 a0 ea bf ad 2c ad 63 65 c6 70 c4 e5 8d 40 aa 08 ....,.ce.p...@..
+00c0 45 66 e2 4d c9 46 00 33 43 e0 ba d6 80 29 21 5e Ef.M.F.3C....)!^
+00d0 d1 9a bc 44 fa 4d 46 f9 25 80 40 b5 27 dd c5 02 ...D.MF.%.@.'...
+00e0 f8 a4 9a cb cf 3f ef c7 cd 71 45 a5 35 b1 21 14 .....?...qE.5.!.
+00f0 39 57 f8 0a 24 98 ea 15 e1 e3 cb 9d f2 4e ef 89 9W..$........N..
+0100 97 c0 b2 96 9a 1e ad d0 9a 99 62 9f 13 2e       ..........b...
+
+ntlm_DecryptMessage: RecvRc4Seal = 0xe
+ntlm_DecryptMessage: Data Buffer after decryption (RC4(&context->RecvRc4Seal, length, data, data_buffer->pvBuffer))
+0000 31 82 01 0a 02 82 01 01 00 a8 56 65 d3 ce 8a 54 1.........Ve...T
+0010 4d 9d b0 84 31 19 71 7f dd 42 fb 2a 7a 72 13 a1 M...1.q..B.*zr..
+0020 b9 72 bb d3 08 ad 7d 6c 15 65 03 d1 c4 54 c5 33 .r....}l.e...T.3
+0030 6b 7d 69 89 5e fe e0 01 c0 7e 9b cb 5d 65 36 cd k}i.^....~..]e6.
+0040 77 5d f3 7a 5b 29 44 72 d5 38 e2 cf b1 c7 78 9b w].z[)Dr.8....x.
+0050 58 b9 17 7c b7 d6 c7 c7 bf 90 4e 7c 39 93 cb 2e X..|......N|9...
+0060 e0 c2 33 2d a5 7e e0 7b b6 f9 91 32 b7 d4 85 b7 ..3-.~.{...2....
+0070 35 2d 2b 00 6d f8 ea 8c 97 5f 51 1d 68 04 3c 79 5-+.m...._Q.h.<y
+0080 14 71 a7 c7 d7 70 7a e0 ba 12 69 c8 d3 d9 4e ab .q...pz...i...N.
+0090 51 47 a3 ec 99 d4 88 ca da c2 7f 79 4b 66 ed 87 QG.........yKf..
+00a0 be c2 5f ea cf e1 b5 f0 3d 9b f2 19 c3 e0 e1 7a .._.....=......z
+00b0 45 71 12 3d 72 1d 6f 2b 1c 46 68 c0 8f 4f ce 3a Eq.=r.o+.Fh..O.:
+00c0 c5 cd 22 65 2d 43 b0 5c dd 89 ae be 70 59 5e 0c .."e-C.\....pY^.
+00d0 bd f5 46 82 1e e4 86 95 7b 60 ae 45 50 c2 54 08 ..F.....{`.EP.T.
+00e0 49 9a 9e fb b2 b6 78 e5 2f 9c 5a d0 8a 03 77 68 I.....x./.Z...wh
+00f0 30 93 78 6d 90 6d 50 fa a7 65 fe 59 33 27 4e 4b 0.xm.mP..e.Y3'NK
+0100 f8 38 44 3a 12 f4 07 a0 8d 02 03 01 00 01       .8D:..........
+
+ntlm_DecryptMessage: RecvSigningKey:
+0000 b6 58 c5 98 7a 25 f8 6e d8 e5 6c e9 3e 3c c0 88 .X..z%.n..l.><..
+
+ntlm_DecryptMessage: digest (HMAC_MD5(RecvSigningKey, seq_num + data)), seq_num: 0
+0000 33 77 62 77 99 a9 14 40 1d 76 17 98 21 65 36 05 3wbw...@.v..!e6.
+
+ntlm_DecryptMessage: Checksum (RC4(&context->RecvRc4Seal, 8, digest, checksum), first 8 bytes of digest only!):
+0000 25 f8 2d 1e 4e 6a ec 4f                         %.-.Nj.O
+ntlm_DecryptMessage: Expected Signature (version + checksum + seq_num):
+0000 01 00 00 00 25 f8 2d 1e 4e 6a ec 4f 00 00 00 00 ....%.-.Nj.O....
+ntlm_DecryptMessage: RecvSeqNum (after increase): 1, SeqNo: 0.
+credssp_decrypt_public_key_echo: Server public key (length = 270):
+recv_seq_num: 1
+Public key after decryption:
+0000 30 82 01 0a 02 82 01 01 00 a8 56 65 d3 ce 8a 54 0.........Ve...T
+0010 4d 9d b0 84 31 19 71 7f dd 42 fb 2a 7a 72 13 a1 M...1.q..B.*zr..
+0020 b9 72 bb d3 08 ad 7d 6c 15 65 03 d1 c4 54 c5 33 .r....}l.e...T.3
+0030 6b 7d 69 89 5e fe e0 01 c0 7e 9b cb 5d 65 36 cd k}i.^....~..]e6.
+0040 77 5d f3 7a 5b 29 44 72 d5 38 e2 cf b1 c7 78 9b w].z[)Dr.8....x.
+0050 58 b9 17 7c b7 d6 c7 c7 bf 90 4e 7c 39 93 cb 2e X..|......N|9...
+0060 e0 c2 33 2d a5 7e e0 7b b6 f9 91 32 b7 d4 85 b7 ..3-.~.{...2....
+0070 35 2d 2b 00 6d f8 ea 8c 97 5f 51 1d 68 04 3c 79 5-+.m...._Q.h.<y
+0080 14 71 a7 c7 d7 70 7a e0 ba 12 69 c8 d3 d9 4e ab .q...pz...i...N.
+0090 51 47 a3 ec 99 d4 88 ca da c2 7f 79 4b 66 ed 87 QG.........yKf..
+00a0 be c2 5f ea cf e1 b5 f0 3d 9b f2 19 c3 e0 e1 7a .._.....=......z
+00b0 45 71 12 3d 72 1d 6f 2b 1c 46 68 c0 8f 4f ce 3a Eq.=r.o+.Fh..O.:
+00c0 c5 cd 22 65 2d 43 b0 5c dd 89 ae be 70 59 5e 0c .."e-C.\....pY^.
+00d0 bd f5 46 82 1e e4 86 95 7b 60 ae 45 50 c2 54 08 ..F.....{`.EP.T.
+00e0 49 9a 9e fb b2 b6 78 e5 2f 9c 5a d0 8a 03 77 68 I.....x./.Z...wh
+00f0 30 93 78 6d 90 6d 50 fa a7 65 fe 59 33 27 4e 4b 0.xm.mP..e.Y3'NK
+0100 f8 38 44 3a 12 f4 07 a0 8d 02 03 01 00 01       .8D:..........
+ntlm_EncryptMessage: data:
+0000 30 57 a0 03 02 01 01 a1 50 04 4e 30 4c a0 14 04 0W......P.N0L...
+0010 12 77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 .w.o.r.k.g.r.o.u
+0020 00 70 00 a1 1c 04 1a 41 00 64 00 6d 00 69 00 6e .p.....A.d.m.i.n
+0030 00 69 00 73 00 74 00 72 00 61 00 74 00 6f 00 72 .i.s.t.r.a.t.o.r
+0040 00 a2 16 04 14 52 00 32 00 50 00 72 00 65 00 76 .....R.2.P.r.e.v
+0050 00 69 00 65 00 77 00 21 00                      .i.e.w.!.
+
+ntlm_EncryptMessage: digest (HMAC_MD5(SendSigningKey, seq_num + data)), seq_num: 1
+0000 40 75 a0 e9 45 65 d1 78 54 1c 7e 27 08 4c 6f bd @u..Ee.xT.~'.Lo.
+
+ntlm_EncryptMessage: Data Buffer before encryption (length = 89)
+0000 30 57 a0 03 02 01 01 a1 50 04 4e 30 4c a0 14 04 0W......P.N0L...
+0010 12 77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 .w.o.r.k.g.r.o.u
+0020 00 70 00 a1 1c 04 1a 41 00 64 00 6d 00 69 00 6e .p.....A.d.m.i.n
+0030 00 69 00 73 00 74 00 72 00 61 00 74 00 6f 00 72 .i.s.t.r.a.t.o.r
+0040 00 a2 16 04 14 52 00 32 00 50 00 72 00 65 00 76 .....R.2.P.r.e.v
+0050 00 69 00 65 00 77 00 21 00                      .i.e.w.!.
+
+ntlm_EncryptMessage: SendRc4Seal = 0x6f
+ntlm_EncryptMessage: Encrypted Data Buffer (RC4(&context->SendRc4Seal, length, data, data_buffer->pvBuffer))
+0000 5a 26 69 b7 70 4b 41 55 82 43 a2 3a 72 6a e0 69 Z&i.pKAU.C.:rj.i
+0010 9b 53 66 b6 70 75 c4 80 4f 61 e6 85 20 7e 3a 1b .Sf.pu..Oa.. ~:.
+0020 a9 6a da 69 0b a5 4e 16 d9 da 71 5e ce e4 60 89 .j.i..N...q^..`.
+0030 98 e6 30 59 d0 43 38 55 4a 97 e4 20 83 cd db 6b ..0Y.C8UJ.. ...k
+0040 2b ca ac 9d 99 e6 2b ea 47 5f c1 4c 54 67 d1 75 +.....+.G_.LTg.u
+0050 2c f7 d6 d6 04 8b 28 99 e9                      ,.....(..
+
+ntlm_EncryptMessage: Checksum ( RC4(&context->SendRc4Seal, 8, digest, checksum), first 8 bytes of digest only!):
+0000 7a 7e b7 6c 49 3e 6b 7a                         z~.lI>kz
+ntlm_EncryptMessage: signature (version + checksum + seq_num)
+0000 01 00 00 00 7a 7e b7 6c 49 3e 6b 7a 01 00 00 00 ....z~.lI>kz....
+
+ntlm_EncryptMessage: SendSeqNum (after increase): 2, SeqNo: 1.
+Unable to detect time zone
+Closed from X11

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/test/doc/rdp.pfx
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/rdp.pfx b/services/console-proxy-rdp/rdpconsole/src/test/doc/rdp.pfx
new file mode 100755
index 0000000..311ca43
Binary files /dev/null and b/services/console-proxy-rdp/rdpconsole/src/test/doc/rdp.pfx differ

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java b/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
old mode 100644
new mode 100755
index 89eed8a..a40cdb8
--- a/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
+++ b/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
@@ -16,9 +16,9 @@
 // under the License.
 package rdpclient;
 
-import static rdpclient.MockServer.Packet.PacketType.CLIENT;
-import static rdpclient.MockServer.Packet.PacketType.SERVER;
-import static rdpclient.MockServer.Packet.PacketType.UPGRADE_TO_SSL;
+import static streamer.debug.MockServer.Packet.PacketType.CLIENT;
+import static streamer.debug.MockServer.Packet.PacketType.SERVER;
+import static streamer.debug.MockServer.Packet.PacketType.UPGRADE_TO_SSL;
 
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -30,160 +30,161 @@ import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
 
 import junit.framework.TestCase;
-import rdpclient.MockServer.Packet;
+import streamer.debug.MockServer;
+import streamer.debug.MockServer.Packet;
 
 public class MockServerTest extends TestCase {
 
     public void testIsMockServerCanRespond() throws Exception {
 
-	final byte[] mockClientData = new byte[] { 0x01, 0x02, 0x03 };
-	final byte[] mockServerData = new byte[] { 0x03, 0x02, 0x01 };
+        final byte[] mockClientData = new byte[] {0x01, 0x02, 0x03};
+        final byte[] mockServerData = new byte[] {0x03, 0x02, 0x01};
 
-	MockServer server = new MockServer(new Packet[] { new Packet("Client hello") {
-	    {
-		type = CLIENT;
-		data = mockClientData;
-	    }
-	}, new Packet("Server hello") {
-	    {
-		type = SERVER;
-		data = mockServerData;
-	    }
-	} });
+        MockServer server = new MockServer(new Packet[] {new Packet("Client hello") {
+            {
+                type = CLIENT;
+                data = mockClientData;
+            }
+        }, new Packet("Server hello") {
+            {
+                type = SERVER;
+                data = mockServerData;
+            }
+        }});
 
-	server.start();
+        server.start();
 
-	// Connect to server and send and receive mock data
+        // Connect to server and send and receive mock data
 
-	Socket socket = SocketFactory.getDefault().createSocket();
-	try {
-	    socket.connect(server.getAddress());
+        Socket socket = SocketFactory.getDefault().createSocket();
+        try {
+            socket.connect(server.getAddress());
 
-	    InputStream is = socket.getInputStream();
-	    OutputStream os = socket.getOutputStream();
+            InputStream is = socket.getInputStream();
+            OutputStream os = socket.getOutputStream();
 
-	    // Write mock data to server
-	    os.write(mockClientData);
+            // Write mock data to server
+            os.write(mockClientData);
 
-	    // Read data from server
-	    byte actualData[] = new byte[mockServerData.length];
-	    int actualDataLength = is.read(actualData);
+            // Read data from server
+            byte actualData[] = new byte[mockServerData.length];
+            int actualDataLength = is.read(actualData);
 
-	    // Compare mock data with actual data
-	    assertEquals("Unexpected length of actual data read from server.", mockServerData.length, actualDataLength);
+            // Compare mock data with actual data
+            assertEquals("Unexpected length of actual data read from server.", mockServerData.length, actualDataLength);
 
-	    for (int i = 0; i < actualDataLength; i++) {
-		assertEquals("Unexpected byte #" + i + " in response", mockServerData[i], actualData[i]);
-	    }
+            for (int i = 0; i < actualDataLength; i++) {
+                assertEquals("Unexpected byte #" + i + " in response", mockServerData[i], actualData[i]);
+            }
 
-	    server.waitUntilShutdowned(1 * 1000 /* up to 1 second */);
+            server.waitUntilShutdowned(1 * 1000 /* up to 1 second */);
 
-	    assertNull("Unexpected exception at mock server side.", server.getException());
-	    assertTrue("Server is not shutdowned at after conversation.", server.isShutdowned());
+            assertNull("Unexpected exception at mock server side.", server.getException());
+            assertTrue("Server is not shutdowned at after conversation.", server.isShutdowned());
 
-	} finally {
-	    socket.close();
-	}
+        } finally {
+            socket.close();
+        }
     }
 
     public void testIsMockServerCanUpgradeConnectionToSsl() throws Exception {
 
-	final byte[] mockClientData1 = new byte[] { 0x01, 0x02, 0x03 };
-	final byte[] mockServerData1 = new byte[] { 0x03, 0x02, 0x01 };
-
-	final byte[] mockClientData2 = new byte[] { 0x02, 0x04, 0x02, 0x03 };
-	final byte[] mockServerData2 = new byte[] { 0x02, 0x02, 0x01, 0x04 };
-
-	MockServer server = new MockServer(new Packet[] { new Packet("Client hello") {
-	    {
-		type = CLIENT;
-		data = mockClientData1;
-	    }
-	}, new Packet("Server hello") {
-	    {
-		type = SERVER;
-		data = mockServerData1;
-	    }
-	}, new Packet("Upgrade connection to SSL") {
-	    {
-		type = UPGRADE_TO_SSL;
-	    }
-	}, new Packet("Client data over SSL") {
-	    {
-		type = CLIENT;
-		data = mockClientData2;
-	    }
-	}, new Packet("Server data over SSL") {
-	    {
-		type = SERVER;
-		data = mockServerData2;
-	    }
-	} });
-
-	server.start();
-
-	// Connect to server and send and receive mock data
-
-	Socket socket = SocketFactory.getDefault().createSocket();
-	try {
-	    InetSocketAddress address = server.getAddress();
-	    socket.connect(address);
-
-	    // Send hello data over plain connection
-	    {
-		InputStream is = socket.getInputStream();
-		OutputStream os = socket.getOutputStream();
-
-		// Write mock data to server
-		os.write(mockClientData1);
-
-		// Read data from server
-		byte actualData[] = new byte[mockServerData1.length];
-		int actualDataLength = is.read(actualData);
-
-		// Compare mock data with actual data
-		assertEquals("Unexpected length of actual data read from server.", mockServerData1.length, actualDataLength);
-
-		for (int i = 0; i < actualDataLength; i++) {
-		    assertEquals("Unexpected byte #" + i + " in response", mockServerData1[i], actualData[i]);
-		}
-	    }
-
-	    // Upgrade connection to SSL and send mock data
-	    {
-		//System.setProperty("javax.net.debug", "ssl");
-
-		final SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
-		SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, address.getHostName(), address.getPort(), true);
-		sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
-		sslSocket.startHandshake();
-
-		InputStream is = sslSocket.getInputStream();
-		OutputStream os = sslSocket.getOutputStream();
-
-		// Write mock data to server
-		os.write(mockClientData2);
-
-		// Read data from server
-		byte actualData[] = new byte[mockServerData2.length];
-		int actualDataLength = is.read(actualData);
-
-		// Compare mock data with actual data
-		assertEquals("Unexpected length of actual data read from server.", mockServerData2.length, actualDataLength);
-
-		for (int i = 0; i < actualDataLength; i++) {
-		    assertEquals("Unexpected byte #" + i + " in response", mockServerData2[i], actualData[i]);
-		}
-
-	    }
-
-	    server.waitUntilShutdowned(1 * 1000 /* up to 1 second */);
-
-	    assertNull("Unexpected exception at mock server side.", server.getException());
-	    assertTrue("Server is not shutdowned at after conversation.", server.isShutdowned());
-	} finally {
-	    socket.close();
-	}
+        final byte[] mockClientData1 = new byte[] {0x01, 0x02, 0x03};
+        final byte[] mockServerData1 = new byte[] {0x03, 0x02, 0x01};
+
+        final byte[] mockClientData2 = new byte[] {0x02, 0x04, 0x02, 0x03};
+        final byte[] mockServerData2 = new byte[] {0x02, 0x02, 0x01, 0x04};
+
+        MockServer server = new MockServer(new Packet[] {new Packet("Client hello") {
+            {
+                type = CLIENT;
+                data = mockClientData1;
+            }
+        }, new Packet("Server hello") {
+            {
+                type = SERVER;
+                data = mockServerData1;
+            }
+        }, new Packet("Upgrade connection to SSL") {
+            {
+                type = UPGRADE_TO_SSL;
+            }
+        }, new Packet("Client data over SSL") {
+            {
+                type = CLIENT;
+                data = mockClientData2;
+            }
+        }, new Packet("Server data over SSL") {
+            {
+                type = SERVER;
+                data = mockServerData2;
+            }
+        }});
+
+        server.start();
+
+        // Connect to server and send and receive mock data
+
+        Socket socket = SocketFactory.getDefault().createSocket();
+        try {
+            InetSocketAddress address = server.getAddress();
+            socket.connect(address);
+
+            // Send hello data over plain connection
+            {
+                InputStream is = socket.getInputStream();
+                OutputStream os = socket.getOutputStream();
+
+                // Write mock data to server
+                os.write(mockClientData1);
+
+                // Read data from server
+                byte actualData[] = new byte[mockServerData1.length];
+                int actualDataLength = is.read(actualData);
+
+                // Compare mock data with actual data
+                assertEquals("Unexpected length of actual data read from server.", mockServerData1.length, actualDataLength);
+
+                for (int i = 0; i < actualDataLength; i++) {
+                    assertEquals("Unexpected byte #" + i + " in response", mockServerData1[i], actualData[i]);
+                }
+            }
+
+            // Upgrade connection to SSL and send mock data
+            {
+                //System.setProperty("javax.net.debug", "ssl");
+
+                final SSLSocketFactory sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
+                SSLSocket sslSocket = (SSLSocket)sslSocketFactory.createSocket(socket, address.getHostName(), address.getPort(), true);
+                sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
+                sslSocket.startHandshake();
+
+                InputStream is = sslSocket.getInputStream();
+                OutputStream os = sslSocket.getOutputStream();
+
+                // Write mock data to server
+                os.write(mockClientData2);
+
+                // Read data from server
+                byte actualData[] = new byte[mockServerData2.length];
+                int actualDataLength = is.read(actualData);
+
+                // Compare mock data with actual data
+                assertEquals("Unexpected length of actual data read from server.", mockServerData2.length, actualDataLength);
+
+                for (int i = 0; i < actualDataLength; i++) {
+                    assertEquals("Unexpected byte #" + i + " in response", mockServerData2[i], actualData[i]);
+                }
+
+            }
+
+            server.waitUntilShutdowned(1 * 1000 /* up to 1 second */);
+
+            assertNull("Unexpected exception at mock server side.", server.getException());
+            assertTrue("Server is not shutdowned at after conversation.", server.isShutdowned());
+        } finally {
+            socket.close();
+        }
 
     }
 }


[17/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java
old mode 100644
new mode 100755
index cc8d1f1..969dfc2
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java
@@ -16,28 +16,84 @@
 // under the License.
 package rdpclient;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import rdpclient.adapter.AwtRdpKeyboardAdapter;
+import rdpclient.adapter.AwtRdpMouseAdapter;
+import rdpclient.hyperv.ClientPreConnectionBlob;
+import rdpclient.ntlmssp.ClientNtlmsspNegotiate;
+import rdpclient.ntlmssp.ClientNtlmsspPubKeyAuth;
+import rdpclient.ntlmssp.ClientNtlmsspUserCredentials;
+import rdpclient.ntlmssp.NtlmState;
+import rdpclient.ntlmssp.ServerNtlmsspChallenge;
+import rdpclient.ntlmssp.ServerNtlmsspPubKeyPlus1;
+import rdpclient.rdp.ClientConfirmActivePDU;
+import rdpclient.rdp.ClientFastPathPDU;
+import rdpclient.rdp.ClientInfoPDU;
+import rdpclient.rdp.ClientMCSAttachUserRequest;
+import rdpclient.rdp.ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs;
+import rdpclient.rdp.ClientMCSConnectInitial;
+import rdpclient.rdp.ClientMCSErectDomainRequest;
+import rdpclient.rdp.ClientTpkt;
+import rdpclient.rdp.ClientX224ConnectionRequestPDU;
+import rdpclient.rdp.ClientX224DataPDU;
+import rdpclient.rdp.RdpConstants;
+import rdpclient.rdp.RdpState;
+import rdpclient.rdp.ServerBitmapUpdate;
+import rdpclient.rdp.ServerDemandActivePDU;
+import rdpclient.rdp.ServerFastPath;
+import rdpclient.rdp.ServerIOChannelRouter;
+import rdpclient.rdp.ServerLicenseErrorPDUValidClient;
+import rdpclient.rdp.ServerMCSAttachUserConfirmPDU;
+import rdpclient.rdp.ServerMCSConnectResponse;
+import rdpclient.rdp.ServerMCSPDU;
+import rdpclient.rdp.ServerPaletteUpdate;
+import rdpclient.rdp.ServerX224ConnectionConfirmPDU;
+import rdpclient.rdp.ServerX224DataPdu;
 import streamer.PipelineImpl;
 import streamer.Queue;
-
-import common.AwtCanvasAdapter;
+import streamer.ssl.SSLState;
+import streamer.ssl.UpgradeSocketToSSL;
 import common.AwtKeyEventSource;
 import common.AwtMouseEventSource;
 import common.BufferedImageCanvas;
 import common.ScreenDescription;
+import common.adapter.AwtCanvasAdapter;
 
 public class RdpClient extends PipelineImpl {
 
-  /**
-   * Name of last OneTimePacket in handshake sequence.
-   */
-  private static final String HANDSHAKE_END = "server_valid_client";
-
-  public RdpClient(String id, String userName, ScreenDescription screen, BufferedImageCanvas canvas) {
-    super(id);
-    assembleRDPPipeline(userName, screen, canvas);
-  }
+    /**
+     * Name of last OneTimePacket in handshake sequence.
+     */
+    private static final String HANDSHAKE_END = "server_valid_client";
+
+    /**
+     * Create new RDP or HyperV cli
+     * 
+     * @param id
+     *          id of this element
+     * @param userName
+     *          user name
+     * @param password
+     *          password
+     * @param pcb
+     *          pre-connection blob for HyperV server or null/empty string to
+     *          disable. Usually, HyperV VM ID, e.g.
+     *          "39418F90-6D03-468E-B796-91C60DD6653A".
+     * @param screen
+     *          screen description to fill
+     * @param canvas
+     *          canvas to draw on
+     * @param sslState
+     */
+    public RdpClient(String id, String serverHostName, String domain, String userName, String password, String pcb, ScreenDescription screen,
+            BufferedImageCanvas canvas, SSLState sslState) {
+        super(id);
+        assembleRDPPipeline(serverHostName, domain, userName, password, pcb, screen, canvas, sslState);
+    }
 
-//  /* DEBUG */
+    // /* DEBUG */
 //  @Override
 //  protected HashMap<String, streamer.Element> initElementMap(String id) {
 //    HashMap<String, streamer.Element> map = new HashMap<String, streamer.Element>();
@@ -46,169 +102,292 @@ public class RdpClient extends PipelineImpl {
 //    return map;
 //  }
 
-  private void assembleRDPPipeline(String userName, ScreenDescription screen, BufferedImageCanvas canvas) {
-    //
-    // Handshake chain
-    //
+    /**
+     * Assemble connection sequence and main pipeline.
+     * 
+     * Connection sequence for RDP w/o NLA: cookie(TPKT) SSL x224(TPKT)
+     * main(FastPath).
+     * 
+     * Connection sequence for RDP w NLA: cookie(TPKT) SSL credssp x224(TPKT)
+     * main(FastPath).
+     * 
+     * Connection sequence for HyperV w NLA: pcb SSL credssp cookie(TPKT)
+     * x224(TPKT) main(FastPath).
+     */
+    protected void assembleRDPPipeline(String serverHostName, String domain, String userName, String password, String pcb, ScreenDescription screen,
+            BufferedImageCanvas canvas, SSLState sslState) {
+        // If preconnection blob with VM ID is specified, then we are connecting to
+        // HyperV server
+        boolean hyperv = (pcb != null && !pcb.isEmpty());
+        // HyperV server requires NLA (CredSSP/SPNEGO/NTLMSSP) to connect, because
+        // it cannot display login screen
+        boolean credssp = hyperv || (password != null && !password.isEmpty());
 
-    RdpState state = new RdpState();
-    int[] channelsToJoin = new int[] { RdpConstants.CHANNEL_RDPRDR, RdpConstants.CHANNEL_IO };
+        String workstation;
+        try {
+            workstation = InetAddress.getLocalHost().getHostName();
+        } catch (UnknownHostException e) {
+            workstation = "workstation";
+        }
 
-    // Add elements
+        //
+        // Handshake chain
+        //
 
-    add(
+        RdpState state = new RdpState();
+        NtlmState ntlmState = new NtlmState();
 
-    new ClientX224ConnectionRequestPDU("client_connection_req", userName), new ServerX224ConnectionConfirmPDU("server_connection_conf"),
+        int[] channelsToJoin = new int[] {RdpConstants.CHANNEL_IO,
+                // RdpConstants.CHANNEL_RDPRDR, // RDPRDR channel is not used in current
+                // version
 
-    new UpgradeSocketToSSL("upgrade_to_ssl"),
+                // RdpConstants .CHANNEL_CLIPRDR // Clipboard channel is refused to join :-/
+        };
 
-    new ClientMCSConnectInitial("client_initial_conference_create"), new ServerMCSConnectResponse("server_initial_conference_create"),
+        // Add elements
 
-    new ClientMCSErectDomainRequest("client_erect_domain"),
+        // If pre-connection blob is specified, then add element to send it as
+        // first packet
+        if (hyperv) {
+            add(new ClientPreConnectionBlob("pcb", pcb));
+        }
 
-    new ClientMCSAttachUserRequest("client_atach_user"), new ServerMCSAttachUserConfirmPDU("server_atach_user_confirm", state),
+        // If password is specified, then use CredSSP/NTLM (NTLMSSP)
+        int protocol = RdpConstants.RDP_NEG_REQ_PROTOCOL_SSL;
+        if (credssp) {
+            protocol = RdpConstants.RDP_NEG_REQ_PROTOCOL_HYBRID;
 
-    new ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs("client_channel_join_rdprdr", channelsToJoin, state),
+            add(
+                    new ClientNtlmsspNegotiate("client_ntlmssp_nego", ntlmState),
 
-    new ClientInfoPDU("client_info_req", userName),
+                    new ServerNtlmsspChallenge("server_ntlmssp_challenge", ntlmState),
 
-    new ServerLicenseErrorPDUValidClient("server_valid_client"),
+                    new ClientNtlmsspPubKeyAuth("client_ntlmssp_auth", ntlmState, sslState, serverHostName, domain, workstation, userName, password),
 
-    new ServerFastPath("server_fastpath"),
+                    new ServerNtlmsspPubKeyPlus1("server_ntlmssp_confirm", ntlmState),
 
-    new ServerTpkt("server_tpkt"),
+                    new ClientNtlmsspUserCredentials("client_ntlmssp_finish", ntlmState)
 
-    new ServerX224DataPdu("server_x224_data"),
+            );
+        }
 
-    // These TPKT and X224 wrappers are connected directly to OUT for handshake
-    // sequence
-        new ClientTpkt("client_tpkt_ot"),
+        add(new ClientX224ConnectionRequestPDU("client_connection_req", userName, protocol), new ServerX224ConnectionConfirmPDU("server_connection_conf"),
+                new UpgradeSocketToSSL("upgrade_to_ssl"),
 
-        new ClientX224DataPdu("client_x224_data_ot")
+                new ClientMCSConnectInitial("client_initial_conference_create"), new ServerMCSConnectResponse("server_initial_conference_create"),
 
-    );
+                new ClientMCSErectDomainRequest("client_erect_domain"),
 
-    // Handshake sequence (via SlowPath)
-    link("IN",
+                new ClientMCSAttachUserRequest("client_atach_user"), new ServerMCSAttachUserConfirmPDU("server_atach_user_confirm", state),
 
-    "server_fastpath >tpkt", "server_tpkt",
+                new ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs("client_channel_join_rdprdr", channelsToJoin, state),
 
-    "client_connection_req", "server_connection_conf",
+                new ClientInfoPDU("client_info_req", userName),
 
-    "upgrade_to_ssl",
+                new ServerLicenseErrorPDUValidClient("server_valid_client"),
 
-    "client_initial_conference_create", "server_initial_conference_create",
+                new ServerFastPath("server_fastpath"),
 
-    "client_erect_domain",
+                // new ServerTpkt("server_tpkt"),
 
-    "server_x224_data",
+                new ServerX224DataPdu("server_x224_data"),
 
-    "client_atach_user", "server_atach_user_confirm",
+                // These TPKT and X224 wrappers are connected directly to OUT for
+                // handshake sequence
+                new ClientTpkt("client_tpkt_ot"),
 
-    "client_channel_join_rdprdr",
+                new ClientX224DataPDU("client_x224_data_ot")
 
-    "client_info_req",
+        );
 
-    "server_valid_client"
+        // If HyperV VM ID is set, then insert element which will send VM ID as
+        // first packet of connection, before other packets
+        if (hyperv) {
 
-    );
+            // HyperV: pcb SSL credssp cookie x224 main.
 
-    // Chain for direct handshake responses (without involving of queue)
-    link("client_x224_data_ot", "client_tpkt_ot", "client_tpkt_ot< OUT");
+            link("IN",
 
-    // Connect one time outputs to client TPKT input
-    String tpkt_peers[] = new String[] { "client_connection_req", "server_connection_conf", "upgrade_to_ssl", "client_x224_data_ot" };
-    for (String element : tpkt_peers) {
-      link(element + " >otout", element + "< client_tpkt_ot");
-    }
+                    // Pre Connection Blob
+                    "pcb",
 
-    // Connect one time outputs to client X224 input
-    String x224_peers[] = new String[] { "client_initial_conference_create", "server_initial_conference_create", "client_erect_domain", "client_atach_user",
-        "server_atach_user_confirm", "client_channel_join_rdprdr", "client_info_req", "server_valid_client" };
-    for (String element : x224_peers) {
-      link(element + " >otout", element + "< client_x224_data_ot");
-    }
+                    // Main (will be used after connection seq) or tpkt (to X224) 
+                    "server_fastpath >tpkt",
+
+                    // SSL
+                    "upgrade_to_ssl",
+
+                    // CredSSP
+                    "client_ntlmssp_nego", "server_ntlmssp_challenge", "client_ntlmssp_auth", "server_ntlmssp_confirm", "client_ntlmssp_finish",
+
+                    // Cookie
+                    "client_connection_req", "server_connection_conf",
+
+                    // X224
+                    "client_initial_conference_create");
+
+            for (String element : new String[] {"pcb", "client_ntlmssp_nego", "server_ntlmssp_challenge", "client_ntlmssp_auth", "server_ntlmssp_confirm",
+                    "client_ntlmssp_finish"}) {
+                link(element + " >otout", element + "< OUT");
+
+            }
+
+        } else {
+
+            // RDP: cookie SSL (credssp) x224 main.
+
+            link("IN",
+
+                    // Main or tpkt
+                    "server_fastpath >tpkt",
+
+                    // Cookie
+                    "client_connection_req", "server_connection_conf",
+
+                    // SSL
+                    "upgrade_to_ssl");
+
+            if (credssp) {
+                // SSL
+                link("upgrade_to_ssl",
+
+                        // CredSSP
+                        "client_ntlmssp_nego", "server_ntlmssp_challenge", "client_ntlmssp_auth", "server_ntlmssp_confirm", "client_ntlmssp_finish",
 
-    //
-    // Transition
-    //
+                        // X224
+                        "client_initial_conference_create");
 
-    add(
-    // To transfer packets between input threads and output thread.
-    new Queue("queue"),
+                for (String element : new String[] {"client_ntlmssp_nego", "server_ntlmssp_challenge", "client_ntlmssp_auth", "server_ntlmssp_confirm",
+                        "client_ntlmssp_finish"}) {
+                    link(element + " >otout", element + "< OUT");
 
-    // Slow path: MultiChannel Support
-        new ServerMCSPDU("server_mcs")
+                }
 
-    );
+            } else {
 
-    // Last element of handshake sequence will wake up queue and and socket
-    // output pull loop, which will switch links, between socket output and
-    // queue, from push mode to pull mode.
-    link(HANDSHAKE_END + " >queue", "queue", "OUT");
+                link(
+                        // SSL
+                        "upgrade_to_ssl",
 
-    // Transition from handshake sequence for slow path packets
-    link(HANDSHAKE_END, "server_mcs");
+                        // X224
+                        "client_initial_conference_create");
+            }
+        }
 
-    //
-    // Main network
-    //
+        link(
+                // X224
+                "client_initial_conference_create", "server_initial_conference_create",
 
-    AwtMouseEventSource mouseEventSource = new AwtMouseEventSource("mouse");
-    AwtKeyEventSource keyEventSource = new AwtKeyEventSource("keyboard");
+                "client_erect_domain",
 
-    // Subscribe packet sender to various events
-    canvas.addMouseListener(mouseEventSource);
-    canvas.addMouseMotionListener(mouseEventSource);
-    canvas.addKeyListener(keyEventSource);
+                "server_x224_data",
 
-    // Add elements
-    add(
+                "client_atach_user", "server_atach_user_confirm",
 
-    new ServerChannel1003Router("server_channel_1003", state),
+                "client_channel_join_rdprdr",
 
-    new ServerDemandActivePDU("server_demand_active", screen, state),
+                "client_info_req",
 
-    new ClientConfirmActivePDU("client_confirm_active", screen, state),
+                "server_valid_client"
 
-    new ServerBitmapUpdate("server_bitmap_update"),
+        );
 
-    new AwtCanvasAdapter("canvas_adapter", canvas, screen),
+        // Chain for direct handshake responses (without involving of queue)
+        link("client_x224_data_ot", "client_tpkt_ot", "client_tpkt_ot< OUT");
 
-    new ServerPaletteUpdate("server_palette", screen),
+        // Connect one time outputs to client TPKT input
+        String tpkt_peers[] = new String[] {"client_connection_req", "server_connection_conf", "upgrade_to_ssl", "client_x224_data_ot"};
+        for (String element : tpkt_peers) {
+            link(element + " >otout", element + "< client_tpkt_ot");
+        }
 
-    keyEventSource, new AwtRdpKeyboardAdapter("keyboard_adapter"),
+        // Connect one time outputs to client X224 input
+        String x224_peers[] = new String[] {"client_initial_conference_create", "server_initial_conference_create", "client_erect_domain", "client_atach_user",
+                "server_atach_user_confirm", "client_channel_join_rdprdr", "client_info_req", "server_valid_client"};
+        for (String element : x224_peers) {
+            link(element + " >otout", element + "< client_x224_data_ot");
+        }
 
-    mouseEventSource, new AwtRdpMouseAdapter("mouse_adapter"),
+        //
+        // Transition
+        //
 
-    // These FastPath, TPKT, and X224 wrappers are connected to queue
-        new ClientTpkt("client_tpkt_queue"),
+        add(
+                // To transfer packets between input threads and output thread.
+                new Queue("queue"),
 
-        new ClientX224DataPdu("client_x224_data_queue"),
+                // Slow path: MultiChannel Support
+                new ServerMCSPDU("server_mcs")
 
-        new ClientFastPathPDU("client_fastpath_queue"));
+        );
 
-    // Server packet handlers
-    link("server_mcs >channel_1003", "server_channel_1003");
-    link("server_fastpath >bitmap", "fastpath< server_bitmap_update", "server_bitmap_update< canvas_adapter");
-    link("server_channel_1003 >bitmap", "slowpath< server_bitmap_update");
+        // Last element of handshake sequence will wake up queue and and socket
+        // output pull loop, which will switch links, between socket output and
+        // queue, from push mode to pull mode.
+        link(HANDSHAKE_END + " >queue", "queue", "OUT");
 
-    link("server_fastpath >palette", "fastpath< server_palette");
-    link("server_channel_1003 >palette", "slowpath< server_palette");
+        // Transition from handshake sequence for slow path packets
+        link(HANDSHAKE_END, "server_mcs");
 
-    link("server_channel_1003 >demand_active", "slowpath< server_demand_active");
-    // link("server_demand_active >confirm_active", "client_confirm_active",
-    // "confirm_active< client_channel_1003");
-    link("server_demand_active >confirm_active", "client_confirm_active", "confirm_active< client_x224_data_queue");
+        //
+        // Main network
+        //
 
-    // Link mouse and keyboard to socket via adapters and send them using
-    // FastPath protocol
-    link(mouseEventSource.getId(), "mouse_adapter", "mouse_adapter< client_fastpath_queue");
-    link(keyEventSource.getId(), "keyboard_adapter", "keyboard_adapter< client_fastpath_queue");
+        AwtMouseEventSource mouseEventSource = new AwtMouseEventSource("mouse");
+        AwtKeyEventSource keyEventSource = new AwtKeyEventSource("keyboard");
 
-    // Link packet wrappers to outgoing queue
-    link("client_fastpath_queue", "client_fastpath_queue< queue");
-    link("client_x224_data_queue", "client_tpkt_queue", "client_tpkt_queue< queue");
+        // Subscribe packet sender to various events
+        canvas.addMouseListener(mouseEventSource);
+        canvas.addMouseMotionListener(mouseEventSource);
+        canvas.addKeyListener(keyEventSource);
 
-  }
+        // Add elements
+        add(
+
+                new ServerIOChannelRouter("server_io_channel", state),
+
+                new ServerDemandActivePDU("server_demand_active", screen, state),
+
+                new ClientConfirmActivePDU("client_confirm_active", screen, state),
+
+                new ServerBitmapUpdate("server_bitmap_update"),
+
+                new AwtCanvasAdapter("canvas_adapter", canvas, screen),
+
+                new ServerPaletteUpdate("server_palette", screen),
+
+                keyEventSource, new AwtRdpKeyboardAdapter("keyboard_adapter"),
+
+                mouseEventSource, new AwtRdpMouseAdapter("mouse_adapter"),
+
+                // These FastPath, TPKT, and X224 wrappers are connected to queue
+                new ClientTpkt("client_tpkt_queue"),
+
+                new ClientX224DataPDU("client_x224_data_queue"),
+
+                new ClientFastPathPDU("client_fastpath_queue"));
+
+        // Server packet handlers
+        link("server_mcs >channel_1003", "server_io_channel");
+        link("server_fastpath >bitmap", "fastpath< server_bitmap_update", "server_bitmap_update< canvas_adapter");
+        link("server_io_channel >bitmap", "slowpath< server_bitmap_update");
+
+        link("server_fastpath >palette", "fastpath< server_palette");
+        link("server_io_channel >palette", "slowpath< server_palette");
+
+        link("server_io_channel >demand_active", "slowpath< server_demand_active");
+        // link("server_demand_active >confirm_active", "client_confirm_active",
+        // "confirm_active< client_channel_1003");
+        link("server_demand_active >confirm_active", "client_confirm_active", "confirm_active< client_x224_data_queue");
+
+        // Link mouse and keyboard to socket via adapters and send them using
+        // FastPath protocol
+        link(mouseEventSource.getId(), "mouse_adapter", "mouse_adapter< client_fastpath_queue");
+        link(keyEventSource.getId(), "keyboard_adapter", "keyboard_adapter< client_fastpath_queue");
+
+        // Link packet wrappers to outgoing queue
+        link("client_fastpath_queue", "client_fastpath_queue< queue");
+        link("client_x224_data_queue", "client_tpkt_queue", "client_tpkt_queue< queue");
+
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpConstants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpConstants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpConstants.java
deleted file mode 100644
index 1e3646a..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpConstants.java
+++ /dev/null
@@ -1,74 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import java.nio.charset.Charset;
-
-public interface RdpConstants {
-
-  /**
-   * Default charset to use when communicating with server using 8 bit strings.
-   */
-  public static final Charset CHARSET_8 = Charset.availableCharsets().get("US-ASCII");
-  
-  /**
-   * Default charset to use when communicating with server using 16 bit strings.
-   */
-  public static final Charset CHARSET_16 = Charset.availableCharsets().get("UTF-16LE");
-  
-
-  /**
-   * Negotiate SSL protocol to use to protect RDP connection.
-   * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx 
-   */
-  public static final int RDP_NEG_REQ_PROTOCOL_SSL = 1;
-  
-  /**
-   * Negotiate CredSSP protocol to use to protect RDP connection.
-   * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx 
-   * When used, client must set @see RDP_NEG_REQ_PROTOCOL_SSL too.
-   */
-  public static final int RDP_NEG_REQ_PROTOCOL_HYBRID = 2;
-  
-  /**
-   * RDP negotiation: flags (not used, always 0).
-   */
-  public static final int RDP_NEG_REQ_FLAGS = 0;
-
-  /**
-   * RDP Negotiation: request.
-   */
-  public static final int RDP_NEG_REQ_TYPE_NEG_REQ = 1;
-  
-  /**
-   * RDP Negotiation: response.
-   */
-  public static final int RDP_NEG_REQ_TYPE_NEG_RSP = 2;
-  
-  /**
-   * RDP Negotiation: failure.
-   */
-  public static final int RDP_NEG_REQ_TYPE_NEG_FAILURE = 3;
-  
-
-  public static final int CHANNEL_IO = 1003;
-  
-  public static final int CHANNEL_RDPRDR = 1004;
-
-
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpState.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpState.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpState.java
deleted file mode 100644
index c85972d..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpState.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public class RdpState {
-  
-  public long serverShareId;
-  public int serverUserChannelId;
-
-  public Set<Integer> channels=new HashSet<Integer>();
-  
-  public void channelJoined(int actualChannel) {
-    channels.add(actualChannel);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerBitmapUpdate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerBitmapUpdate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerBitmapUpdate.java
deleted file mode 100644
index 0e5b79a..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerBitmapUpdate.java
+++ /dev/null
@@ -1,201 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import common.BitmapOrder;
-import common.BitmapRectangle;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.FakeSink;
-import streamer.Link;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240624.aspx
- */
-public class ServerBitmapUpdate extends BaseElement {
-  public static final int UPDATETYPE_BITMAP = 0x0001;
-
-  /**
-   * Indicates that the bitmap data is compressed. The bitmapComprHdr field MUST
-   * be present if the NO_BITMAP_COMPRESSION_HDR (0x0400) flag is not set.
-   */
-  public static final int BITMAP_COMPRESSION = 0x0001;
-
-  /**
-   * Indicates that the bitmapComprHdr field is not present (removed for
-   * bandwidth efficiency to save 8 bytes).
-   */
-  private static final int NO_BITMAP_COMPRESSION_HDR = 0x0400;
-
-  public ServerBitmapUpdate(String id) {
-    super(id);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    // * DEBUG */System.out.println(buf.toHexString(buf.length));
-
-    BitmapOrder order = new BitmapOrder();
-
-    // (2 bytes): A 16-bit, unsigned integer. The update type. This field MUST
-    // be set to UPDATETYPE_BITMAP (0x0001).
-    int updateType = buf.readSignedShortLE();
-    if (updateType != UPDATETYPE_BITMAP)
-      throw new RuntimeException("Unknown update type. Expected update type: UPDATETYPE_BITMAP (0x1). Actual update type: " + updateType + ", buf: " + buf
-          + ".");
-
-    // (2 bytes): A 16-bit, unsigned integer. The number of screen rectangles
-    // present in the rectangles field.
-    int numberRectangles = buf.readSignedShortLE();
-
-    // (variable): Variable-length array of TS_BITMAP_DATA structures, each of
-    // which contains a rectangular clipping taken from the server-side screen
-    // frame buffer. The number of screen clippings in the array is specified by
-    // the numberRectangles field.
-    BitmapRectangle[] rectangles = new BitmapRectangle[numberRectangles];
-    for (int i = 0; i < numberRectangles; i++) {
-      rectangles[i] = readRectangle(buf);
-    }
-    order.rectangles = rectangles;
-
-    buf.assertThatBufferIsFullyRead();
-
-    ByteBuffer data = new ByteBuffer(0);
-    data.setOrder(order);
-    pushDataToAllOuts(data);
-
-    buf.unref();
-  }
-
-  public BitmapRectangle readRectangle(ByteBuffer buf) {
-
-    BitmapRectangle rectangle = new BitmapRectangle();
-
-    // (2 bytes): A 16-bit, unsigned integer. Left bound of the rectangle.
-    rectangle.x = buf.readSignedShortLE();
-
-    // (2 bytes): A 16-bit, unsigned integer. Top bound of the rectangle.
-    rectangle.y = buf.readSignedShortLE();
-
-    // (2 bytes): A 16-bit, unsigned integer. Inclusive right bound of the
-    // rectangle.
-    int destRight = buf.readSignedShortLE();
-    rectangle.width=destRight-rectangle.x+1;
-
-    // (2 bytes): A 16-bit, unsigned integer. Inclusive bottom bound of the
-    // rectangle.
-    int destBottom = buf.readSignedShortLE();
-    rectangle.height=destBottom-rectangle.y+1;
-
-    // (2 bytes): A 16-bit, unsigned integer. The width of the rectangle.
-    rectangle.bufferWidth = buf.readSignedShortLE();
-
-    // (2 bytes): A 16-bit, unsigned integer. The height of the rectangle.
-    rectangle.bufferHeight = buf.readSignedShortLE();
-
-    // (2 bytes): A 16-bit, unsigned integer. The color depth of the rectangle
-    // data in bits-per-pixel.
-    rectangle.colorDepth = buf.readSignedShortLE();
-
-    // (2 bytes): A 16-bit, unsigned integer. The flags describing the format of
-    // the bitmap data in the bitmapDataStream field.
-    int flags = buf.readSignedShortLE();
-
-    // BITMAP_COMPRESSION 0x0001
-    // Indicates that the bitmap data is compressed. The bitmapComprHdr field
-    // MUST be present if the NO_BITMAP_COMPRESSION_HDR (0x0400) flag is not
-    // set.
-    boolean compressed=((flags & BITMAP_COMPRESSION) > 0);
-
-    // (2 bytes): A 16-bit, unsigned integer. The size in bytes of the data in
-    // the bitmapComprHdr and bitmapDataStream fields.
-    int bitmapLength = buf.readSignedShortLE();
-
-    // NO_BITMAP_COMPRESSION_HDR 0x0400
-    // Indicates that the bitmapComprHdr field is not present (removed for
-    // bandwidth efficiency to save 8 bytes).
-    if (compressed && (flags & NO_BITMAP_COMPRESSION_HDR) == 0) {
-      // (8 bytes): Optional Compressed Data Header structure specifying the
-      // bitmap data in the bitmapDataStream.
-      // This field MUST be present if the BITMAP_COMPRESSION (0x0001) flag is
-      // present in the Flags field, but the NO_BITMAP_COMPRESSION_HDR (0x0400)
-      // flag is not.
-
-      // Note: Even when compression header is enabled, server sends nothing.
-      // rectangle.compressedBitmapHeader = buf.readBytes(8);
-    }
-
-    // (variable): A variable-length array of bytes describing a bitmap image.
-    // Bitmap data is either compressed or uncompressed, depending on whether
-    // the BITMAP_COMPRESSION flag is present in the Flags field. Uncompressed
-    // bitmap data is formatted as a bottom-up, left-to-right series of pixels.
-    // Each pixel is a whole number of bytes. Each row contains a multiple of
-    // four bytes (including up to three bytes of padding, as necessary).
-    // Compressed bitmaps not in 32 bpp format are compressed using Interleaved
-    // RLE and encapsulated in an RLE Compressed Bitmap Stream structure,
-    // while compressed bitmaps at a color depth of 32 bpp are compressed
-    // using RDP 6.0 Bitmap Compression and stored inside
-    // an RDP 6.0 Bitmap Compressed Stream structure.
-    if (!compressed) {
-      rectangle.bitmapDataStream = buf.readBytes(bitmapLength);
-    } else {
-      ByteBuffer compressedImage = buf.readBytes(bitmapLength);
-      //* DEBUG */System.out.println("Compressed image: " + compressedImage + ", depth: " + rectangle.bitsPerPixel + ".");
-      rectangle.bitmapDataStream = RLEBitmapDecompression.rleDecompress(compressedImage, rectangle.bufferWidth, rectangle.bufferHeight, rectangle.colorDepth);
-      compressedImage.unref();
-    }
-
-    return rectangle;
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    ByteBuffer packet = new ByteBuffer(new byte[] { 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x00,
-        0x01, 0x04, 0x0a, 0x00, 0x0c, (byte) 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
-
-    Element bitmap = new ServerBitmapUpdate("bitmap") {
-      {
-        verbose = true;
-      }
-    };
-    FakeSink fakeSink = new FakeSink("sink") {
-      {
-        verbose = true;
-      }
-    };
-    Pipeline pipeline = new PipelineImpl("test");
-
-    // BufferedImageCanvas canvas = new BufferedImageCanvas(1024, 768);
-    // Element adapter = new AwtRdpAdapter("test",canvas );
-    // pipeline.addAndLink(bitmap, adapter);
-    pipeline.addAndLink(bitmap, fakeSink);
-
-    bitmap.handleData(packet, null);
-
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerChannel1003Router.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerChannel1003Router.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerChannel1003Router.java
deleted file mode 100644
index fdad522..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerChannel1003Router.java
+++ /dev/null
@@ -1,530 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class ServerChannel1003Router extends BaseElement {
-
-  /**
-   * Demand Active PDU.
-   */
-  public static final int PDUTYPE_DEMANDACTIVEPDU = 0x1;
-
-  /**
-   * Confirm Active PDU.
-   */
-  public static final int PDUTYPE_CONFIRMACTIVEPDU = 0x3;
-
-  /**
-   * Deactivate All PDU.
-   */
-  public static final int PDUTYPE_DEACTIVATEALLPDU = 0x6;
-
-  /**
-   * Data PDU (actual type is revealed by the pduType2 field in the Share Data
-   * Header).
-   */
-  public static final int PDUTYPE_DATAPDU = 0x7;
-
-  /**
-   * Enhanced Security Server Redirection PDU.
-   */
-  public static final int PDUTYPE_SERVER_REDIR_PKT = 0xA;
-
-  protected RdpState state;
-
-  public ServerChannel1003Router(String id, RdpState state) {
-    super(id);
-    this.state=state;
-  }
-
-  /**
-   * @see http://msdn.microsoft.com/en-us/library/cc240576.aspx
-   */
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    int length = buf.readUnsignedShortLE();
-    if(buf.length!=length)
-    {
-      // It is ServerErrorAlert-ValidClient
-      // Ignore it
-      //throw new RuntimeException("[" + this + "] ERROR: Incorrect PDU length: " + length + ", data: " + buf + ".");
-    }
-
-    int type = buf.readUnsignedShortLE() & 0xf;
-
-    // int sourceId = buf.readUnsignedShortLE();
-    buf.skipBytes(2);
-
-    switch (type) {
-    case PDUTYPE_DEMANDACTIVEPDU:
-      pushDataToPad("demand_active", buf);
-      break;
-    case PDUTYPE_CONFIRMACTIVEPDU:
-      throw new RuntimeException("Unexpected client CONFIRM ACTIVE PDU. Data: " + buf + ".");
-    case PDUTYPE_DEACTIVATEALLPDU:
-      // pushDataToPad("deactivate_all", buf);
-      /* ignore */buf.unref();
-      break;
-    case PDUTYPE_DATAPDU:
-      handleDataPdu(buf);
-      break;
-    case PDUTYPE_SERVER_REDIR_PKT:
-      // pushDataToPad("server_redir", buf);
-      /* ignore */buf.unref();
-      break;
-    default:
-      throw new RuntimeException("[" + this + "] ERROR: Unknown PDU type: " + type + ", data: " + buf + ".");
-    }
-
-  }
-
-  /**
-   * Graphics Update PDU.
-   */
-  public static final int PDUTYPE2_UPDATE = 0x02;
-
-  /**
-   * Control PDU.
-   */
-  public static final int PDUTYPE2_CONTROL = 0x14;
-
-  /**
-   * Pointer Update PDU.
-   */
-  public static final int PDUTYPE2_POINTER = 0x1B;
-
-  /**
-   * Input Event PDU.
-   */
-  public static final int PDUTYPE2_INPUT = 0x1C;
-
-  /**
-   * Synchronize PDU.
-   */
-  public static final int PDUTYPE2_SYNCHRONIZE = 0x1F;
-
-  /**
-   * Refresh Rect PDU.
-   */
-  public static final int PDUTYPE2_REFRESH_RECT = 0x21;
-
-  /**
-   * Play Sound PDU.
-   */
-  public static final int PDUTYPE2_PLAY_SOUND = 0x22;
-
-  /**
-   * Suppress Output PDU.
-   */
-  public static final int PDUTYPE2_SUPPRESS_OUTPUT = 0x23;
-
-  /**
-   * Shutdown Request PDU.
-   */
-  public static final int PDUTYPE2_SHUTDOWN_REQUEST = 0x24;
-
-  /**
-   * Shutdown Request Denied PDU.
-   */
-  public static final int PDUTYPE2_SHUTDOWN_DENIED = 0x25;
-
-  /**
-   * Save Session Info PDU.
-   */
-  public static final int PDUTYPE2_SAVE_SESSION_INFO = 0x26;
-
-  /**
-   * Font List PDU.
-   */
-  public static final int PDUTYPE2_FONTLIST = 0x27;
-
-  /**
-   * Font Map PDU.
-   */
-  public static final int PDUTYPE2_FONTMAP = 0x28;
-
-  /**
-   * Set Keyboard Indicators PDU.
-   */
-  public static final int PDUTYPE2_SET_KEYBOARD_INDICATORS = 0x29;
-
-  /**
-   * Persistent Key List PDU.
-   */
-  public static final int PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST = 0x2B;
-
-  /**
-   * Bitmap Cache Error PDU.
-   */
-  public static final int PDUTYPE2_BITMAPCACHE_ERROR_PDU = 0x2C;
-
-  /**
-   * Set Keyboard IME Status PDU.
-   */
-  public static final int PDUTYPE2_SET_KEYBOARD_IME_STATUS = 0x2D;
-
-  /**
-   * Offscreen Bitmap Cache Error PDU.
-   */
-  public static final int PDUTYPE2_OFFSCRCACHE_ERROR_PDU = 0x2E;
-
-  /**
-   * Set Error Info PDU.
-   */
-  public static final int PDUTYPE2_SET_ERROR_INFO_PDU = 0x2F;
-
-  /**
-   * DrawNineGrid Cache Error PDU.
-   */
-  public static final int PDUTYPE2_DRAWNINEGRID_ERROR_PDU = 0x30;
-
-  /**
-   * GDI+ Error PDU.
-   */
-  public static final int PDUTYPE2_DRAWGDIPLUS_ERROR_PDU = 0x31;
-
-  /**
-   * Auto-Reconnect Status PDU.
-   */
-  public static final int PDUTYPE2_ARC_STATUS_PDU = 0x32;
-
-  /**
-   * Status Info PDU.
-   */
-  public static final int PDUTYPE2_STATUS_INFO_PDU = 0x36;
-
-  /**
-   * Monitor Layout PDU.
-   */
-  public static final int PDUTYPE2_MONITOR_LAYOUT_PDU = 0x37;
-
-  /**
-   * Indicates an Orders Update.
-   */
-  public static final int UPDATETYPE_ORDERS = 0x0000;
-
-  /**
-   * Indicates a Bitmap Graphics Update.
-   */
-  public static final int UPDATETYPE_BITMAP = 0x0001;
-
-  /**
-   * Indicates a Palette Update.
-   */
-  public static final int UPDATETYPE_PALETTE = 0x0002;
-
-  /**
-   * Indicates a Synchronize Update.
-   */
-  public static final int UPDATETYPE_SYNCHRONIZE = 0x0003;
-
-  /**
-   * @see http://msdn.microsoft.com/en-us/library/cc240577.aspx
-   */
-  protected void handleDataPdu(ByteBuffer buf) {
-
-    // (4 bytes): A 32-bit, unsigned integer. Share identifier for the packet.
-     long shareId = buf.readUnsignedIntLE();
-     if(shareId!=state.serverShareId)
-       throw new RuntimeException("Unexpected share ID: "+shareId+".");
-//    buf.skipBytes(4);
-
-    // Padding.
-    buf.skipBytes(1);
-
-    // (1 byte): An 8-bit, unsigned integer. The stream identifier for the
-    // packet.
-    // int streamId = buf.readUnsignedByte();
-    buf.skipBytes(1);
-
-    // (2 bytes): A 16-bit, unsigned integer. The uncompressed length of the
-    // packet in bytes.
-    int uncompressedLength = buf.readUnsignedShortLE();
-
-    // (1 byte): An 8-bit, unsigned integer. The type of Data PDU.
-    int type2 = buf.readUnsignedByte();
-
-    // (1 byte): An 8-bit, unsigned integer. The compression type and flags
-    // specifying the data following the Share Data Header
-    int compressedType = buf.readUnsignedByte();
-    if (compressedType != 0)
-      throw new RuntimeException("Compression of protocol packets is not supported. Data: " + buf + ".");
-
-    // (2 bytes): A 16-bit, unsigned integer. The compressed length of the
-    // packet in bytes.
-    int compressedLength = buf.readUnsignedShortLE();
-    if (compressedLength != 0)
-      throw new RuntimeException("Compression of protocol packets is not supported. Data: " + buf + ".");
-
-    ByteBuffer data = buf.readBytes(uncompressedLength-18);
-    buf.unref();
-
-    switch (type2) {
-
-    case PDUTYPE2_UPDATE: {
-
-      // (2 bytes): A 16-bit, unsigned integer. Type of the graphics update.
-      int updateType = data.readUnsignedShortLE();
-      ByteBuffer data2 = data.readBytes(data.length - data.cursor);
-      data.unref();
-
-      switch (updateType) {
-      case UPDATETYPE_ORDERS:
-        pushDataToPad("orders", data2);
-        break;
-      case UPDATETYPE_BITMAP:
-        pushDataToPad("bitmap", data2);
-        break;
-      case UPDATETYPE_PALETTE:
-        pushDataToPad("palette", data2);
-        break;
-      case UPDATETYPE_SYNCHRONIZE:
-        // Ignore
-        data2.unref();
-        break;
-      }
-
-      break;
-    }
-    case PDUTYPE2_CONTROL:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_CONTROL ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_POINTER:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_POINTER ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_INPUT:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_INPUT ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_SYNCHRONIZE:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SYNCHRONIZE ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_REFRESH_RECT:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_REFRESH_RECT ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_PLAY_SOUND:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_PLAY_SOUND ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_SUPPRESS_OUTPUT:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SUPPRESS_OUTPUT ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_SHUTDOWN_REQUEST:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SHUTDOWN_REQUEST ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_SHUTDOWN_DENIED:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SHUTDOWN_DENIED ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_SAVE_SESSION_INFO:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SAVE_SESSION_INFO ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_FONTLIST:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_FONTLIST ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_FONTMAP:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_FONTMAP ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_SET_KEYBOARD_INDICATORS:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SET_KEYBOARD_INDICATORS ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_BITMAPCACHE_ERROR_PDU:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_BITMAPCACHE_ERROR_PDU ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_SET_KEYBOARD_IME_STATUS:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SET_KEYBOARD_IME_STATUS ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_OFFSCRCACHE_ERROR_PDU:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_OFFSCRCACHE_ERROR_PDU ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_SET_ERROR_INFO_PDU:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SET_ERROR_INFO_PDU ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_DRAWNINEGRID_ERROR_PDU:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_DRAWNINEGRID_ERROR_PDU ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_DRAWGDIPLUS_ERROR_PDU:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_DRAWGDIPLUS_ERROR_PDU ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_ARC_STATUS_PDU:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_ARC_STATUS_PDU ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_STATUS_INFO_PDU:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_STATUS_INFO_PDU ignored.");
-      // Ignore
-      data.unref();
-      break;
-    case PDUTYPE2_MONITOR_LAYOUT_PDU:
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Packet PDUTYPE2_MONITOR_LAYOUT_PDU ignored.");
-      // Ignore
-      data.unref();
-      break;
-
-    default:
-      throw new RuntimeException("Unknow data PDU type: " + type2 + ", data: " + buf + ".");
-    }
-  }
-
-  /**
-   * Example.
-   * 
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    byte[] packet = new byte[] {
-        // TPKT
-        (byte) 0x03, (byte) 0x00, // TPKT Header: TPKT version = 3
-        (byte) 0x00, (byte) 0x1B, // TPKT length: 27 bytes
-
-        // X224
-        (byte) 0x02, // X224 Length: 2 bytes
-        (byte) 0xF0, // X224 Type: Data
-        (byte) 0x80, // X224 EOT
-
-        // MCS
-        // Type: send data indication: 26 (0x1a, top 6 bits)
-        (byte) 0x68, // ??
-
-        (byte) 0x00, (byte) 0x01, // User ID: 1002 (1001+1)
-        (byte) 0x03, (byte) 0xEB, // Channel ID: 1003
-        (byte) 0x70, // Data priority: high, segmentation: begin|end
-        (byte) 0x0D, // Payload length: 13 bytes
-
-        // Deactivate all PDU
-        (byte) 0x0D, (byte) 0x00, // Length: 13 bytes (LE)
-
-        // - PDUType: (0x16, LE)
-        // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
-        // ProtocolVersion: (000000000001....) 1
-        (byte) 0x16, (byte) 0x00,
-
-        (byte) 0xEA, (byte) 0x03, // PDU source: 1002 (LE)
-        (byte) 0xEA, (byte) 0x03, (byte) 0x01, (byte) 0x00, // ShareID = 66538
-
-        (byte) 0x01, (byte) 0x00, // Length if source descriptor: 1 (LE)
-        (byte) 0x00, // Source descriptor (should be set to 0): 0
-    };
-
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
-    RdpState rdpState =new RdpState() {{serverShareId=66538;}};
-    Element channel1003 = new ServerChannel1003Router("channel_1003", rdpState );
-    Element mcs = new ServerMCSPDU("mcs");
-    Element tpkt = new ServerTpkt("tpkt");
-    Element x224 = new ServerX224DataPdu("x224");
-    Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
-        // Deactivate all PDU
-        (byte) 0x0D, (byte) 0x00, // Length: 13 bytes (LE)
-
-        // - PDUType: 22 (0x16, LE)
-        // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
-        // ProtocolVersion: (000000000001....) 1
-        (byte) 0x16, (byte) 0x00,
-
-        (byte) 0xEA, (byte) 0x03, // PDU source: 1002 (LE)
-        (byte) 0xEA, (byte) 0x03, (byte) 0x01, (byte) 0x00, // ShareID = 66538
-
-        (byte) 0x01, (byte) 0x00, // Length if source descriptor: 1 (LE)
-        (byte) 0x00, // Source descriptor (should be set to 0): 0
-    }));
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, tpkt, x224, mcs, channel1003, sink);
-    pipeline.link("source", "tpkt", "x224", "mcs >channel_1003", "channel_1003 >deactivate_all", "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUCooperate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUCooperate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUCooperate.java
deleted file mode 100644
index f2d3d36..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUCooperate.java
+++ /dev/null
@@ -1,117 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-public class ServerControlPDUCooperate  extends OneTimeSwitch {
-
-  public ServerControlPDUCooperate(String id) {
-    super(id);
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-    
-    // Ignore packet
-    buf.unref();
-    switchOff();
-  }
-
-}
-
-/* @formatter:off */
-/*
-03 00 00 28 02 F0 80 68 00 01 03 EB 70 1A 1A 00 17 00 EA 03 EA 03 01 00 9A 02 1A 00 14 00 00 00 04 00 00 00 00 00 00 00 
-
-
-  Frame: Number = 38, Captured Frame Length = 97, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 40
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 40 (0x28)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: Data Packet
-  - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
-   - Type: Send Data Indication
-    - RootIndex: 26
-       Value: (011010..) 0x1a
-   - UserID: 0x3ea
-    - UserID: 0x3ea
-     - ChannelId: 1002
-      - Align: No Padding
-         Padding2: (00......) 0x0
-        Value: 1 (0x1)
-   - Channel: 0x3eb
-    - ChannelId: 1003
-       Align: No Padding
-       Value: 1003 (0x3EB)
-   - DataPriority: high
-    - DataPriority: high
-     - RootIndex: 1
-        Value: (01......) 0x1
-   - Segmentation: Begin End
-      Begin: (1.......) Begin
-      End:   (.1......) End
-   - Length: 26
-    - Align: No Padding
-       Padding4: (0000....) 0x0
-      Length: 26
-    RDP: RDPBCGR
-- RDPBCGR: TsControlPDU
-  - SlowPathPacket: TsControlPDU 
-   - SlowPath: Type = TS_PDUTYPE_DATAPDU
-    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
-       TotalLength: 26 (0x1A)
-     - PDUType: 23 (0x17)
-        Type:            (............0111) TS_PDUTYPE_DATAPDU
-        ProtocolVersion: (000000000001....) 1
-       PDUSource: 1002 (0x3EA)
-    - SlowPathIoPacket: 0x0
-     - ShareDataHeader: TS_PDUTYPE2_CONTROL
-        ShareID: 66538 (0x103EA)
-        Pad1: 154 (0x9A)
-        StreamID: TS_STREAM_MED
-        UncompressedLength: 26 (0x1A)
-        PDUType2: TS_PDUTYPE2_CONTROL
-      - CompressedType: Not Compressed
-         MPPC:       (....0000) MPPC 8K
-         Reserved:   (...0....)
-         Compressed: (..0.....) Not Compressed
-         Front:      (.0......) Not At Front
-         Flush:      (0.......) Not Flushed
-        CompressedLength: 0 (0x0)
-     - TsControlPDU: Action = Cooperate
-        Action: Cooperate
-        GrantID: 0 (0x0)
-        ControlID: 0 (0x0)
-
- */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUGrantedControl.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUGrantedControl.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUGrantedControl.java
deleted file mode 100644
index e050e8a..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUGrantedControl.java
+++ /dev/null
@@ -1,114 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-public class ServerControlPDUGrantedControl  extends OneTimeSwitch {
-
-  public ServerControlPDUGrantedControl(String id) {
-    super(id);
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-    
-    // Ignore packet
-    buf.unref();
-    switchOff();
-  }
-
-}
-/* @formatter:off */
-/*
-03 00 00 28 02 F0 80 68 00 01 03 EB 70 1A 1A 00 17 00 EA 03 EA 03 01 00 50 02 1A 00 14 00 00 00 02 00 EC 03 EA 03 00 00 
-
-  Frame: Number = 45, Captured Frame Length = 97, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 40
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 40 (0x28)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: Data Packet
-  - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
-   - Type: Send Data Indication
-    - RootIndex: 26
-       Value: (011010..) 0x1a
-   - UserID: 0x3ea
-    - UserID: 0x3ea
-     - ChannelId: 1002
-      - Align: No Padding
-         Padding2: (00......) 0x0
-        Value: 1 (0x1)
-   - Channel: 0x3eb
-    - ChannelId: 1003
-       Align: No Padding
-       Value: 1003 (0x3EB)
-   - DataPriority: high
-    - DataPriority: high
-     - RootIndex: 1
-        Value: (01......) 0x1
-   - Segmentation: Begin End
-      Begin: (1.......) Begin
-      End:   (.1......) End
-   - Length: 26
-    - Align: No Padding
-       Padding4: (0000....) 0x0
-      Length: 26
-    RDP: RDPBCGR
-- RDPBCGR: TsControlPDU
-  - SlowPathPacket: TsControlPDU 
-   - SlowPath: Type = TS_PDUTYPE_DATAPDU
-    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
-       TotalLength: 26 (0x1A)
-     - PDUType: 23 (0x17)
-        Type:            (............0111) TS_PDUTYPE_DATAPDU
-        ProtocolVersion: (000000000001....) 1
-       PDUSource: 1002 (0x3EA)
-    - SlowPathIoPacket: 0x0
-     - ShareDataHeader: TS_PDUTYPE2_CONTROL
-        ShareID: 66538 (0x103EA)
-        Pad1: 80 (0x50)
-        StreamID: TS_STREAM_MED
-        UncompressedLength: 26 (0x1A)
-        PDUType2: TS_PDUTYPE2_CONTROL
-      - CompressedType: Not Compressed
-         MPPC:       (....0000) MPPC 8K
-         Reserved:   (...0....)
-         Compressed: (..0.....) Not Compressed
-         Front:      (.0......) Not At Front
-         Flush:      (0.......) Not Flushed
-        CompressedLength: 0 (0x0)
-     - TsControlPDU: Action = Granted Control
-        Action: Granted Control
-        GrantID: 1004 (0x3EC)
-        ControlID: 1002 (0x3EA)
- */


[07/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSAttachUserConfirmPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSAttachUserConfirmPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSAttachUserConfirmPDU.java
new file mode 100755
index 0000000..09b4129
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSAttachUserConfirmPDU.java
@@ -0,0 +1,116 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * Server response to MCS Attach User request.
+ * 
+ * Once the User Channel ID has been extracted, the client MUST send an MCS
+ * Channel Join Request PDU for the user channel.
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc240685.aspx
+ */
+public class ServerMCSAttachUserConfirmPDU extends OneTimeSwitch {
+
+    public static final int MCS_ATTACH_USER_CONFIRM_PDU = 0xb;
+
+    public static final int INITIATOR_PRESENT = 0x2;
+
+    protected RdpState state;
+
+    public ServerMCSAttachUserConfirmPDU(String id, RdpState state) {
+        super(id);
+        this.state = state;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        int typeAndFlags = buf.readUnsignedByte();
+        int type = typeAndFlags >> 2;
+        int flags = typeAndFlags & 0x3;
+
+        if (type != MCS_ATTACH_USER_CONFIRM_PDU)
+            throw new RuntimeException("[" + this + "] ERROR: Incorrect type of MCS AttachUserConfirm PDU. Expected value: 11, actual value: " + type + ", data: " + buf + ".");
+
+        if (flags != INITIATOR_PRESENT)
+            throw new RuntimeException("Initator field is not present in MCS AttachUserConfirm PDU. Data: " + buf + ".");
+
+        int rtSuccess = buf.readUnsignedByte() >> 4;
+        if (rtSuccess != 0)
+            throw new RuntimeException("[" + this + "] ERROR: Cannot attach user: request failed. Error code: " + rtSuccess + ", data: " + buf + ".");
+
+        // If the initiator field is present, the client stores the value of the
+        // initiator in the User Channel ID store , because the initiator specifies
+        // the User Channel ID.
+        state.serverUserChannelId = buf.readUnsignedShort() + 1001;
+
+        buf.unref();
+
+        // Next: client MCS Channel Join Request PDU (s)
+        switchOff();
+    }
+
+    /**
+     * Example.
+     */
+    /**
+     * Example.
+     * 
+     * @see http://msdn.microsoft.com/en-us/library/cc240842.aspx
+     * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        byte[] packet = new byte[] {(byte)0x2E, // MCS user confirm (001011..,
+                                                // 0xb), InitiatorPresent: 1
+                                                // (......01, 0x1)
+                (byte)0x00, // RT successfull (0000...., 0x0)
+                // Initiator: 1001+3 = 1004
+                (byte)0x00, (byte)0x03,};
+
+        RdpState rdpState = new RdpState();
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet, new byte[] {1, 2, 3}));
+        Element atachUserConfirm = new ServerMCSAttachUserConfirmPDU("attach_user_confirm", rdpState);
+        Element sink = new MockSink("sink");
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, atachUserConfirm, sink, mainSink);
+        pipeline.link("source", "attach_user_confirm", "mainSink");
+        pipeline.link("attach_user_confirm >" + OTOUT, "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        if (rdpState.serverUserChannelId != 1004)
+            System.err.println("Incorrect user channel ID. Expected value: 1004, actual value: " + rdpState.serverUserChannelId + ".");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSChannelJoinConfirmPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSChannelJoinConfirmPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSChannelJoinConfirmPDU.java
new file mode 100755
index 0000000..1aa4a86
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSChannelJoinConfirmPDU.java
@@ -0,0 +1,89 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ServerMCSChannelJoinConfirmPDU extends OneTimeSwitch {
+
+    protected int channel;
+
+    public ServerMCSChannelJoinConfirmPDU(String id, int channel) {
+        super(id);
+        this.channel = channel;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Ignore packet
+        buf.unref();
+        switchOff();
+    }
+
+}
+
+/*
+ * 03 00 00 0F 02 F0 80 3E 00 00 03 03 EC 03 EC 
+
+  Frame: Number = 22, Captured Frame Length = 72, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 15
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 15 (0xF)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: Channel Join Confirm, ChannelId = 1004, Result = rt-successful
+  - MCSHeader: Type=Channel Join Confirm
+   - Type: Channel Join Confirm
+    - RootIndex: 15
+       Value: (001111..) 0xf
+  - MCSChannelJoinConfirm: ChannelId = 1004, Result = rt-successful
+     ChannelIdPresent: 1 (0x1)
+   - Result: rt-successful
+    - Result: rt-successful
+     - RootIndex: 0
+        Value: (0000....) 0x0
+   - Initiator: 0x3ec
+    - UserID: 0x3ec
+     - ChannelId: 1004
+      - Align: No Padding
+         Padding5: (00000...) 0x0
+        Value: 3 (0x3)
+   - Requested: 0x3ec
+    - ChannelId: 1004
+       Align: No Padding
+       Value: 1004 (0x3EC)
+   - ChannelId: 0x3ec
+    - ChannelId: 1004
+       Align: No Padding
+       Value: 1004 (0x3EC)
+ 
+ */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSConnectResponse.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSConnectResponse.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSConnectResponse.java
new file mode 100755
index 0000000..686c939
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSConnectResponse.java
@@ -0,0 +1,283 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+/**
+ * Once the basic server settings data blocks have been processed successfully, the client MUST send the MCS Attach User Request PDU to the server.
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc240682.aspx
+ */
+public class ServerMCSConnectResponse extends OneTimeSwitch {
+
+    public ServerMCSConnectResponse(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Ignore packet
+        buf.unref();
+        switchOff();
+    }
+
+}
+
+/*
+ * @formatter:off
+ * 03 00 00 64 02 F0 80 7F 66 5A 0A 01 00 02 01 00 30 1A 02 01 22 02 01 03 02 01 00 02 01 01 02 01 00 02 01 01 02 03 00 FF F8 02 01 02 04 36 00 05 00 14 7C 00 01 2A 14 76 0A 01 01 00 01 C0 00 4D 63 44 6E 20 01 0C 0C 00 04 00 08 00 01 00 00 00 03 0C 08 00 EB 03 00 00 02 0C 0C 00 00 00 00 00 00 00 00 00 
+
+  Frame: Number = 12, Captured Frame Length = 157, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 100
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 100 (0x64)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: MCSConnect Response
+  - MCSConnectResponse: Result = rt-successful
+   - ConnectResponseHeader: 
+    - AsnId: Application Constructed Tag (102)
+     - HighTag: 
+        Class:     (01......) Application (1)
+        Type:      (..1.....) Constructed
+        TagNumber: (...11111)
+        TagValueEnd: 102 (0x66)
+    - AsnLen: Length = 90, LengthOfLength = 0
+       Length: 90 bytes, LengthOfLength = 0
+   - Result: rt-successful
+    - Value: 0
+     - AsnIntegerHeader: 
+      - AsnId: Enumerated type (Universal 10)
+       - LowTag: 
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...01010) 10
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 0 (0x0)
+   - CalledConnectId: 0
+    - AsnIntegerHeader: 
+     - AsnId: Integer type (Universal 2)
+      - LowTag: 
+         Class:    (00......) Universal (0)
+         Type:     (..0.....) Primitive
+         TagValue: (...00010) 2
+     - AsnLen: Length = 1, LengthOfLength = 0
+        Length: 1 bytes, LengthOfLength = 0
+      AsnInt: 0 (0x0)
+   - DomainParameters: Length = 26, LengthOfLength = 0
+    - DomainParametersHeader: 0x1
+     - AsnId: Sequence and SequenceOf types (Universal 16)
+      - LowTag: 
+         Class:    (00......) Universal (0)
+         Type:     (..1.....) Constructed
+         TagValue: (...10000) 16
+     - AsnLen: Length = 26, LengthOfLength = 0
+        Length: 26 bytes, LengthOfLength = 0
+    - ChannelIds: 34
+     - AsnIntegerHeader: 
+      - AsnId: Integer type (Universal 2)
+       - LowTag: 
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 34 (0x22)
+    - UserIDs: 3
+     - AsnIntegerHeader: 
+      - AsnId: Integer type (Universal 2)
+       - LowTag: 
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 3 (0x3)
+    - TokenIds: 0
+     - AsnIntegerHeader: 
+      - AsnId: Integer type (Universal 2)
+       - LowTag: 
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 0 (0x0)
+    - NumPriorities: 1
+     - AsnIntegerHeader: 
+      - AsnId: Integer type (Universal 2)
+       - LowTag: 
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 1 (0x1)
+    - MinThroughput: 0
+     - AsnIntegerHeader: 
+      - AsnId: Integer type (Universal 2)
+       - LowTag: 
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 0 (0x0)
+    - Height: 1
+     - AsnIntegerHeader: 
+      - AsnId: Integer type (Universal 2)
+       - LowTag: 
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 1 (0x1)
+    - MCSPDUsize: 65528
+     - AsnIntegerHeader: 
+      - AsnId: Integer type (Universal 2)
+       - LowTag: 
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 3, LengthOfLength = 0
+         Length: 3 bytes, LengthOfLength = 0
+       AsnInt: 65528 (0xFFF8)
+    - protocolVersion: 2
+     - AsnIntegerHeader: 
+      - AsnId: Integer type (Universal 2)
+       - LowTag: 
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 2 (0x2)
+   - UserData: Identifier = Generic Conference Contro (0.0.20.124.0.1)
+    - UserDataHeader: 
+     - AsnId: OctetString type (Universal 4)
+      - LowTag: 
+         Class:    (00......) Universal (0)
+         Type:     (..0.....) Primitive
+         TagValue: (...00100) 4
+     - AsnLen: Length = 54, LengthOfLength = 0
+        Length: 54 bytes, LengthOfLength = 0
+    - AsnBerObjectIdentifier: Generic Conference Control (0.0.20.124.0.1)
+     - AsnObjectIdentifierHeader: 
+      - AsnId: Reserved for use by the encoding rules (Universal 0)
+       - LowTag: 
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00000) 0
+      - AsnLen: Length = 5, LengthOfLength = 0
+         Length: 5 bytes, LengthOfLength = 0
+       First: 0 (0x0)
+       Final: 20 (0x14)
+       Final: 124 (0x7C)
+       Final: 0 (0x0)
+       Final: 1 (0x1)
+    - ConnectPDULength: 42
+       Align: No Padding
+       Length: 42
+    - ConnectGCCPDU: conferenceCreateResponse
+       ExtensionBit: 0 (0x0)
+     - ChoiceValue: conferenceCreateResponse
+        Value: (001.....) 0x1
+     - conferenceCreateResponse: 
+        ExtensionBit: 0 (0x0)
+        userDataPresent: 1 (0x1)
+      - nodeID: 0x79f3
+       - UserID: 31219
+        - Align: No Padding
+           Padding2: (00......) 0x0
+          Value: 30218 (0x760A)
+      - tag: 1 (0x1)
+       - Length: 1
+          Align: No Padding
+          Length: 1
+         Value: 1 (0x1)
+      - result: success
+         ExtensionBit: 0 (0x0)
+       - RootIndex: 0
+          Value: (000.....) 0x0
+      - userData: 
+       - Size: 1
+        - Align: No Padding
+           Padding4: (0000....) 0x0
+          Length: 1
+       - UserData: 0x4d63446e
+          valuePresent: 1 (0x1)
+        - key: h221NonStandard
+         - ChoiceValue: h221NonStandard
+            Value: (1.......) 0x1
+         - h221NonStandard: 
+          - H221NonStandardIdentifier: length: 4
+           - ConstrainedLength: 4
+              Value: (00000000) 0x0
+           - Align: No Padding
+              Padding6: (000000..) 0x0
+             Value: Binary Large Object (4 Bytes)
+        - ServerMcsConnectResponsePdu: 
+         - RDPGCCUserDataResponseLength: 32
+            Align: No Padding
+            Length: 32
+         - TsUd: SC_CORE
+          - TsUdHeader: Type = SC_CORE, Length = 12
+             Type: SC_CORE
+             Length: 12 (0xC)
+          - TsUdScCore: 
+             Version: RDP 5.0, 5.1, 5.2, 6.0, 6.1, and 7.0 
+             ClientRequestedProtocols: TLS 1.0
+         - TsUd: SC_NET
+          - TsUdHeader: Type = SC_NET, Length = 8
+             Type: SC_NET
+             Length: 8 (0x8)
+          - TsUdScNet: 
+             MCSChannelID: 1003 (0x3EB)
+             ChannelCount: 0 (0x0)
+             Pad: 0 Bytes
+         - TsUd: SC_SECURITY
+          - TsUdHeader: Type = SC_SECURITY, Length = 12
+             Type: SC_SECURITY
+             Length: 12 (0xC)
+          - TsUdSCSec1: 
+           - EncryptionMethod: 
+              Support40Bit:  (...............................0) Not Support 
+              Support128Bit: (..............................0.) Not Support 128-bit
+              Reserved1:     (.............................0..)
+              Support56Bit:  (............................0...) Not Support 56-bit
+              SupportFIPS:   (...........................0....) Not Support FIPS Compliant
+              Reserved2:     (000000000000000000000000000.....)
+             EncryptionLevel: TS_ENCRYPTION_NONE
+ */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSPDU.java
new file mode 100755
index 0000000..badea27
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSPDU.java
@@ -0,0 +1,149 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class ServerMCSPDU extends BaseElement {
+
+    public ServerMCSPDU(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        byte headerByte = buf.readSignedByte();
+        int type = headerByte >> 2;
+
+        switch (type) {
+        // Expected type: send data indication: 26 (0x1a, top 6 bits, or 0x68)
+        case 0x1a: {
+            // int userId = buf.readUnsignedShort() + 1001; // User ID: 1002 (1001+1)
+            buf.skipBytes(2); // Ignore user ID
+
+            int channelId = buf.readUnsignedShort(); // Channel ID: 1003
+
+            int flags = buf.readSignedByte();
+            if ((flags & 0x30) != 0x30)
+                throw new RuntimeException("Fragmented MCS packets are not supported.");
+
+            int payloadLength = buf.readVariableUnsignedShort();
+
+            ByteBuffer data = buf.readBytes(payloadLength);
+
+            buf.unref();
+
+            pushDataToPad("channel_" + channelId, data);
+            break;
+        }
+
+        case 0x8: {
+            // Disconnection sequence.
+            buf.unref();
+            break;
+        }
+
+        default:
+            throw new RuntimeException("Unsupported MCS packet type: " + type + "(" + headerByte + "), data: " + buf + ".");
+        }
+
+    }
+
+    /**
+     * Example.
+     * 
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        // System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        byte[] packet = new byte[] {
+                // TPKT
+                (byte)0x03, (byte)0x00, // TPKT Header: TPKT version = 3
+                (byte)0x00, (byte)0x1B, // TPKT length: 27 bytes
+
+                // X224
+                (byte)0x02, // X224 Length: 2 bytes
+                (byte)0xF0, // X224 Type: Data
+                (byte)0x80, // X224 EOT
+
+                // MCS
+                // Type: send data indication: 26 (0x1a, top 6 bits)
+                (byte)0x68, // ??
+
+                (byte)0x00, (byte)0x01, // User ID: 1002 (1001+1)
+                (byte)0x03, (byte)0xEB, // Channel ID: 1003
+                (byte)0x70, // Data priority: high, segmentation: begin|end
+                (byte)0x0D, // Payload length: 13 bytes
+
+                // Deactivate all PDU
+                (byte)0x0D, (byte)0x00, // Length: 13 bytes (LE)
+
+                // - PDUType: 22 (0x16, LE)
+                // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
+                // ProtocolVersion: (000000000001....) 1
+                (byte)0x16, (byte)0x00,
+
+                (byte)0xEA, (byte)0x03, // PDU source: 1002 (LE)
+                (byte)0xEA, (byte)0x03, (byte)0x01, (byte)0x00, // ShareID = 66538
+
+                (byte)0x01, (byte)0x00, // Length if source descriptor: 1 (LE)
+                (byte)0x00, // Source descriptor (should be set to 0): 0
+        };
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mcs = new ServerMCSPDU("mcs") {
+            {
+                verbose = true;
+            }
+        };
+        Element tpkt = new ServerTpkt("tpkt");
+        Element x224 = new ServerX224DataPdu("x224");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
+                // Deactivate all PDU
+                (byte)0x0D, (byte)0x00, // Length: 13 bytes (LE)
+
+                // - PDUType: 22 (0x16, LE)
+                // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
+                // ProtocolVersion: (000000000001....) 1
+                (byte)0x16, (byte)0x00,
+
+                (byte)0xEA, (byte)0x03, // PDU source: 1002 (LE)
+                (byte)0xEA, (byte)0x03, (byte)0x01, (byte)0x00, // ShareID = 66538
+
+                (byte)0x01, (byte)0x00, // Length if source descriptor: 1 (LE)
+                (byte)0x00, // Source descriptor (should be set to 0): 0
+        }));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, tpkt, x224, mcs, sink);
+        pipeline.link("source", "tpkt", "x224", "mcs >channel_1003", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerPaletteUpdate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerPaletteUpdate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerPaletteUpdate.java
new file mode 100755
index 0000000..0beca2f
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerPaletteUpdate.java
@@ -0,0 +1,78 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import java.awt.image.IndexColorModel;
+
+import common.ScreenDescription;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240623.aspx
+ */
+public class ServerPaletteUpdate extends BaseElement {
+
+    public static final int UPDATETYPE_PALETTE = 0x0002;
+    protected ScreenDescription screen;
+
+    public ServerPaletteUpdate(String id, ScreenDescription screen) {
+        super(id);
+        this.screen = screen;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // (2 bytes): A 16-bit, unsigned integer. The update type. This field MUST
+        // be set to UPDATETYPE_PALETTE (0x0002).
+        int updateType = buf.readUnsignedShortLE();
+        if (updateType != UPDATETYPE_PALETTE)
+            throw new RuntimeException("Unexpected update type. Expected type: UPDATETYPE_PALETTE (0x0002), actual value: " + updateType + ", data: " + buf + ".");
+
+        // pad2Octets (2 bytes): A 16-bit, unsigned integer. Padding. Values in this
+        // field MUST be ignored.
+        buf.skipBytes(2);
+
+        // (4 bytes): A 32-bit, unsigned integer. The number of RGB triplets in the
+        // paletteData field. This field MUST be set to 256 (the number of entries
+        // in an 8 bpp palette).
+        int numberColors = (int)buf.readUnsignedIntLE();
+        if (numberColors != 256)
+            throw new RuntimeException("Unexpected value for number of color field in server Palette Update packet. Expected value: 256 colors, actual value: "
+                    + numberColors + ", data: " + buf + ".");
+
+        // (variable): An array of palette entries in RGB triplet format packed on
+        // byte boundaries. The number of triplet entries is given by the
+        // numberColors field.
+        ByteBuffer paletteEntries = buf.readBytes(numberColors * 3);
+
+        // In the case of a Palette Update, the client MUST update the global
+        // palette on all drawing surfaces
+        screen.colorMap = new IndexColorModel(8, numberColors, paletteEntries.data, paletteEntries.offset, false);
+
+        /* DEBUG */buf.assertThatBufferIsFullyRead();
+
+        buf.unref();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerSynchronizePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerSynchronizePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerSynchronizePDU.java
new file mode 100755
index 0000000..b83f474
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerSynchronizePDU.java
@@ -0,0 +1,115 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ServerSynchronizePDU extends OneTimeSwitch {
+
+    public ServerSynchronizePDU(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Ignore packet
+        buf.unref();
+        switchOff();
+    }
+
+}
+
+/* @formatter:off */
+/*
+
+ * 03 00 00 24 02 F0 80 68 00 01 03 EB 70 16 16 00 17 00 EA 03 EA 03 01 00 08 00 16 00 1F 00 00 00 01 00 86 A4 
+
+  Frame: Number = 36, Captured Frame Length = 93, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 36
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 36 (0x24)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: Data Packet
+  - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
+   - Type: Send Data Indication
+    - RootIndex: 26
+       Value: (011010..) 0x1a
+   - UserID: 0x3ea
+    - UserID: 0x3ea
+     - ChannelId: 1002
+      - Align: No Padding
+         Padding2: (00......) 0x0
+        Value: 1 (0x1)
+   - Channel: 0x3eb
+    - ChannelId: 1003
+       Align: No Padding
+       Value: 1003 (0x3EB)
+   - DataPriority: high
+    - DataPriority: high
+     - RootIndex: 1
+        Value: (01......) 0x1
+   - Segmentation: Begin End
+      Begin: (1.......) Begin
+      End:   (.1......) End
+   - Length: 22
+    - Align: No Padding
+       Padding4: (0000....) 0x0
+      Length: 22
+    RDP: RDPBCGR
+- RDPBCGR: SynchronizePDU
+  - SlowPathPacket: SynchronizePDU 
+   - SlowPath: Type = TS_PDUTYPE_DATAPDU
+    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
+       TotalLength: 22 (0x16)
+     - PDUType: 23 (0x17)
+        Type:            (............0111) TS_PDUTYPE_DATAPDU
+        ProtocolVersion: (000000000001....) 1
+       PDUSource: 1002 (0x3EA)
+    - SlowPathIoPacket: 0x0
+     - ShareDataHeader: TS_PDUTYPE2_SYNCHRONIZE
+        ShareID: 66538 (0x103EA)
+        Pad1: 8 (0x8)
+        StreamID: STREAM_UNDEFINED
+        UncompressedLength: 22 (0x16)
+        PDUType2: TS_PDUTYPE2_SYNCHRONIZE
+      - CompressedType: Not Compressed
+         MPPC:       (....0000) MPPC 8K
+         Reserved:   (...0....)
+         Compressed: (..0.....) Not Compressed
+         Front:      (.0......) Not At Front
+         Flush:      (0.......) Not Flushed
+        CompressedLength: 0 (0x0)
+     - TsSynchronizePDU: 0x1
+        MessageType: 0x1, MUST be set to SYNCMSGTYPE_SYNC (1)
+        TargetUser: 42118 (0xA486)
+ */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerTpkt.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerTpkt.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerTpkt.java
new file mode 100755
index 0000000..d9662d2
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerTpkt.java
@@ -0,0 +1,70 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class ServerTpkt extends BaseElement {
+
+    /**
+     * TPKT protocol version (first byte).
+     */
+    public static final int PROTOCOL_TPKT = 3;
+
+    public ServerTpkt(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // We need at least 4 bytes to get packet length
+        if (!cap(buf, 4, UNLIMITED, link, false))
+            return;
+
+        int version = buf.readUnsignedByte();
+        if (version != PROTOCOL_TPKT)
+            throw new RuntimeException("Unexpected data in TPKT header. Expected TPKT version: 0x03,  actual value: " + buf + ".");
+
+        buf.skipBytes(1); // Reserved byte
+
+        // Length of whole packet, including header
+        int length = buf.readUnsignedShort();
+        if (!cap(buf, length, length, link, false))
+            return;
+
+        int payloadLength = length - buf.cursor;
+
+        // Extract payload
+        ByteBuffer outBuf = buf.slice(buf.cursor, payloadLength, true);
+        buf.unref();
+
+        if (verbose) {
+            outBuf.putMetadata("source", this);
+        }
+
+        pushDataToAllOuts(outBuf);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224ConnectionConfirmPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224ConnectionConfirmPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224ConnectionConfirmPDU.java
new file mode 100755
index 0000000..d024063
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224ConnectionConfirmPDU.java
@@ -0,0 +1,234 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * Once the External Security Protocol handshake has run to completion, the
+ * client MUST continue with the connection sequence by sending the MCS Connect
+ * Initial PDU to the server over the newly established secure channel.
+ * 
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc240663.aspx
+ */
+public class ServerX224ConnectionConfirmPDU extends OneTimeSwitch {
+
+    public static final int X224_TPDU_CONNECTION_REQUEST = 0xe0;
+    public static final int X224_TPDU_CONNECTION_CONFIRM = 0xd0;
+    public static final int X224_TPDU_DISCONNECTION_REQUEST = 0x80;
+    public static final int X224_TPDU_DISCONNECTION_CONFIRM = 0xc0;
+    public static final int X224_TPDU_EXPEDITED_DATA = 0x10;
+    public static final int X224_TPDU_DATA_ACKNOWLEDGE = 0x61;
+    public static final int X224_TPDU_EXPEDITET_ACKNOWLEDGE = 0x40;
+    public static final int X224_TPDU_REJECT = 0x51;
+    public static final int X224_TPDU_ERROR = 0x70;
+    public static final int X224_TPDU_PROTOCOL_IDENTIFIER = 0x01;
+
+    /**
+     * The server requires that the client support Enhanced RDP Security with
+     * either TLS 1.0, 1.1 or 1.2 or CredSSP. If only CredSSP was requested then
+     * the server only supports TLS.
+     */
+    public static final int SSL_REQUIRED_BY_SERVER = 0x00000001;
+
+    /**
+     * The server is configured to only use Standard RDP Security mechanisms and
+     * does not support any External Security Protocols.
+     */
+    public static final int SSL_NOT_ALLOWED_BY_SERVER = 0x00000002;
+
+    /**
+     * The server does not possess a valid authentication certificate and cannot
+     * initialize the External Security Protocol Provider.
+     */
+    public static final int SSL_CERT_NOT_ON_SERVER = 0x00000003;
+
+    /**
+     * The list of requested security protocols is not consistent with the current
+     * security protocol in effect. This error is only possible when the Direct
+     * Approach is used and an External Security Protocolis already being used.
+     */
+    public static final int INCONSISTENT_FLAGS = 0x00000004;
+
+    /**
+     * The server requires that the client support Enhanced RDP Security with
+     * CredSSP.
+     */
+    public static final int HYBRID_REQUIRED_BY_SERVER = 0x00000005;
+
+    /**
+     * The server requires that the client support Enhanced RDP Security with TLS
+     * 1.0, 1.1 or 1.2 and certificate-based client authentication.
+     */
+    public static final int SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER = 0x00000006;
+
+    public ServerX224ConnectionConfirmPDU(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        int x224Length = buf.readVariableSignedIntLE();
+
+        int x224Type = buf.readUnsignedByte();
+        if (x224Type != X224_TPDU_CONNECTION_CONFIRM)
+            throw new RuntimeException("Unexpected type of packet. Expected type: " + X224_TPDU_CONNECTION_CONFIRM + " (CONNECTION CONFIRM), actual type: "
+                    + x224Type + ", length: " + x224Length + ", buf: " + buf + ".");
+
+        // Ignore destination reference, because client side has only one node
+        buf.skipBytes(2);
+
+        // Source reference
+        // int srcRef = buf.readUnsignedShort();
+        buf.skipBytes(2);
+
+        // Ignore class and options
+        buf.skipBytes(1);
+
+        // RDP_NEG_RSP::type (TYPE_RDP_NEG_RSP)
+        int negType = buf.readUnsignedByte();
+
+        // RDP_NEG_RSP::flags (0)
+        buf.skipBytes(1); // Ignore: always 0
+
+        // RDP_NEG_RSP::length (always 8 bytes)
+        int length = buf.readUnsignedShortLE();
+
+        if (length != 8)
+            throw new RuntimeException("Unexpected length of buffer. Expected value: 8, actual value: " + length + ", RDP NEG buf: " + buf + ".");
+
+        // RDP_NEG_RSP: Selected protocols (PROTOCOL_SSL)
+        int protocol = buf.readSignedIntLE();
+
+        if (negType != RdpConstants.RDP_NEG_REQ_TYPE_NEG_RSP) {
+            // Parse error code, see
+            // http://msdn.microsoft.com/en-us/library/cc240507.aspx
+            int errorCode = protocol;
+            String message = "Unknown error.";
+            switch (errorCode) {
+            case SSL_REQUIRED_BY_SERVER:
+                message = "The server requires that the client support Enhanced RDP Security with either TLS 1.0, 1.1 or 1.2 or CredSSP. If only CredSSP was requested then the server only supports TLS.";
+                break;
+
+            case SSL_NOT_ALLOWED_BY_SERVER:
+                message = "The server is configured to only use Standard RDP Security mechanisms and does not support any External Security Protocols.";
+                break;
+
+            case SSL_CERT_NOT_ON_SERVER:
+                message = "The server does not possess a valid authentication certificate and cannot initialize the External Security Protocol Provider.";
+                break;
+
+            case INCONSISTENT_FLAGS:
+                message = "The list of requested security protocols is not consistent with the current security protocol in effect. This error is only possible when the Direct Approach is used and an External Security Protocolis already being used.";
+                break;
+
+            case HYBRID_REQUIRED_BY_SERVER:
+                message = "The server requires that the client support Enhanced RDP Security with CredSSP.";
+                break;
+
+            case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
+                message = "The server requires that the client support Enhanced RDP Security  with TLS 1.0, 1.1 or 1.2 and certificate-based client authentication.";
+                break;
+
+            }
+            throw new RuntimeException("Connection failure: " + message);
+        }
+
+        if (protocol != RdpConstants.RDP_NEG_REQ_PROTOCOL_SSL && protocol != RdpConstants.RDP_NEG_REQ_PROTOCOL_HYBRID)
+            throw new RuntimeException("Unexpected protocol type (nor SSL, nor HYBRID (SSL+CredSSP)): " + protocol + ", RDP NEG buf: " + buf + ".");
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: RDP Negotiation response. Type: " + negType + ", protocol: " + protocol + ".");
+
+        // Next: upgrade socket to SSL, send ConnectInitial packet
+        switchOff();
+    }
+
+    /**
+     * Example.
+     * 
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+//    byte[] packet = new byte[] { 
+//    
+//        0x03, // -> TPKT Header: TPKT version = 3
+//        0x00, // TPKT Header: Reserved = 0
+//        0x00, 0x13, // TPKT Header: Packet length - (total = 19 bytes)
+//        0x0e, // X.224: Length indicator (14 bytes)
+//        (byte) 0xd0, // X.224: Type (high nibble) = 0xd = CC TPDU; credit
+//                     // (low nibble) = 0
+//        0x00, 0x00, // X.224: Destination reference = 0
+//        0x12, 0x34, // X.224: Source reference = 0x1234 (bogus value)
+//        0x00, // X.224: Class and options = 0
+//
+//        0x02, // RDP_NEG_RSP::type (TYPE_RDP_NEG_RSP)
+//        0x00, // RDP_NEG_RSP::flags (0)
+//        0x08, 0x00, // RDP_NEG_RSP::length (8 bytes)
+//        0x01, 0x00, 0x00, 0x00 // RDP_NEG_RSP: Selected protocols (PROTOCOL_SSL)
+//    };
+
+        // Connection failure
+        // 03 00 00 13 0e d0 00 00 12 34 00 03 00 08 00 05 00 00 00
+        byte[] packet = new byte[] {
+
+                0x03, // -> TPKT Header: TPKT version = 3
+                0x00, // TPKT Header: Reserved = 0
+                0x00, 0x13, // TPKT Header: Packet length - (total = 19 bytes)
+                0x0e, // X.224: Length indicator (14 bytes)
+                (byte)0xd0, // X.224: Type (high nibble) = 0xd = CC TPDU; credit
+                            // (low nibble) = 0
+                0x00, 0x00, // X.224: Destination reference = 0
+                0x12, 0x34, // X.224: Source reference = 0x1234 (bogus value)
+                0x00, // X.224: Class and options = 0
+                (byte)0x03, // Failure 
+                (byte)0x00, // RDP_NEG_RSP::flags (0)
+                (byte)0x08, (byte)0x00, // RDP_NEG_RSP::length (8 bytes) 
+                (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x00, // Code:  HYBRID_REQUIRED_BY_SERVER
+
+        };
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element cc = new ServerX224ConnectionConfirmPDU("cc");
+        Element tpkt = new ServerTpkt("tpkt");
+        Element sink = new MockSink("sink", new ByteBuffer[] {});
+        Element mainSink = new MockSink("mainSink", new ByteBuffer[] {});
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, tpkt, cc, sink, mainSink);
+        pipeline.link("source", "tpkt", "cc", "mainSink");
+        pipeline.link("cc >" + OTOUT, "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224DataPdu.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224DataPdu.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224DataPdu.java
new file mode 100755
index 0000000..2c0087e
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224DataPdu.java
@@ -0,0 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class ServerX224DataPdu extends BaseElement {
+
+    public static final int X224_TPDU_LAST_DATA_UNIT = 0x80;
+    public static final int X224_TPDU_DATA = 0xF0;
+
+    public ServerX224DataPdu(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        int headerLength = buf.readVariableSignedIntLE();
+
+        if (headerLength != 2)
+            throw new RuntimeException("Unexpected X224 Data PDU header length. Expected header length: 2 , actual header length: " + headerLength + ".");
+
+        // Read X224 type and options
+        int type = buf.readUnsignedByte(); // High nibble: type, low nibble:
+
+        if ((type & 0xf0) != X224_TPDU_DATA)
+            throw new RuntimeException("[" + this + "] ERROR: Unexepcted X224 packet type. Expected packet type: " + X224_TPDU_DATA
+                    + " (X224_TPDU_DATA), actual packet type: " + type + ", buf: " + buf + ".");
+
+        int options = buf.readUnsignedByte();
+
+        if ((options & X224_TPDU_LAST_DATA_UNIT) != X224_TPDU_LAST_DATA_UNIT)
+            throw new RuntimeException("Unexepcted X224 packet options. Expected options: " + X224_TPDU_LAST_DATA_UNIT
+                    + " (X224_TPDU_LAST_DATA_UNIT), actual packet options: " + options + ", buf: " + buf + ".");
+
+        ByteBuffer payload = buf.readBytes(buf.length - buf.cursor);
+
+        buf.unref();
+
+        pushDataToAllOuts(payload);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/AssertingByteBuffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/AssertingByteBuffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/AssertingByteBuffer.java
deleted file mode 100644
index 1958475..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/AssertingByteBuffer.java
+++ /dev/null
@@ -1,107 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 streamer;
-
-import java.nio.charset.Charset;
-
-/**
- * Assert that writes to this buffer are matching expected data.
- */
-public class AssertingByteBuffer extends ByteBuffer {
-
-  public AssertingByteBuffer(byte[] expectedData) {
-    super(expectedData);
-  }
-
-  private void assertEquals(int expected, int actual) {
-    if (expected != actual)
-      throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ", buf: "+this+".");
-  }
-
-  @Override
-  public void writeByte(int b) {
-    if(b<0)
-      throw new RuntimeException();
-    //*DEBUG*/System.out.println("WriteByte: "+b+", cursor:"+cursor+".");
-    assertEquals(readUnsignedByte(), b&0xff);
-  }
-
-  @Override
-  public void writeShort(int x) {
-    //*DEBUG*/System.out.println("WriteShort: "+x+", cursor:"+cursor+".");
-    assertEquals(readUnsignedShort(), x&0xFFff);
-  }
-
-  @Override
-  public void writeShortLE(int x) {
-    //*DEBUG*/System.out.println("WriteShortLE: "+x+", cursor:"+cursor+".");
-    assertEquals(readUnsignedShortLE(), x&0xFFff);
-  }
-
-  @Override
-  public void writeInt(int i) {
-    //*DEBUG*/System.out.println("WriteInt: "+i+", cursor:"+cursor+".");
-    assertEquals(readSignedInt(), i);
-  }
-
-  @Override
-  public void writeIntLE(int i) {
-    //*DEBUG*/System.out.println("WriteIntLE: "+i+", cursor:"+cursor+".");
-    assertEquals(readSignedIntLE(), i);
-  }
-
-  @Override
-  public void writeVariableIntLE(int i) {
-    //*DEBUG*/System.out.println("WriteVariableIntLE: "+i+", cursor:"+cursor+".");
-    assertEquals(readVariableSignedIntLE(), i);
-  }
-
-  @Override
-  public void writeString(String actual, Charset charset) {
-    //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
-    String expected = readString(actual.length(), charset);
-    if (!actual.equals(expected))
-      throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
-  }
-
-  @Override
-  public void writeBytes(ByteBuffer actual) {
-    //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
-    ByteBuffer expected = readBytes(actual.length);
-    if (!actual.equals(expected))
-      throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
-  }
-
-  @Override
-  public void writeBytes(byte[] actualData) {
-    ByteBuffer actual = new ByteBuffer(actualData);
-    //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
-    ByteBuffer expected = readBytes(actual.length);
-    if (!actual.equals(expected))
-      throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
-  }
-
-  @Override
-  public void writeBytes(byte[] actualData, int offset, int length) {
-    ByteBuffer actual = new ByteBuffer(actualData, offset, length);
-    //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
-    ByteBuffer expected = readBytes(actual.length);
-    if (!actual.equals(expected))
-      throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BaseElement.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BaseElement.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BaseElement.java
old mode 100644
new mode 100755
index 86f9be3..10c7c70
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BaseElement.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BaseElement.java
@@ -21,397 +21,401 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
+import streamer.debug.FakeSink;
+import streamer.debug.FakeSource;
+
 public class BaseElement implements Element {
 
-  protected String id;
-
-  /**
-   * Constant for @see cap() method to indicate that length is not restricted.
-   */
-  public static final int UNLIMITED = -1;
-
-  /**
-   * Set to true to enable debugging messages.
-   */
-  protected boolean verbose = false;
-
-  /**
-   * Limit on number of packets sent to sink from this element. Can be handy for
-   * fake elements and handshake-related elements.
-   */
-  protected int numBuffers = 0;
-
-  /**
-   * Number of packets sent to sink.
-   */
-  protected int packetNumber = 0;
-
-  /**
-   * Recommended size for incoming buffer in pull mode.
-   */
-  protected int incommingBufLength = -1;
-
-  protected Map<String, DataSource> inputPads = new HashMap<String, DataSource>();
-  protected Map<String, DataSink> outputPads = new HashMap<String, DataSink>();
-
-  public BaseElement(String id) {
-    this.id = id;
-
-    verbose = System.getProperty("streamer.Element.debug", "false").equals("true") || System.getProperty("streamer.Element.debug", "").contains(id);
-  }
-
-  @Override
-  public String toString() {
-    return "Element(" + id + ")";
-  }
-
-  @Override
-  public Link getLink(String padName) {
-    if (inputPads.containsKey(padName))
-      return (Link) inputPads.get(padName);
-    else if (outputPads.containsKey(padName))
-      return (Link) outputPads.get(padName);
-    else
-      return null;
-  }
-
-  @Override
-  public Set<String> getPads(Direction direction) {
-    switch (direction) {
-    case IN:
-      return inputPads.keySet();
-
-    case OUT:
-      return outputPads.keySet();
+    protected String id;
+
+    /**
+     * Constant for @see cap() method to indicate that length is not restricted.
+     */
+    public static final int UNLIMITED = -1;
+
+    /**
+     * Set to true to enable debugging messages.
+     */
+    protected boolean verbose = false;
+
+    /**
+     * Limit on number of packets sent to sink from this element. Can be handy for
+     * fake elements and handshake-related elements.
+     */
+    protected int numBuffers = 0;
+
+    /**
+     * Number of packets sent to sink.
+     */
+    protected int packetNumber = 0;
+
+    /**
+     * Recommended size for incoming buffer in pull mode.
+     */
+    protected int incommingBufLength = -1;
+
+    protected Map<String, DataSource> inputPads = new HashMap<String, DataSource>();
+    protected Map<String, DataSink> outputPads = new HashMap<String, DataSink>();
+
+    public BaseElement(String id) {
+        this.id = id;
+
+        verbose = System.getProperty("streamer.Element.debug", "false").equals("true") || System.getProperty("streamer.Element.debug", "").contains(id);
+    }
+
+    @Override
+    public String toString() {
+        return "Element(" + id + ")";
+    }
+
+    @Override
+    public Link getLink(String padName) {
+        if (inputPads.containsKey(padName))
+            return (Link)inputPads.get(padName);
+        else if (outputPads.containsKey(padName))
+            return (Link)outputPads.get(padName);
+        else
+            return null;
     }
-    return null;
-  }
-
-  @Override
-  public void validate() {
-    for (String padName : inputPads.keySet()) {
-      if (inputPads.get(padName) == null)
-        throw new RuntimeException("[ " + this + "] Required input pad is not connected. Pad name: " + padName + ".");
+
+    @Override
+    public Set<String> getPads(Direction direction) {
+        switch (direction) {
+        case IN:
+            return inputPads.keySet();
+
+        case OUT:
+            return outputPads.keySet();
+        }
+        return null;
     }
 
-    for (String padName : outputPads.keySet()) {
-      if (outputPads.get(padName) == null)
-        throw new RuntimeException("[ " + this + "] Required output pad is not connected. Pad name: " + padName + ".");
+    @Override
+    public void validate() {
+        for (String padName : inputPads.keySet()) {
+            if (inputPads.get(padName) == null)
+                throw new RuntimeException("[ " + this + "] Required input pad is not connected. Pad name: " + padName + ".");
+        }
+
+        for (String padName : outputPads.keySet()) {
+            if (outputPads.get(padName) == null)
+                throw new RuntimeException("[ " + this + "] Required output pad is not connected. Pad name: " + padName + ".");
+        }
     }
-  }
 
-  @Override
-  public void setLink(String padName, Link link, Direction direction) {
-    switch (direction) {
-    case IN:
-      if (inputPads.get(padName) != null)
-        throw new RuntimeException("Cannot link more than one wire to same pad. Element: " + this + ", pad: " + padName + ":" + direction + ", new link: "
-            + link + ", existing link: " + inputPads.get(padName) + ".");
-      inputPads.put(padName, link);
-      link.setSink(this);
+    @Override
+    public void setLink(String padName, Link link, Direction direction) {
+        switch (direction) {
+        case IN:
+            if (inputPads.get(padName) != null)
+                throw new RuntimeException("Cannot link more than one wire to same pad. Element: " + this + ", pad: " + padName + ":" + direction + ", new link: "
+                        + link + ", existing link: " + inputPads.get(padName) + ".");
+            inputPads.put(padName, link);
+            link.setSink(this);
 
-      break;
+            break;
 
-    case OUT:
-      if (outputPads.get(padName) != null)
-        throw new RuntimeException("Cannot link more than one wire to same pad. Element: " + this + ", pad: " + padName + ":" + direction + ", new link: "
-            + link + ", existing link: " + outputPads.get(padName) + ".");
+        case OUT:
+            if (outputPads.get(padName) != null)
+                throw new RuntimeException("Cannot link more than one wire to same pad. Element: " + this + ", pad: " + padName + ":" + direction + ", new link: "
+                        + link + ", existing link: " + outputPads.get(padName) + ".");
 
-      outputPads.put(padName, link);
-      link.setSource(this);
+            outputPads.put(padName, link);
+            link.setSource(this);
 
-      break;
+            break;
+        }
     }
-  }
-
-  @Override
-  public void dropLink(String padName) {
-    if (inputPads.containsKey(padName)) {
-      Link link = (Link) inputPads.remove(padName);
-      if (link != null)
-        link.setSink(null);
+
+    @Override
+    public void dropLink(String padName) {
+        if (inputPads.containsKey(padName)) {
+            Link link = (Link)inputPads.remove(padName);
+            if (link != null)
+                link.setSink(null);
+        }
+
+        if (outputPads.containsKey(padName)) {
+            Link link = (Link)outputPads.remove(padName);
+            if (link != null)
+                link.setSource(null);
+        }
     }
 
-    if (outputPads.containsKey(padName)) {
-      Link link = (Link) outputPads.remove(padName);
-      if (link != null)
-        link.setSource(null);
+    /**
+     * By default, try to pull data from input links.
+     * 
+     * Override this method in data source elements.
+     */
+    @Override
+    public void poll(boolean block) {
+        for (DataSource source : inputPads.values()) {
+            Link link = (Link)source;
+            ByteBuffer buf = link.pull(block);
+
+            if (buf != null) {
+                handleData(buf, link);
+            }
+        }
     }
-  }
-
-  /**
-   * By default, try to pull data from input links.
-   * 
-   * Override this method in data source elements.
-   */
-  @Override
-  public void poll(boolean block) {
-    for (DataSource source : inputPads.values()) {
-      Link link = (Link) source;
-      ByteBuffer buf = link.pull(block);
-
-      if (buf != null) {
-        handleData(buf, link);
-      }
+
+    /**
+     * By default, do nothing with incoming data and retransmit data to all output
+     * pads.
+     */
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        pushDataToAllOuts(buf);
     }
-  }
-
-  /**
-   * By default, do nothing with incoming data and retransmit data to all output
-   * pads.
-   */
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    pushDataToAllOuts(buf);
-  }
-
-  /**
-   * Send data to all output pads.
-   */
-  protected final void pushDataToAllOuts(ByteBuffer buf) {
-
-    if (buf == null)
-      return;
-
-    if (outputPads.size() == 0)
-      throw new RuntimeException("Number of outgoing connection is zero. Cannot send data to output. Data: " + buf + ".");
-
-    // Send data to all pads with OUT direction
-    for (DataSink out : outputPads.values()) {
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Sending buf " + buf + " to " + out + ".");
-
-      buf.rewindCursor();
-      buf.ref();
-      out.sendData(buf);
+
+    /**
+     * Send data to all output pads.
+     */
+    protected final void pushDataToAllOuts(ByteBuffer buf) {
+
+        if (buf == null) {
+            throw new NullPointerException();
+        }
+
+        if (outputPads.size() == 0)
+            throw new RuntimeException("Number of outgoing connection is zero. Cannot send data to output. Data: " + buf + ".");
+
+        // Send data to all pads with OUT direction
+        for (DataSink out : outputPads.values()) {
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Sending buf " + buf + " to " + out + ".");
+
+            buf.rewindCursor();
+            buf.ref();
+            out.sendData(buf);
+        }
+
+        buf.unref();
+        packetNumber++;
     }
 
-    buf.unref();
-    packetNumber++;
-  }
-
-  /**
-   * Send data to given pad only.
-   */
-  protected void pushDataToPad(String padName, ByteBuffer buf) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Sending buf " + buf + " to " + padName + ".");
-
-    DataSink link = outputPads.get(padName);
-    if (link == null)
-      throw new RuntimeException("Output pad of " + this + " element is not connected to a link. Pad name: " + padName + ".");
-
-    buf.rewindCursor();
-    link.sendData(buf);
-  }
-
-  /**
-   * By default, do nothing with incoming event and retransmit event to all
-   * pads.
-   */
-  @Override
-  public void handleEvent(Event event, Direction direction) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Event " + event + ":" + direction + " is received.");
-
-    switch (event) {
-    case STREAM_CLOSE:
-      onClose();
-      break;
-    case STREAM_START:
-      onStart();
-      break;
+    /**
+     * Send data to given pad only.
+     */
+    protected void pushDataToPad(String padName, ByteBuffer buf) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Sending buf " + buf + " to " + padName + ".");
+
+        DataSink link = outputPads.get(padName);
+        if (link == null)
+            throw new RuntimeException("Output pad of " + this + " element is not connected to a link. Pad name: " + padName + ".");
+
+        buf.rewindCursor();
+        link.sendData(buf);
     }
 
-    sendEventToAllPads(event, direction);
-  }
-
-  /**
-   * Override this method to do something when STREAM_CLOSE event arrives.
-   */
-  protected void onClose() {
-  }
-
-  /**
-   * Override this method to do something when STREAM_START event arrives.
-   */
-  protected void onStart() {
-  }
-
-  /**
-   * Send event to all outputs.
-   * 
-   * @param event
-   *          a event
-   * @param direction
-   *          IN to send event to input pads, OUT to send event to all output
-   *          pads
-   */
-  protected final void sendEventToAllPads(Event event, Direction direction) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Sending event " + event + ":" + direction + ".");
-
-    switch (direction) {
-    case IN:
-      // Send event to all pads with IN direction
-      for (DataSource in : inputPads.values()) {
-        in.sendEvent(event, direction);
-      }
-      break;
-    case OUT:
-      // Send event to all pads with OUT direction
-      for (DataSink out : outputPads.values()) {
-        out.sendEvent(event, direction);
-      }
-      break;
+    /**
+     * By default, do nothing with incoming event and retransmit event to all
+     * pads.
+     */
+    @SuppressWarnings("incomplete-switch")
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Event " + event + ":" + direction + " is received.");
+
+        switch (event) {
+        case STREAM_CLOSE:
+            onClose();
+            break;
+        case STREAM_START:
+            onStart();
+            break;
+        }
+
+        sendEventToAllPads(event, direction);
     }
-  }
-
-  /**
-   * Ensure that packet has required minimum and maximum length, cuts tail when
-   * necessary.
-   * 
-   * @param buf
-   *          a buffer
-   * @param minLength
-   *          minimum length of packet or -1
-   * @param maxLength
-   *          maximum length of packet or -1
-   * @param link
-   *          source link, to push unnecessary data back
-   * @param fromCursor
-   *          if true, then position will be included into calculation
-   * @return true,
-   */
-  public boolean cap(ByteBuffer buf, int minLength, int maxLength, Link link, boolean fromCursor) {
-
-    if (buf == null)
-      return false;
-
-    int length = buf.length;
-
-    int cursor;
-    if (fromCursor)
-      cursor = buf.cursor;
-    else
-      cursor = 0;
-
-    length -= cursor;
-
-    if ((minLength < 0 || length >= minLength) && (maxLength < 0 || length <= maxLength))
-      // Buffer is already in bounds
-      return true;
-
-    // Buffer is too small, wait for the rest of buffer
-    if (minLength >= 0 && length < minLength) {
-
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Buffer is too small. Min length: " + minLength + ", data length (after cursor): " + length + ".");
-
-      link.pushBack(buf.slice(0, length + cursor, true), minLength + cursor);
-      return false;
-    } else if (maxLength >= 0 && length > maxLength) {
-
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Buffer is too big. Max length: " + maxLength + ", data length (after cursor): " + length + ".");
-
-      // Buffer is too big, cut unnecessary tail
-      link.pushBack(buf.slice(maxLength + cursor, length - maxLength, true));
-      buf.length = maxLength + cursor;
 
+    /**
+     * Override this method to do something when STREAM_CLOSE event arrives.
+     */
+    protected void onClose() {
     }
 
-    return true;
-  }
+    /**
+     * Override this method to do something when STREAM_START event arrives.
+     */
+    protected void onStart() {
+    }
 
-  @Override
-  public void dropLink(Link link) {
-    if (inputPads.containsValue(link)) {
-      for (Entry<String, DataSource> entry : inputPads.entrySet())
-        if (link.equals(entry.getValue())) {
-          inputPads.remove(entry.getKey());
-          break;
+    /**
+     * Send event to all outputs.
+     * 
+     * @param event
+     *          a event
+     * @param direction
+     *          IN to send event to input pads, OUT to send event to all output
+     *          pads
+     */
+    protected final void sendEventToAllPads(Event event, Direction direction) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Sending event " + event + ":" + direction + ".");
+
+        switch (direction) {
+        case IN:
+            // Send event to all pads with IN direction
+            for (DataSource in : inputPads.values()) {
+                in.sendEvent(event, direction);
+            }
+            break;
+        case OUT:
+            // Send event to all pads with OUT direction
+            for (DataSink out : outputPads.values()) {
+                out.sendEvent(event, direction);
+            }
+            break;
         }
     }
 
-    if (outputPads.containsValue(link)) {
-      for (Entry<String, DataSink> entry : outputPads.entrySet())
-        if (link.equals(entry.getValue())) {
-          outputPads.remove(entry.getKey());
-          break;
+    /**
+     * Ensure that packet has required minimum and maximum length, cuts tail when
+     * necessary.
+     * 
+     * @param buf
+     *          a buffer
+     * @param minLength
+     *          minimum length of packet or -1
+     * @param maxLength
+     *          maximum length of packet or -1
+     * @param link
+     *          source link, to push unnecessary data back
+     * @param fromCursor
+     *          if true, then position will be included into calculation
+     * @return true, if buffer is long enough, false otherwise
+     */
+    public boolean cap(ByteBuffer buf, int minLength, int maxLength, Link link, boolean fromCursor) {
+
+        if (buf == null)
+            return false;
+
+        int length = buf.length;
+
+        int cursor;
+        if (fromCursor)
+            cursor = buf.cursor;
+        else
+            cursor = 0;
+
+        length -= cursor;
+
+        if ((minLength < 0 || length >= minLength) && (maxLength < 0 || length <= maxLength))
+            // Buffer is already in bounds
+            return true;
+
+        // Buffer is too small, wait for the rest of buffer
+        if (minLength >= 0 && length < minLength) {
+
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Buffer is too small. Min length: " + minLength + ", data length (after cursor): " + length + ".");
+
+            link.pushBack(buf.slice(0, length + cursor, true), minLength + cursor);
+            return false;
+        } else if (maxLength >= 0 && length > maxLength) {
+
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Buffer is too big. Max length: " + maxLength + ", data length (after cursor): " + length + ".");
+
+            // Buffer is too big, cut unnecessary tail
+            link.pushBack(buf.slice(maxLength + cursor, length - maxLength, true));
+            buf.length = maxLength + cursor;
+
         }
+
+        return true;
     }
-  }
-
-  @Override
-  public void replaceLink(Link existingLink, Link newLink) {
-    if (inputPads.containsValue(existingLink)) {
-      for (Entry<String, DataSource> entry : inputPads.entrySet())
-        if (existingLink.equals(entry.getValue())) {
-          inputPads.put(entry.getKey(), newLink);
-          newLink.setSink(this);
-          break;
+
+    @Override
+    public void dropLink(Link link) {
+        if (inputPads.containsValue(link)) {
+            for (Entry<String, DataSource> entry : inputPads.entrySet())
+                if (link.equals(entry.getValue())) {
+                    inputPads.remove(entry.getKey());
+                    break;
+                }
+        }
+
+        if (outputPads.containsValue(link)) {
+            for (Entry<String, DataSink> entry : outputPads.entrySet())
+                if (link.equals(entry.getValue())) {
+                    outputPads.remove(entry.getKey());
+                    break;
+                }
         }
     }
 
-    if (outputPads.containsValue(existingLink)) {
-      for (Entry<String, DataSink> entry : outputPads.entrySet())
-        if (existingLink.equals(entry.getValue())) {
-          outputPads.put(entry.getKey(), newLink);
-          newLink.setSource(this);
-          break;
+    @Override
+    public void replaceLink(Link existingLink, Link newLink) {
+        if (inputPads.containsValue(existingLink)) {
+            for (Entry<String, DataSource> entry : inputPads.entrySet())
+                if (existingLink.equals(entry.getValue())) {
+                    inputPads.put(entry.getKey(), newLink);
+                    newLink.setSink(this);
+                    break;
+                }
         }
+
+        if (outputPads.containsValue(existingLink)) {
+            for (Entry<String, DataSink> entry : outputPads.entrySet())
+                if (existingLink.equals(entry.getValue())) {
+                    outputPads.put(entry.getKey(), newLink);
+                    newLink.setSource(this);
+                    break;
+                }
+        }
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        Element source = new FakeSource("source") {
+            {
+                this.verbose = true;
+                this.numBuffers = 10;
+                this.incommingBufLength = 3;
+                this.delay = 100;
+            }
+        };
+
+        Element sink = new FakeSink("sink") {
+            {
+                this.verbose = true;
+            }
+        };
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source);
+        pipeline.add(new BaseElement("t1"));
+        pipeline.add(new BaseElement("t2"));
+        pipeline.add(new BaseElement("t3"));
+        pipeline.add(new BaseElement("t4"));
+        pipeline.add(sink);
+
+        pipeline.link("source", "t1", "t2", "t3", "t4", "sink");
+
+        // Links between source-t1-t2 will operate in pull mode.
+        // Links between t3-t4-sink will operate in push mode.
+        // Link between t2-t3 will run main loop (pull from source and push to
+        // sink).
+        Link link = pipeline.getLink("t3", STDOUT);
+        link.sendEvent(Event.STREAM_START, Direction.IN);
+        link.run();
     }
-  }
-
-  @Override
-  public String getId() {
-    return id;
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    Element source = new FakeSource("source") {
-      {
-        this.verbose = true;
-        this.numBuffers = 10;
-        this.incommingBufLength = 3;
-        this.delay = 100;
-      }
-    };
-
-    Element sink = new FakeSink("sink") {
-      {
-        this.verbose = true;
-      }
-    };
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source);
-    pipeline.add(new BaseElement("t1"));
-    pipeline.add(new BaseElement("t2"));
-    pipeline.add(new BaseElement("t3"));
-    pipeline.add(new BaseElement("t4"));
-    pipeline.add(sink);
-
-    pipeline.link("source", "t1", "t2", "t3", "t4", "sink");
-
-    // Links between source-t1-t2 will operate in pull mode.
-    // Links between t3-t4-sink will operate in push mode.
-    // Link between t2-t3 will run main loop (pull from source and push to
-    // sink).
-    pipeline.getLink("t3", STDOUT).run();
-  }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BufferPool.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BufferPool.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BufferPool.java
old mode 100644
new mode 100755
index 47f1435..d8e9139
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BufferPool.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BufferPool.java
@@ -17,20 +17,20 @@
 package streamer;
 
 public class BufferPool {
-  public static byte[] allocateNewBuffer(int minSize) {
-    // TODO: search for free buffer in pool
-    if (minSize >= 0)
-      return new byte[minSize];
-    else
-      // Return large buffer by default, too minimize number of round trips
-      // between to read full packet when packet is large, but it is important
-      // to return buffer to pool to reuse it (or null-ify links to it for
-      // faster GC)
-      // TODO: get free buffer from pool
-      return new byte[128 * 1024];
-  }
+    public static byte[] allocateNewBuffer(int minSize) {
+        // TODO: search for free buffer in pool
+        if (minSize >= 0)
+            return new byte[minSize];
+        else
+            // Return large buffer by default, too minimize number of round trips
+            // between to read full packet when packet is large, but it is important
+            // to return buffer to pool to reuse it (or null-ify links to it for
+            // faster GC)
+            // TODO: get free buffer from pool
+            return new byte[128 * 1024];
+    }
 
-  public static void recycleBuffer(byte[] buf) {
-    // TODO: return buffer to pool
-  }
+    public static void recycleBuffer(byte[] buf) {
+        // TODO: return buffer to pool
+    }
 }


[12/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspChallenge.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspChallenge.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspChallenge.java
new file mode 100755
index 0000000..e93f630
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspChallenge.java
@@ -0,0 +1,293 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp;
+
+import java.util.Arrays;
+
+import rdpclient.ntlmssp.asn1.NegoItem;
+import rdpclient.ntlmssp.asn1.TSRequest;
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc236642.aspx
+ */
+public class ServerNtlmsspChallenge extends OneTimeSwitch implements NtlmConstants {
+
+    protected NtlmState ntlmState;
+
+    public ServerNtlmsspChallenge(String id, NtlmState state) {
+        super(id);
+        this.ntlmState = state;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Extract server challenge, extract server flags.
+
+        // Parse TSRequest in BER format
+        TSRequest request = new TSRequest("TSRequest");
+        request.readTag(buf);
+
+        ByteBuffer negoToken = ((NegoItem)request.negoTokens.tags[0]).negoToken.value;
+        ntlmState.challengeMessage = negoToken.toByteArray(); // Store message for MIC calculation in AUTH message
+
+        parseNtlmChallenge(negoToken);
+
+        negoToken.unref();
+        buf.unref();
+        switchOff();
+    }
+
+    public void parseNtlmChallenge(ByteBuffer buf) {
+
+        // Signature: "NTLMSSP\0"
+        String signature = buf.readVariableString(RdpConstants.CHARSET_8);
+        if (!signature.equals(NTLMSSP))
+            throw new RuntimeException("Unexpected NTLM message singature: \"" + signature + "\". Expected signature: \"" + NTLMSSP + "\". Data: " + buf + ".");
+
+        // MessageType (CHALLENGE)
+        int messageType = buf.readSignedIntLE();
+        if (messageType != NtlmConstants.CHALLENGE)
+            throw new RuntimeException("Unexpected NTLM message type: " + messageType + ". Expected type: CHALLENGE (" + NtlmConstants.CHALLENGE + "). Data: " + buf
+                    + ".");
+
+        // TargetName
+        ntlmState.serverTargetName = readStringByDescription(buf);
+
+        // NegotiateFlags
+        ntlmState.negotiatedFlags = new NegoFlags(buf.readSignedIntLE());
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Server negotiate flags: " + ntlmState.negotiatedFlags + ".");
+
+        // ServerChallenge
+        ByteBuffer challenge = buf.readBytes(8);
+        ntlmState.serverChallenge = challenge.toByteArray();
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Server challenge: " + challenge + ".");
+        challenge.unref();
+
+        // Reserved/context
+        buf.skipBytes(8);
+
+        // TargetInfo
+        ByteBuffer targetInfo = readBlockByDescription(buf);
+
+        // Store raw target info block for Type3 message
+        ntlmState.serverTargetInfo = targetInfo.toByteArray();
+
+        // Parse target info block
+        parseTargetInfo(targetInfo);
+        targetInfo.unref();
+
+        // OS Version, NTLM revision, 8 bytes, Optional. Ignore it.
+
+        // Ignore rest of buffer with allocated blocks
+
+        buf.unref();
+    }
+
+    public void parseTargetInfo(ByteBuffer buf) {
+        // Parse attribute list
+
+        while (buf.remainderLength() > 0) {
+            int type = buf.readUnsignedShortLE();
+            int length = buf.readUnsignedShortLE();
+
+            if (type == MSV_AV_EOL)
+                // End of list
+                break;
+
+            ByteBuffer data = buf.readBytes(length);
+            parseAttribute(data, type, length);
+            data.unref();
+        }
+    }
+
+    public void parseAttribute(ByteBuffer buf, int type, int length) {
+        switch (type) {
+        case MSV_AV_NETBIOS_DOMAIN_NAME:
+            ntlmState.serverNetbiosDomainName = buf.readString(length, RdpConstants.CHARSET_16);
+            break;
+        case MSV_AV_NETBIOS_COMPUTER_NAME:
+            ntlmState.serverNetbiosComputerName = buf.readString(length, RdpConstants.CHARSET_16);
+            break;
+        case MSV_AV_DNS_DOMAIN_NAME:
+            ntlmState.serverDnsDomainName = buf.readString(length, RdpConstants.CHARSET_16);
+            break;
+        case MSV_AV_DNS_COMPUTER_NAME:
+            ntlmState.serverDnsComputerName = buf.readString(length, RdpConstants.CHARSET_16);
+            break;
+        case MSV_AV_DNS_TREE_NAME:
+            ntlmState.serverDnsTreeName = buf.readString(length, RdpConstants.CHARSET_16);
+            break;
+
+        case MSV_AV_TIMESTAMP:
+            ByteBuffer tmp = buf.readBytes(length);
+            ntlmState.serverTimestamp = tmp.toByteArray();
+            //*DEBUG*/System.out.println("Server timestamp: "+tmp.toPlainHexString());
+            tmp.unref();
+            break;
+
+        default:
+            // Ignore
+            //throw new RuntimeException("[" + this + "] ERROR: Unknown NTLM target info attribute: " + type + ". Data: " + buf + ".");
+
+        }
+
+    }
+
+    /**
+     * Read NTLM wide string, by it description. Buffer offset must point to
+     * beginning of NTLM message signature.
+     * 
+     * @param buf
+     *          buffer with cursor pointing to description
+     * @return
+     */
+    public static String readStringByDescription(ByteBuffer buf) {
+        ByteBuffer block = readBlockByDescription(buf);
+        String value = block.readString(block.length, RdpConstants.CHARSET_16);
+        block.unref();
+
+        return value;
+    }
+
+    public static ByteBuffer readBlockByDescription(ByteBuffer buf) {
+        int blockLength = buf.readUnsignedShortLE(); // In bytes
+        int allocatedSpace = buf.readUnsignedShortLE();
+        int offset = buf.readSignedIntLE();
+
+        if (allocatedSpace < blockLength)
+            blockLength = allocatedSpace;
+
+        if (offset > buf.length || offset < 0 || offset + allocatedSpace > buf.length)
+            throw new RuntimeException("ERROR: NTLM block is too long. Allocated space: " + allocatedSpace + ", block offset: " + offset + ", data: "
+                    + buf + ".");
+
+        // Move cursor to position of allocated block, starting from beginning of
+        // this buffer
+        int storedCursor = buf.cursor;
+        buf.cursor = offset;
+
+        // Read string
+        ByteBuffer value = buf.readBytes(blockLength);
+
+        // Restore cursor
+        buf.cursor = storedCursor;
+
+        return value;
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        0x30, (byte) 0x82, 0x01, 0x02, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 258 bytes
+        (byte) 0xa0, 0x03, // TAG: [0] (constructed) LEN: 3 bytes
+        0x02, 0x01, 0x03,  // TAG: [UNIVERSAL 2] (primitive) "INTEGER" LEN: 1 bytes, Version: 0x3
+        (byte) 0xa1, (byte) 0x81, (byte) 0xfa, // TAG: [1] (constructed) LEN: 250 bytes
+        0x30, (byte) 0x81, (byte) 0xf7, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 247 bytes
+        0x30, (byte) 0x81, (byte) 0xf4, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 244 bytes
+        (byte) 0xa0, (byte) 0x81, (byte) 0xf1, // TAG: [0] (constructed) LEN: 241 bytes
+        0x04, (byte) 0x81, (byte) 0xee, // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 238 bytes
+
+        0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, // "NTLMSSP\0"
+
+        0x02, 0x00, 0x00, 0x00, // MessageType (CHALLENGE) 
+        0x1e, 0x00, 0x1e, 0x00, 0x38, 0x00, 0x00, 0x00, // TargetName (length: 30, allocated space: 30, offset: 56)
+        0x35, (byte) 0x82, (byte) 0x8a, (byte) 0xe2, // NegotiateFlags
+        0x52, (byte) 0xbe, (byte) 0x83, (byte) 0xd1, (byte) 0xf8, (byte) 0x80, 0x16, 0x6a,  //  ServerChallenge 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  Reserved
+        (byte) 0x98, 0x00, (byte) 0x98, 0x00, 0x56, 0x00, 0x00, 0x00, // TargetInfo (length: 152, allocated space: 152, offset: 86)
+        0x06, 0x03, (byte) 0xd7, 0x24, 0x00, 0x00, 0x00, 0x0f,  // Version (6.3, build 9431) , NTLM current revision: 15
+
+
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00,  // Target name value: "WIN-LO419B2LSR0"
+
+        // Target Info value:
+        
+        // Attribute list
+
+        0x02, 0x00, // Item Type: NetBIOS domain name (0x0002, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x01, 0x00,  //  Item Type: NetBIOS computer name (0x0001, LE) 
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x04, 0x00,  // Item Type: DNS domain name (0x0004, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x03, 0x00,  // Item Type: DNS computer name (0x0003, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x07, 0x00,  // Item Type: Timestamp (0x0007, LE)
+        0x08, 0x00, //  Item Length: 8 (LE)
+        (byte) 0x99, 0x4f, 0x02, (byte) 0xd8, (byte) 0xf4, (byte) 0xaf, (byte) 0xce, 0x01, // TODO
+
+        // Attribute: End of list
+        0x00, 0x00,
+        0x00, 0x00, 
+    };
+    /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet, new byte[] {1, 2, 3}));
+        NtlmState state = new NtlmState();
+        Element ntlmssp_challenge = new ServerNtlmsspChallenge("ntlmssp_challenge", state);
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers());
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, ntlmssp_challenge, sink, mainSink);
+        pipeline.link("source", "ntlmssp_challenge", "mainSink");
+        pipeline.link("ntlmssp_challenge >" + OTOUT, "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        // Check state challenge
+        byte[] challenge = new byte[] {0x52, (byte)0xbe, (byte)0x83, (byte)0xd1, (byte)0xf8, (byte)0x80, 0x16, 0x6a};
+        if (state.serverChallenge == null)
+            throw new RuntimeException("Challenge was not extracted from server NTLMSSP Challenge packet.");
+        if (!Arrays.equals(challenge, state.serverChallenge))
+            throw new RuntimeException("Challenge was extracted from server NTLMSSP Challenge packet is not equal to expected. Actual value: "
+                    + state.serverChallenge + ", expected value: " + challenge + ".");
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspPubKeyPlus1.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspPubKeyPlus1.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspPubKeyPlus1.java
new file mode 100755
index 0000000..bbb75fc
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspPubKeyPlus1.java
@@ -0,0 +1,125 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp;
+
+import java.util.Arrays;
+
+import rdpclient.ntlmssp.asn1.TSRequest;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ServerNtlmsspPubKeyPlus1 extends OneTimeSwitch implements Element {
+
+    protected NtlmState ntlmState;
+
+    public ServerNtlmsspPubKeyPlus1(String id, NtlmState ntlmState) {
+        super(id);
+        this.ntlmState = ntlmState;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        TSRequest tsRequest = new TSRequest("TSRequest");
+        tsRequest.readTag(buf);
+
+        ByteBuffer encryptedPubKey = tsRequest.pubKeyAuth.value;
+        if (encryptedPubKey == null || encryptedPubKey.length == 0)
+            throw new RuntimeException("[" + this
+                    + "] ERROR: Unexpected message from RDP server. Expected encrypted server public key but got nothing instead. Data: " + buf);
+
+        byte[] decryptedPubKey = ntlmState.ntlm_DecryptMessage(encryptedPubKey.toByteArray());
+        //* DEBUG */System.out.println("Decrypted pub key:\n" + new ByteBuffer(decryptedPubKey).dump());
+
+        // Decrease first byte by 1
+        decryptedPubKey[0]--;
+
+        // Compare returned value with expected value
+        if (!Arrays.equals(decryptedPubKey, ntlmState.subjectPublicKey))
+            throw new RuntimeException("[" + this
+                    + "] ERROR: Unexpected message from RDP server. Expected encrypted server public key but an unknown response. Encryted key after decryption: "
+                    + new ByteBuffer(decryptedPubKey).toPlainHexString());
+
+        buf.unref();
+        switchOff(); // Ignore packet
+    }
+}
+
+/* @formatter:off */
+
+// CredSSP header in BER format:
+
+// 0x30, (byte) 0x82, 0x01, 0x2b, // TAG: [UNIVERSAL 16] (constructed)
+// "SEQUENCE" LEN: 299 bytes
+// (byte) 0xa0, 0x03, // TAG: [0] (constructed) LEN: 3 bytes
+// 0x02, 0x01, 0x03, // TAG: [UNIVERSAL 2] (primitive) "INTEGER" LEN: 1 bytes,
+// Version: 0x3
+// (byte) 0xa3, (byte) 0x82, 0x01, 0x22, // TAG: [3] (constructed) LEN: 290
+// bytes
+// 0x04, (byte) 0x82, 0x01, 0x1e, // TAG: [UNIVERSAL 4] (primitive)
+// "OCTET STRING" LEN: 286 bytes
+
+// ???
+
+// 0x01, 0x00, 0x00, 0x00, // ???
+// (byte) 0x98, (byte) 0xb0, 0x72, 0x48, 0x42, 0x09, (byte) 0xbd, 0x42, 0x00,
+// 0x00, 0x00, //
+// 0x00, (byte) 0xf6, 0x76, 0x0a, 0x40, (byte) 0xb4, 0x7b, (byte) 0xee, 0x69,
+// (byte) 0xfc, (byte) 0x95, 0x2d, 0x5f, 0x6a, (byte) 0xe8, (byte) 0x87, //
+// 0x4e, (byte) 0xeb, (byte) 0xae, 0x29, (byte) 0xf2, (byte) 0xde, 0x5e, 0x0a,
+// 0x6e, 0x45, (byte) 0xeb, (byte) 0x95, (byte) 0xd9, 0x48, (byte) 0xfc, 0x44,
+// //
+// 0x7a, 0x34, (byte) 0xb4, (byte) 0xc4, (byte) 0xee, (byte) 0x93, (byte) 0xd2,
+// (byte) 0xb4, (byte) 0xe5, (byte) 0xe5, (byte) 0xc1, 0x0f, (byte) 0x9e, 0x3b,
+// (byte) 0xce, (byte) 0xaa, //
+// 0x76, (byte) 0x9e, 0x2b, 0x33, 0x44, 0x76, 0x2f, 0x2f, (byte) 0x83, 0x34,
+// 0x3c, (byte) 0xe9, (byte) 0xc2, (byte) 0xeb, 0x0e, (byte) 0xce, //
+// 0x6c, (byte) 0xcd, 0x1c, (byte) 0xae, 0x74, 0x78, 0x3e, (byte) 0x8c, 0x17,
+// (byte) 0xb4, 0x39, (byte) 0x9a, 0x21, (byte) 0x99, (byte) 0xde, (byte) 0xae,
+// //
+// 0x72, 0x23, (byte) 0x94, (byte) 0xc6, (byte) 0xe9, (byte) 0xcb, 0x48, (byte)
+// 0xb1, 0x54, 0x20, 0x70, 0x70, (byte) 0xc0, 0x77, 0x10, 0x4b, //
+// (byte) 0x8a, (byte) 0xe0, (byte) 0xa0, 0x6c, (byte) 0xb9, 0x65, (byte) 0xfc,
+// 0x67, (byte) 0xe3, 0x3b, (byte) 0xb6, 0x46, 0x5e, (byte) 0xaf, (byte) 0xe7,
+// (byte) 0x92, //
+// 0x6a, (byte) 0xaf, (byte) 0x86, 0x4d, 0x74, 0x33, 0x49, 0x2a, (byte) 0xf0,
+// (byte) 0xdd, 0x66, (byte) 0xce, (byte) 0xec, (byte) 0xcc, 0x6b, 0x62, //
+// 0x4f, 0x35, (byte) 0xb5, 0x0f, (byte) 0x95, (byte) 0xd7, (byte) 0xf7, (byte)
+// 0xf3, 0x4b, 0x59, 0x5f, 0x29, (byte) 0xc9, (byte) 0xc4, (byte) 0xdc, 0x47, //
+// (byte) 0xe9, (byte) 0x8d, 0x47, (byte) 0xd2, 0x1d, 0x35, 0x43, (byte) 0xce,
+// (byte) 0xff, (byte) 0xd7, 0x6b, 0x28, (byte) 0xd8, 0x06, (byte) 0xe8, (byte)
+// 0xba, //
+// (byte) 0xf1, 0x4d, (byte) 0xba, 0x43, (byte) 0x8e, 0x64, (byte) 0xba, (byte)
+// 0xcd, (byte) 0xcb, (byte) 0xaf, 0x1a, 0x61, (byte) 0xd8, 0x11, 0x19, (byte)
+// 0xf7, //
+// (byte) 0xae, (byte) 0xfe, (byte) 0x94, 0x48, (byte) 0x8e, (byte) 0x9f, 0x57,
+// 0x17, (byte) 0xd2, (byte) 0xa3, (byte) 0xfd, 0x79, (byte) 0xb5, (byte) 0xa3,
+// 0x7d, (byte) 0xca, //
+// (byte) 0xff, (byte) 0x94, (byte) 0xb5, (byte) 0xb5, 0x03, (byte) 0xf3, 0x13,
+// 0x6a, 0x74, 0x7a, (byte) 0xae, (byte) 0x9d, (byte) 0xe9, 0x5c, 0x32, 0x42, //
+// 0x37, (byte) 0xa6, (byte) 0xb3, (byte) 0xf5, 0x4b, (byte) 0xaa, 0x22, 0x61,
+// (byte) 0xf5, 0x28, 0x5b, 0x41, 0x26, 0x32, 0x63, 0x5f, //
+// 0x43, (byte) 0xfd, 0x2e, 0x44, 0x7d, (byte) 0xfb, (byte) 0xb6, 0x09, (byte)
+// 0xc5, (byte) 0xc8, 0x33, (byte) 0xbe, (byte) 0x81, 0x08, (byte) 0xd4, 0x5f,
+// //
+// (byte) 0xad, (byte) 0xee, 0x49, 0x25, 0x62, 0x52, (byte) 0x83, (byte) 0xc1,
+// 0x3e, 0x17, 0x5b, (byte) 0xea, 0x4b, (byte) 0x90, 0x62, (byte) 0xf7, //
+// 0x4e, 0x28, (byte) 0xfb, (byte) 0xab, (byte) 0x9a, (byte) 0xbc, 0x5e, (byte)
+// 0xd4, (byte) 0xd5, 0x56, (byte) 0xf4, 0x4a, 0x2a, 0x7e, (byte) 0xd7, //
+
+/* @formatter:on */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/AlgorithmIdentifier.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/AlgorithmIdentifier.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/AlgorithmIdentifier.java
new file mode 100755
index 0000000..283c709
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/AlgorithmIdentifier.java
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp.asn1;
+
+import common.asn1.Any;
+import common.asn1.ObjectID;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * X509 SubjectPublicKeyInfo field ASN.1 description.
+ */
+public class AlgorithmIdentifier extends Sequence {
+    public ObjectID algorithm = new ObjectID("algorithm");
+    public Any parameters = new Any("parameters") {
+        {
+            optional = true;
+        }
+    };
+
+    public AlgorithmIdentifier(String name) {
+        super(name);
+        this.tags = new Tag[] {algorithm, parameters};
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoData.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoData.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoData.java
new file mode 100755
index 0000000..1e646b4
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoData.java
@@ -0,0 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp.asn1;
+
+import common.asn1.SequenceOf;
+import common.asn1.Tag;
+
+/**
+ * The NegoData structure contains the SPNEGO messages, as specified in
+ * [MS-SPNG] section 2.
+ * 
+ * <pre>
+ * NegoData ::= SEQUENCE OF SEQUENCE {
+ *   negoToken     [0] OCTET STRING
+ * }
+ * </pre>
+ * 
+ * If we write NegoItem as
+ * 
+ * <pre>
+ * NegoItem ::= SEQUENCE {
+ *   negoToken     [0] OCTET STRING
+ * }
+ * </pre>
+ * 
+ * then NegoData can be written as
+ * 
+ * <pre>
+ * NegoData ::= SEQUENCE OF NegoItem
+ * </pre>
+ * 
+ * <ul>
+ * <li>negoToken: One or more SPNEGO tokens, as specified in [MS-SPNG].
+ * </ul>
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc226781.aspx
+ */
+public class NegoData extends SequenceOf {
+
+    public NegoData(String name) {
+        super(name);
+        this.type = new NegoItem("NegoItem");
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new NegoData(name + suffix).copyFrom(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoItem.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoItem.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoItem.java
new file mode 100755
index 0000000..302ef5b
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoItem.java
@@ -0,0 +1,73 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp.asn1;
+
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * The NegoData structure contains the SPNEGO messages, as specified in
+ * [MS-SPNG] section 2.
+ * 
+ * <pre>
+ * NegoData ::= SEQUENCE OF SEQUENCE {
+ *   negoToken     [0] OCTET STRING
+ * }
+ * </pre>
+ * 
+ * If we write NegoItem as
+ * 
+ * <pre>
+ * NegoItem ::= SEQUENCE {
+ *   negoToken     [0] OCTET STRING
+ * }
+ * </pre>
+ * 
+ * then NegoData can be written as
+ * 
+ * <pre>
+ * NegoData ::= SEQUENCE OF NegoItem
+ * </pre>
+ * 
+ * <ul>
+ * <li>negoToken: One or more SPNEGO tokens, as specified in [MS-SPNG].
+ * </ul>
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc226781.aspx
+ */
+public class NegoItem extends Sequence {
+
+    public OctetString negoToken = new OctetString("negoToken") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 0;
+        }
+    };
+
+    public NegoItem(String name) {
+        super(name);
+        this.tags = new Tag[] {negoToken};
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new NegoItem(name + suffix).copyFrom(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/SubjectPublicKeyInfo.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/SubjectPublicKeyInfo.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/SubjectPublicKeyInfo.java
new file mode 100755
index 0000000..f2d6962
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/SubjectPublicKeyInfo.java
@@ -0,0 +1,35 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp.asn1;
+
+import common.asn1.BitString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * X509 SubjectPublicKeyInfo field ASN.1 description.
+ */
+public class SubjectPublicKeyInfo extends Sequence {
+    public AlgorithmIdentifier algorithm = new AlgorithmIdentifier("algorithm");
+    public BitString subjectPublicKey = new BitString("subjectPublicKey");
+
+    public SubjectPublicKeyInfo(String name) {
+        super(name);
+        this.tags = new Tag[] {algorithm, subjectPublicKey};
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCredentials.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCredentials.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCredentials.java
new file mode 100755
index 0000000..1133c7d
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCredentials.java
@@ -0,0 +1,62 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp.asn1;
+
+import common.asn1.Asn1Integer;
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * <pre>
+ * TSCredentials ::= SEQUENCE {
+ *   credType      [0] INTEGER,
+ *   credentials   [1] OCTET STRING
+ * }
+ * 
+ * credType:
+ *   1 - credentials contains a TSPasswordCreds structure that defines the user's password credentials.
+ *   2 - credentials contains a TSSmartCardCreds structure that defines the user's smart card credentials.
+ * </pre>
+ */
+public class TSCredentials extends Sequence {
+    public Asn1Integer credType = new Asn1Integer("credType") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 0;
+        }
+    };
+    public OctetString credentials = new OctetString("credentials") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 1;
+        }
+    };
+
+    public TSCredentials(String name) {
+        super(name);
+        this.tags = new Tag[] {credType, credentials};
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new TSCredentials(name + suffix).copyFrom(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCspDataDetail.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCspDataDetail.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCspDataDetail.java
new file mode 100755
index 0000000..170fed2
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCspDataDetail.java
@@ -0,0 +1,98 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp.asn1;
+
+import common.asn1.Asn1Integer;
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * <pre>
+ * TSCspDataDetail ::= SEQUENCE {
+ *   keySpec       [0] INTEGER,
+ *   cardName      [1] OCTET STRING OPTIONAL,
+ *   readerName    [2] OCTET STRING OPTIONAL,
+ *   containerName [3] OCTET STRING OPTIONAL,
+ *   cspName       [4] OCTET STRING OPTIONAL
+ * }
+ * </pre>
+ * <ul>
+ * <li>keySpec: Defines the specification of the user's smart card.
+ * 
+ * <li>cardName: Specifies the name of the smart card.
+ * 
+ * <li>readerName: Specifies the name of the smart card reader.
+ * 
+ * <li>containerName: Specifies the name of the certificate container.
+ * 
+ * <li>cspName: Specifies the name of the CSP.
+ * </ul>
+ * @see http://msdn.microsoft.com/en-us/library/cc226785.aspx
+ */
+public class TSCspDataDetail extends Sequence {
+    public Asn1Integer keySpec = new Asn1Integer("keySpec") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 0;
+        }
+    };
+    public OctetString cardName = new OctetString("cardName") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 1;
+            optional = true;
+        }
+    };
+    public OctetString readerName = new OctetString("readerName") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 2;
+            optional = true;
+        }
+    };
+    public OctetString containerName = new OctetString("containerName") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 3;
+            optional = true;
+        }
+    };
+    public OctetString cspName = new OctetString("cspName") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 4;
+            optional = true;
+        }
+    };
+
+    public TSCspDataDetail(String name) {
+        super(name);
+        this.tags = new Tag[] {keySpec, cardName, readerName, containerName, cspName};
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new TSCspDataDetail(name + suffix).copyFrom(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSPasswordCreds.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSPasswordCreds.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSPasswordCreds.java
new file mode 100755
index 0000000..83d756d
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSPasswordCreds.java
@@ -0,0 +1,76 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp.asn1;
+
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * <pre>
+ * TSPasswordCreds ::= SEQUENCE {
+ *   domainName    [0] OCTET STRING,
+ *   userName      [1] OCTET STRING,
+ *   password      [2] OCTET STRING
+ * }
+ * </pre>
+ * 
+ * <ul>
+ * <li>domainName: Contains the name of the user's account domain, as defined in
+ * [MS-GLOS].
+ * 
+ * <li>userName: Contains the user's account name.
+ * 
+ * <li>Password: Contains the user's account password.
+ * </ul>
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc226783.aspx
+ */
+public class TSPasswordCreds extends Sequence {
+    public OctetString domainName = new OctetString("domainName") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 0;
+        }
+    };
+    public OctetString userName = new OctetString("userName") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 1;
+        }
+    };
+    public OctetString password = new OctetString("password") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 2;
+        }
+    };
+
+    public TSPasswordCreds(String name) {
+        super(name);
+        this.tags = new Tag[] {domainName, userName, password};
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new TSPasswordCreds(name + suffix).copyFrom(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java
new file mode 100755
index 0000000..5599b61
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java
@@ -0,0 +1,202 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp.asn1;
+
+import common.asn1.Asn1Integer;
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+import streamer.ByteBuffer;
+
+/**
+ * The TSRequest structure is the top-most structure used by the CredSSP client
+ * and CredSSP server. It contains the SPNEGO messages between the client and
+ * server, and either the public key authentication messages that are used to
+ * bind to the TLS session or the client credentials that are delegated to the
+ * server. The TSRequest message is always sent over the TLS-encrypted channel
+ * between the client and server in a CredSSP Protocol exchange (see step 1 in
+ * section 3.1.5).
+ * 
+ * <pre>
+ * TSRequest ::= SEQUENCE {
+ *   version       [0] INTEGER,
+ *   negoTokens    [1] NegoData OPTIONAL,
+ *   authInfo      [2] OCTET STRING OPTIONAL,
+ *   pubKeyAuth    [3] OCTET STRING OPTIONAL
+ * }
+ * 
+ * </pre>
+ * <ul>
+ * 
+ * <li>version: This field specifies the supported version of the CredSSP
+ * Protocol. This field MUST be 2. If the version is greater than 2, a version 2
+ * client or server treats its peer as one that is compatible with version 2 of
+ * the CredSSP Protocol.
+ * 
+ * <li>negoTokens: A NegoData structure, as defined in section 2.2.1.1, that
+ * contains the SPNEGO messages that are passed between the client and server.
+ * 
+ * <li>authInfo: A TSCredentials structure, as defined in section 2.2.1.2, that
+ * contains the user's credentials that are delegated to the server. The
+ * authinfo field <b>MUST be encrypted</b> under the encryption key that is
+ * negotiated under the SPNEGO package.
+ * 
+ * <li>pubKeyAuth: This field is used to assure that the public key that is used
+ * by the server during the TLS handshake belongs to the target server and not
+ * to a "man in the middle". The client encrypts the public key it received from
+ * the server (contained in the X.509 certificate) in the TLS handshake from
+ * step 1, by using the confidentiality support of SPNEGO. The public key that
+ * is encrypted is the ASN.1-encoded SubjectPublicKey sub-field of
+ * SubjectPublicKeyInfo from the X.509 certificate, as specified in [RFC3280]
+ * section 4.1. The encrypted key is encapsulated in the pubKeyAuth field of the
+ * TSRequest structure and is sent over the TLS channel to the server. After the
+ * client completes the SPNEGO phase of the CredSSP Protocol, it uses
+ * GSS_WrapEx() for the negotiated protocol to encrypt the server's public key.
+ * The pubKeyAuth field carries the message signature and then the encrypted
+ * public key to the server. In response, the server uses the pubKeyAuth field
+ * to transmit to the client a modified version of the public key (as described
+ * in section 3.1.5) that is encrypted under the encryption key that is
+ * negotiated under SPNEGO.
+ * </ul>
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc226780.aspx
+ */
+public class TSRequest extends Sequence {
+    public Asn1Integer version = new Asn1Integer("version") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 0;
+        }
+    };
+    public NegoData negoTokens = new NegoData("negoTokens") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 1;
+            optional = true;
+        }
+    };
+    public OctetString authInfo = new OctetString("authInfo") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 2;
+            optional = true;
+        }
+    };
+    public OctetString pubKeyAuth = new OctetString("pubKeyAuth") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 3;
+            optional = true;
+        }
+    };
+
+    public TSRequest(String name) {
+        super(name);
+        this.tags = new Tag[] {version, negoTokens, authInfo, pubKeyAuth};
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new TSRequest(name + suffix).copyFrom(this);
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String[] args) {
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        0x30, (byte) 0x82, 0x01, 0x02, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 258 bytes
+        (byte) 0xa0, 0x03, // TAG: [0] (constructed) LEN: 3 bytes
+        0x02, 0x01, 0x03,  // TAG: [UNIVERSAL 2] (primitive) "INTEGER" LEN: 1 bytes, Version: 0x3
+        (byte) 0xa1, (byte) 0x81, (byte) 0xfa, // TAG: [1] (constructed) LEN: 250 bytes
+        0x30, (byte) 0x81, (byte) 0xf7, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 247 bytes
+        0x30, (byte) 0x81, (byte) 0xf4, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 244 bytes
+        (byte) 0xa0, (byte) 0x81, (byte) 0xf1, // TAG: [0] (constructed) LEN: 241 bytes
+        0x04, (byte) 0x81, (byte) 0xee, // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 238 bytes
+
+        0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, // "NTLMSSP\0"
+
+        0x02, 0x00, 0x00, 0x00, // MessageType (CHALLENGE) 
+        0x1e, 0x00, 0x1e, 0x00, 0x38, 0x00, 0x00, 0x00, // TargetName (length: 30, allocated space: 30, offset: 56)
+        0x35, (byte) 0x82, (byte) 0x8a, (byte) 0xe2, // NegotiateFlags TODO
+        0x52, (byte) 0xbe, (byte) 0x83, (byte) 0xd1, (byte) 0xf8, (byte) 0x80, 0x16, 0x6a,  //  ServerChallenge 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  Reserved
+        (byte) 0x98, 0x00, (byte) 0x98, 0x00, 0x56, 0x00, 0x00, 0x00, // TargetInfo (length: 152, allocated space: 152, offset: 86)
+        0x06, 0x03, (byte) 0xd7, 0x24, 0x00, 0x00, 0x00, 0x0f,  // Version (6.3, build 9431) , NTLM current revision: 15
+
+
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00,  // Target name value: "WIN-LO419B2LSR0"
+
+        // Target Info value:
+        
+        // Attribute list
+
+        0x02, 0x00, // Item Type: NetBIOS domain name (0x0002, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x01, 0x00,  //  Item Type: NetBIOS computer name (0x0001, LE) 
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x04, 0x00,  // Item Type: DNS domain name (0x0004, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x03, 0x00,  // Item Type: DNS computer name (0x0003, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x07, 0x00,  // Item Type: Timestamp (0x0007, LE)
+        0x08, 0x00, //  Item Length: 8 (LE)
+        (byte) 0x99, 0x4f, 0x02, (byte) 0xd8, (byte) 0xf4, (byte) 0xaf, (byte) 0xce, 0x01, // TODO
+
+        // Attribute: End of list
+        0x00, 0x00,
+        0x00, 0x00, 
+    };
+    /* @formatter:on */
+
+        TSRequest request = new TSRequest("TSRequest");
+
+        // Read request from buffer
+        // System.out.println("Request BER tree before parsing: " + request);
+        ByteBuffer toReadBuf = new ByteBuffer(packet);
+        request.readTag(toReadBuf);
+        // System.out.println("Request BER tree after parsing: " + request);
+
+        // System.out.println("version value: " + request.version.value);
+        // System.out.println("negoToken value: " + ((NegoItem)
+        // request.negoTokens.tags[0]).negoToken.value);
+
+        // Write request to buffer and compare with original
+        ByteBuffer toWriteBuf = new ByteBuffer(packet.length + 100, true);
+        request.writeTag(toWriteBuf);
+        toWriteBuf.trimAtCursor();
+
+        if (!toReadBuf.equals(toWriteBuf))
+            throw new RuntimeException("Data written to buffer is not equal to data read from buffer. \nExpected: " + toReadBuf + "\nActual: " + toWriteBuf + ".");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSSmartCardCreds.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSSmartCardCreds.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSSmartCardCreds.java
new file mode 100755
index 0000000..9889747
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSSmartCardCreds.java
@@ -0,0 +1,90 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp.asn1;
+
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * <pre>
+ * TSSmartCardCreds ::= SEQUENCE {
+ *   pin           [0] OCTET STRING,
+ *   cspData       [1] TSCspDataDetail,
+ *   userHint      [2] OCTET STRING OPTIONAL,
+ *   domainHint    [3] OCTET STRING OPTIONAL
+ * }
+ * </pre>
+ * 
+ * <ul>
+ * <li>pin: Contains the user's smart card PIN.
+ * 
+ * <li>cspData: A TSCspDataDetail structure that contains information about the
+ * cryptographic service provider (CSP).
+ * 
+ * <li>userHint: Contains the user's account hint.
+ * 
+ * <li>domainHint: Contains the user's domain name to which the user's account
+ * belongs. This name could be entered by the user when the user is first
+ * prompted for the PIN.
+ * </ul>
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc226784.aspx
+ */
+public class TSSmartCardCreds extends Sequence {
+    public OctetString pin = new OctetString("pin") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 0;
+        }
+    };
+    public TSCspDataDetail cspData = new TSCspDataDetail("cspData") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 1;
+        }
+    };
+    public OctetString userHint = new OctetString("userHint") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 2;
+            optional = true;
+        }
+    };
+    public OctetString domainHint = new OctetString("domainHint") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 3;
+            optional = true;
+        }
+    };
+
+    public TSSmartCardCreds(String name) {
+        super(name);
+        this.tags = new Tag[] {pin, cspData, userHint, domainHint};
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new TSSmartCardCreds(name + suffix).copyFrom(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/package-info.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/package-info.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/package-info.java
new file mode 100755
index 0000000..4708c0f
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/package-info.java
@@ -0,0 +1,71 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+/**
+ * 
+ * CredSSP/SPNEGO/NTLMSSP implementation.
+ * 
+ * CredSSP ASN.1 definition:
+ * 
+ <pre>
+CredSSP DEFINITIONS EXPLICIT TAGS ::=
+
+BEGIN
+
+TSPasswordCreds ::= SEQUENCE {
+  domainName    [0] OCTET STRING,
+  userName      [1] OCTET STRING,
+  password      [2] OCTET STRING
+}
+
+TSCspDataDetail ::= SEQUENCE {
+  keySpec       [0] INTEGER,
+  cardName      [1] OCTET STRING OPTIONAL,
+  readerName    [2] OCTET STRING OPTIONAL,
+  containerName [3] OCTET STRING OPTIONAL,
+  cspName       [4] OCTET STRING OPTIONAL
+}
+
+TSSmartCardCreds ::= SEQUENCE {
+  pin           [0] OCTET STRING,
+  cspData       [1] TSCspDataDetail,
+  userHint      [2] OCTET STRING OPTIONAL,
+  domainHint    [3] OCTET STRING OPTIONAL
+}
+
+TSCredentials ::= SEQUENCE {
+  credType      [0] INTEGER,
+  credentials   [1] OCTET STRING
+}
+
+NegoData ::= SEQUENCE OF SEQUENCE {
+  negoToken     [0] OCTET STRING
+}
+
+TSRequest ::= SEQUENCE {
+  version       [0] INTEGER,
+  negoTokens    [1] NegoData OPTIONAL,
+  authInfo      [2] OCTET STRING OPTIONAL,
+  pubKeyAuth    [3] OCTET STRING OPTIONAL
+}
+
+END
+</pre>
+
+For packet flow, @see http://msdn.microsoft.com/en-us/library/cc226794.aspx
+ */
+package rdpclient.ntlmssp;
+


[19/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSAttachUserRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSAttachUserRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSAttachUserRequest.java
deleted file mode 100644
index 10a7eff..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSAttachUserRequest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240684.aspx
- */
-public class ClientMCSAttachUserRequest extends OneTimeSwitch {
-
-  public ClientMCSAttachUserRequest(String id) {
-    super(id);
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    throw new RuntimeException("Unexpected packet: " + buf + ".");
-  }
-
-  @Override
-  protected void onStart() {
-    super.onStart();
-
-    int length = 1;
-    ByteBuffer buf = new ByteBuffer(length, true);
-
-    buf.writeByte(0x28); // AttachUserRequest
-
-    pushDataToOTOut(buf);
-
-    switchOff();
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    /* @formatter:off */
-    byte[] packet = new byte[] {
-
-        0x03, 0x00, 0x00, 0x08,  //  TPKT Header (length = 8 bytes)
-        0x02, (byte) 0xf0, (byte) 0x80,  //  X.224 Data TPDU
-        
-        // PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
-        0x28, 
-        
-        // 0x28:
-        // 0 - --\
-        // 0 -   |
-        // 1 -   | CHOICE: From DomainMCSPDU select attachUserRequest (10) 
-        // 0 -   | of type AttachUserRequest
-        // 1 -   |
-        // 0 - --/
-        // 0 - padding
-        // 0 - padding
-
-    };
-    /* @formatter:on */
-
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-    Element todo = new ClientMCSAttachUserRequest("TODO");
-    Element x224 = new ClientX224DataPdu("x224");
-    Element tpkt = new ClientTpkt("tpkt");
-    Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-    Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, todo, x224, tpkt, sink, mainSink);
-    pipeline.link("source", "TODO", "mainSink");
-    pipeline.link("TODO >" + OTOUT, "x224", "tpkt", "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs.java
deleted file mode 100644
index f082539..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs.java
+++ /dev/null
@@ -1,222 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * The MCS Channel Join Request PDUs are sent sequentially. The first PDU is
- * sent after receiving the MCS Attach User Confirm PDU and subsequent PDUs are
- * sent after receiving the MCS Channel Join Confirm PDU for the previous
- * request. Sending of the MCS Channel Join Request PDUs MUST continue until all
- * channels have been successfully joined.
- * 
- * @see http://msdn.microsoft.com/en-us/library/cc240686.aspx
- */
-public class ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs extends OneTimeSwitch {
-
-  private static final int MCS_CHANNEL_CONFIRM_PDU = 15;
-
-  protected int[] channels;
-  protected int channelRequestsSent = 0;
-
-  protected RdpState state;
-
-  public ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs(String id, int[] channels, RdpState state) {
-    super(id);
-    this.channels = channels;
-    this.state=state;
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    // Parse channel confirm response
-    int typeAndFlags = buf.readUnsignedByte();
-    int type = typeAndFlags >> 2;
-    // int flags = typeAndFlags & 0x3;
-
-    if (type != MCS_CHANNEL_CONFIRM_PDU)
-      throw new RuntimeException("["+this+"] ERROR: Incorrect type of MCS AttachUserConfirm PDU. Expected value: 15, actual value: " + type + ", data: " + buf + ".");
-
-    int rtSuccess = buf.readUnsignedByte() >> 4;
-    if (rtSuccess != 0)
-      throw new RuntimeException("["+this+"] ERROR: Cannot connect to channel: request failed. Error code: " + rtSuccess + ", channel ID: " + channels[channelRequestsSent - 1]
-          + ", data: " + buf + ".");
-
-    // Initiator and requested fields MAY be ignored, however, the channelId
-    // field MUST be examined. If the value of the channelId field does not
-    // correspond with the value of the channelId field sent in the previous MCS
-    // Channel Join Request PDU the connection SHOULD be dropped.
-
-    // Initiator: 1007 (6+1001)
-    // int initator=buf.readUnsignedShort();
-    buf.skipBytes(2);
-
-    // Requested channel
-    // int requestedChannel=buf.readUnsignedShort();
-    buf.skipBytes(2);
-
-    // Actual channel
-    int actualChannel = buf.readUnsignedShort();
-    if (actualChannel != channels[channelRequestsSent - 1])
-      throw new RuntimeException("Unexpeceted channeld ID returned. Expected channeld ID: " + channels[channelRequestsSent - 1] + ", actual channel ID: "
-          + actualChannel + ", data: " + buf + ".");
-    
-    state.channelJoined(actualChannel);
-    
-    buf.unref();
-    
-
-    if (channelRequestsSent < channels.length)
-      sendChannelRequest(channels[channelRequestsSent++]);
-    else
-      switchOff();
-  }
-
-  @Override
-  protected void onStart() {
-    super.onStart();
-
-    sendChannelRequest(channels[channelRequestsSent++]);
-
-    // Switch off after receiving response(s)
-  }
-
-  private void sendChannelRequest(int channel) {
-    ByteBuffer buf = new ByteBuffer(5, true);
-
-    buf.writeByte(0x38); // Channel Join request
-
-    buf.writeShort(0x03); // ChannelJoinRequest::initiator: 1004
-    buf.writeShort(channel);
-
-    pushDataToOTOut(buf);
-  }
-
-  /**
-   * Example.
-   * 
-   * @see http://msdn.microsoft.com/en-us/library/cc240834.aspx
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    /* @formatter:off */
-    byte[] clientRequestPacket = new byte[] {
-        0x03, 0x00, 0x00, 0x0c,  //  TPKT Header (length = 12 bytes)
-        0x02, (byte) 0xf0, (byte) 0x80,  //  X.224 Data TPDU
-        
-        // PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
-        0x38, 0x00, 0x03, 0x03, (byte) 0xef, 
-
-         // 0x38:
-         // 0 - --\
-         // 0 -   |
-         // 1 -   | CHOICE: From DomainMCSPDU select channelJoinRequest (14) 
-         // 1 -   | of type ChannelJoinRequest
-         // 1 -   |
-         // 0 - --/
-         // 0 - padding
-         // 0 - padding
-
-         // 0x00:
-         // 0 - --\
-         // 0 -   | 
-         // 0 -   | 
-         // 0 -   | 
-         // 0 -   | 
-         // 0 -   | 
-         // 0 -   | 
-         // 0 -   | 
-         //       | ChannelJoinRequest::initiator = 0x03 + 1001 = 1004
-         // 0x03: |
-         // 0 -   | 
-         // 0 -   | 
-         // 0 -   | 
-         // 0 -   | 
-         // 0 -   | 
-         // 1 -   | 
-         // 1 -   | 
-         // 0 - --/
-
-         // 0x03:
-         // 0 - --\
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 1 -   |
-         // 1 -   |
-         //       | ChannelJoinRequest::channelId = 0x03ef = 1007
-         // 0xef: |
-         // 1 -   |
-         // 1 -   |
-         // 1 -   |
-         // 0 -   |
-         // 1 -   |
-         // 1 -   |
-         // 1 -   |
-         // 1 - --/
-    };
-    
-    byte[] serverResponsePacket = new byte[] {
-        // MCS Channel Confirm
-    (byte)0x3e, 
-    
-    // result: rt-successful (0)
-    (byte)0x00, 
-    
-    // Initiator: 1007 (6+1001)
-    (byte)0x00, (byte)0x06, 
-    
-    // Requested channel
-    (byte)0x03, (byte)0xef,
-    
-    // Actual channel
-    (byte)0x03, (byte)0xef,
-    };
-    /* @formatter:on */
-
-    RdpState rdpState = new RdpState();
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(serverResponsePacket, new byte[] { 1, 2, 3 }));
-    Element todo = new ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs("channels", new int[] { 1007 }, rdpState);
-    Element x224 = new ClientX224DataPdu("x224");
-    Element tpkt = new ClientTpkt("tpkt");
-    Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(clientRequestPacket));
-    Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, todo, x224, tpkt, sink, mainSink);
-    pipeline.link("source", "channels", "mainSink");
-    pipeline.link("channels >" + OTOUT, "x224", "tpkt", "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSConnectInitial.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSConnectInitial.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSConnectInitial.java
deleted file mode 100644
index 0189987..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSConnectInitial.java
+++ /dev/null
@@ -1,669 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class ClientMCSConnectInitial extends OneTimeSwitch {
-
-  public ClientMCSConnectInitial(String id) {
-    super(id);
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    throw new RuntimeException("Unexpected packet: " + buf + ".");
-  }
-
-  @Override
-  protected void onStart() {
-    super.onStart();
-
-    int length = 1024; // Large enough
-    ByteBuffer buf = new ByteBuffer(length, true);
-
-    /* @formatter:off */
-    buf.writeBytes(new byte[] {
-//        - T125: MCSConnect Initial
-//        - MCSConnectInitial: Identifier=Generic Conference Control (0.0.20.124.0.1), ConnectPDULength=254
-//         - ConnectInitialHeader: 
-      (byte)0x7F, (byte)0x65, 
-//          - AsnId: Application Constructed Tag (101)
-//           - HighTag: 
-//              Class:     (01......) Application (1)
-//              Type:      (..1.....) Constructed
-//              TagNumber: (...11111)
-//              TagValueEnd: 101 (0x65)
-      (byte)0x82, (byte)0x01, (byte)0x6C, 
-//          - AsnLen: Length = 364, LengthOfLength = 2
-//             LengthType: LengthOfLength = 2
-//             Length: 364 bytes
-      (byte)0x04, (byte)0x01, (byte)0x01, 
-//         - CallingDomainSelector: 0x1
-//          - AsnOctetStringHeader: 
-//           - AsnId: OctetString type (Universal 4)
-//            - LowTag: 
-//               Class:    (00......) Universal (0)
-//               Type:     (..0.....) Primitive
-//               TagValue: (...00100) 4
-//           - AsnLen: Length = 1, LengthOfLength = 0
-//              Length: 1 bytes, LengthOfLength = 0
-//            OctetStream: 0x1
-      (byte)0x04, (byte)0x01, (byte)0x01,
-//         - CalledDomainSelector: 0x1
-//          - AsnOctetStringHeader: 
-//           - AsnId: OctetString type (Universal 4)
-//            - LowTag: 
-//               Class:    (00......) Universal (0)
-//               Type:     (..0.....) Primitive
-//               TagValue: (...00100) 4
-//           - AsnLen: Length = 1, LengthOfLength = 0
-//              Length: 1 bytes, LengthOfLength = 0
-//            OctetStream: 0x1
-      (byte)0x01, (byte)0x01, (byte)0xFF,
-//         - UpwardFlag: True
-//          - AsnBooleanHeader: 
-//           - AsnId: Boolean type (Universal 1)
-//            - LowTag: 
-//               Class:    (00......) Universal (0)
-//               Type:     (..0.....) Primitive
-//               TagValue: (...00001) 1
-//           - AsnLen: Length = 1, LengthOfLength = 0
-//              Length: 1 bytes, LengthOfLength = 0
-//            Tf: 255 (0xFF)
-
-//
-//         - TargetParameters: Length = 26, LengthOfLength = 0
-      (byte)0x30, (byte)0x1A, 
-//          - DomainParametersHeader: 0x1
-//           - AsnId: Sequence and SequenceOf types (Universal 16)
-//            - LowTag: 
-//               Class:    (00......) Universal (0)
-//               Type:     (..1.....) Constructed
-//               TagValue: (...10000) 16
-//           - AsnLen: Length = 26, LengthOfLength = 0
-//              Length: 26 bytes, LengthOfLength = 0
-      (byte)0x02, (byte)0x01, (byte)0x22, 
-//          - ChannelIds: 34
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 34 (0x22)
-      (byte)0x02, (byte)0x01, (byte)0x02,
-//          - UserIDs: 2
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 2 (0x2)
-      (byte)0x02, (byte)0x01, (byte)0x00,
-//          - TokenIds: 0
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 0 (0x0)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - NumPriorities: 1
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x01, (byte)0x00,
-//          - MinThroughput: 0
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 0 (0x0)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - Height: 1
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF,
-//          - MCSPDUsize: 65535
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 3, LengthOfLength = 0
-//               Length: 3 bytes, LengthOfLength = 0
-//             AsnInt: 65535 (0xFFFF)
-      (byte)0x02, (byte)0x01, (byte)0x02, 
-//          - protocolVersion: 2
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 2 (0x2)
-
-//      
-//         - MinimumParameters: Length = 25, LengthOfLength = 0
-      (byte)0x30, (byte)0x19, 
-//          - DomainParametersHeader: 0x1
-//           - AsnId: Sequence and SequenceOf types (Universal 16)
-//            - LowTag: 
-//               Class:    (00......) Universal (0)
-//               Type:     (..1.....) Constructed
-//               TagValue: (...10000) 16
-//           - AsnLen: Length = 25, LengthOfLength = 0
-//              Length: 25 bytes, LengthOfLength = 0
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - ChannelIds: 1
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - UserIDs: 1
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - TokenIds: 1
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - NumPriorities: 1
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x01, (byte)0x00,
-//          - MinThroughput: 0
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 0 (0x0)
-      (byte)0x02, (byte)0x01, (byte)0x01, 
-//          - Height: 1
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x02, (byte)0x04, (byte)0x20, 
-//          - MCSPDUsize: 1056
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 2, LengthOfLength = 0
-//               Length: 2 bytes, LengthOfLength = 0
-//             AsnInt: 1056 (0x420)
-      (byte)0x02, (byte)0x01, (byte)0x02, 
-//          - protocolVersion: 2
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 2 (0x2)
-//         - MaximumParameters: Length = 31, LengthOfLength = 0
-//          - DomainParametersHeader: 0x1
-      (byte)0x30, (byte)0x1F,
-//           - AsnId: Sequence and SequenceOf types (Universal 16)
-//            - LowTag: 
-//               Class:    (00......) Universal (0)
-//               Type:     (..1.....) Constructed
-//               TagValue: (...10000) 16
-//           - AsnLen: Length = 31, LengthOfLength = 0
-//              Length: 31 bytes, LengthOfLength = 0
-      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF, 
-//          - ChannelIds: 65535
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 3, LengthOfLength = 0
-//               Length: 3 bytes, LengthOfLength = 0
-//             AsnInt: 65535 (0xFFFF)
-      (byte)0x02, (byte)0x02, (byte)0xFC, (byte)0x17, 
-//          - UserIDs: 64535
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 2, LengthOfLength = 0
-//               Length: 2 bytes, LengthOfLength = 0
-//             AsnInt: 64535 (0xFC17)
-      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF,
-//          - TokenIds: 65535
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 3, LengthOfLength = 0
-//               Length: 3 bytes, LengthOfLength = 0
-//             AsnInt: 65535 (0xFFFF)
-      (byte)0x02, (byte)0x01, (byte)0x01, 
-//          - NumPriorities: 1
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x01, (byte)0x00, 
-//          - MinThroughput: 0
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 0 (0x0)
-      (byte)0x02, (byte)0x01, (byte)0x01, 
-//          - Height: 1
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF, 
-//          - MCSPDUsize: 65535
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 3, LengthOfLength = 0
-//               Length: 3 bytes, LengthOfLength = 0
-//             AsnInt: 65535 (0xFFFF)
-      (byte)0x02, (byte)0x01, (byte)0x02, 
-//          - protocolVersion: 2
-//           - AsnIntegerHeader: 
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 2 (0x2)
-//         - UserData: Identifier=Generic Conference Contro (0.0.20.124.0.1), ConnectPDULength=254
-//          - UserDataHeader: 
-      (byte)0x04, (byte)0x82, (byte)0x01, (byte)0x07, 
-//           - AsnId: OctetString type (Universal 4)
-//            - LowTag: 
-//               Class:    (00......) Universal (0)
-//               Type:     (..0.....) Primitive
-//               TagValue: (...00100) 4
-//           - AsnLen: Length = 263, LengthOfLength = 2
-//              LengthType: LengthOfLength = 2
-//              Length: 263 bytes
-      (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x14, (byte)0x7C, (byte)0x00, (byte)0x01, 
-//          - AsnBerObjectIdentifier: Generic Conference Contro (0.0.20.124.0.1)
-//           - AsnObjectIdentifierHeader: 
-//            - AsnId: Reserved for use by the encoding rules (Universal 0)
-//             - LowTag: 
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00000) 0
-//            - AsnLen: Length = 5, LengthOfLength = 0
-//               Length: 5 bytes, LengthOfLength = 0
-//             First: 0 (0x0)
-//             Final: 20 (0x14)
-//             Final: 124 (0x7C)
-//             Final: 0 (0x0)
-//             Final: 1 (0x1)
-      (byte)0x80, (byte)0xFE, 
-//          - ConnectPDULength: 254
-//             Align: No Padding
-//             Length: 254
-      (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x10,
-//          - ConnectGCCPDU: conferenceCreateRequest
-//             ExtensionBit: 0 (0x0)
-//           - ChoiceValue: conferenceCreateRequest
-//              Value: (000.....) 0x0
-//           - conferenceCreateRequest: 
-//              ExtensionBit: 0 (0x0)
-//              convenerPasswordPresent: 0 (0x0)
-//              passwordPresent: 0 (0x0)
-//              conductorPrivilegesPresent: 0 (0x0)
-//              conductedPrivilegesPresent: 0 (0x0)
-//              nonConductedPrivilegesPresent: 0 (0x0)
-//              conferenceDescriptionPresent: 0 (0x0)
-//              callerIdentifierPresent: 0 (0x0)
-//              userDataPresent: 1 (0x1)
-//            - conferenceName: 
-//               ExtensionBit: 0 (0x0)
-//               textPresent: 0 (0x0)
-//             - numeric: 1
-//              - SimpleNumericString: 1
-//               - NumericString: 1
-//                - Align: No Padding
-//                   Padding1: (0.......) 0x0
-//                - Length: 1
-//                   Value: (00000000) 0x0
-//                - Restrictedstr: 1
-//                   FourBits: (0001....) 0x1
-//            - lockedConference: False
-//               Value: False 0.......
-//            - listedConference: False
-//               Value: False 0.......
-//            - conductibleConference: False
-//               Value: False 0.......
-//            - TerminationMethod: automatic
-//               ExtensionBit: 0 (0x0)
-//             - RootIndex: 0
-//                Value: (0.......) 0x0
-//            - userData: 
-      (byte)0x00, (byte)0x01, 
-//             - Size: 1
-//              - Align: No Padding
-//                 Padding7: (0000000.) 0x0
-//                Length: 1
-//             - UserData: 0x44756361
-      (byte)0xC0, (byte)0x00, (byte)0x44, (byte)0x75, (byte)0x63, (byte)0x61, 
-//                valuePresent: 1 (0x1)
-//              - key: h221NonStandard "Duca"
-//               - ChoiceValue: h221NonStandard
-//                  Value: (1.......) 0x1
-//               - h221NonStandard: 
-//                - H221NonStandardIdentifier: length: 4
-//                 - ConstrainedLength: 4
-//                    Value: (00000000) 0x0
-//                 - Align: No Padding
-//                    Padding6: (000000..) 0x0
-//                   Value: Binary Large Object (4 Bytes) "Duca"
-//              - ClientMcsConnectInitialPdu: 
-      (byte)0x80, (byte)0xF0, 
-//               - RDPGCCUserDataRequestLength: 240
-//                  Align: No Padding
-//                  Length: 240
-//               - TsUd: CS_CORE
-      (byte)0x01, (byte)0xC0, (byte)0xD8, (byte)0x00, 
-//                - TsUdHeader: Type = CS_CORE, Length = 216
-//                   Type: CS_CORE
-//                   Length: 216 (0xD8)
-//                - TsUdCsCore: 
-      (byte)0x04, (byte)0x00, (byte)0x08, (byte)0x00, 
-//                   Version: RDP 5.0, 5.1, 5.2, 6.0, 6.1, and 7.0 
-      (byte)0x00, (byte)0x04, 
-//                   DesktopWidth: 1024 (0x400)
-      (byte)0x00, (byte)0x03, 
-//                   DesktopHeight: 768 (0x300)
-      (byte)0x01, (byte)0xCA, 
-//                   ColorDepth: 8 bpp
-      (byte)0x03, (byte)0xAA, 
-//                   SASSequence: 0xaa03, SHOULD be set to RNS_UD_SAS_DEL(0xAA03)
-      (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, 
-//                   KeyboardLayout: Language: English, Location: United States
-      (byte)0x28, (byte)0x0A, (byte)0x00, (byte)0x00, 
-//                   ClientBuild: 2600 (0xA28)
-      (byte)0x61, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x6C, (byte)0x00, (byte)0x6C, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x33, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-//                   ClientName: apollo3
-      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-//                   KeyboardType: Undefined value: 0
-      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-//                   KeyboardSubType: 0 (0x0)
-      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-//                   KeyboardFunctionKey: 0 (0x0)
-      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-//                   ImeFileName: 
-      (byte)0x01, (byte)0xCA, 
-//                   PostBeta2ColorDepth: 8 bpp
-      (byte)0x01, (byte)0x00, 
-//                   ClientProductId: 0x1, SHOULD be set to initialized to 1
-      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-//                   SerialNumber: 0x0, SHOULD be set to 0
-      (byte)0x10, (byte)0x00, 
-//                   HighColorDepth: 16-bit 565 RGB
-      (byte)0x07, (byte)0x00, 
-//                 - SupportedColorDepth: 7 (0x7)
-//                    Support24BPP: (...............1) Support 24BPP
-//                    Support16BPP: (..............1.) Support 16BPP
-//                    Support15BPP: (.............1..) Support 15BPP
-//                    Support32BPP: (............0...) Not Support 32BPP
-//                    Reserved:     (000000000000....)
-      (byte)0x01, (byte)0x00, 
-//                 - EarlyCapabilityFlags: 1 (0x1)
-//                    SupportSetErrorPdu:      (...............1) Indicates that the client supports the Set Error Info PDU
-//                    Want32BppSession:        (..............0.) Client is not requesting 32BPP session
-//                    SupportStatusInfoPdu:    (.............0..) Client not supports the Server Status Info PDU
-//                    StrongAsymmetricKeys:    (............0...) Not support asymmetric keys larger than 512-bits
-//                    Unused:                  (...........0....)
-//                    ValidConnection:         (..........0.....) Not Indicates ConnectionType field contains valid data
-//                    SupportMonitorLayoutPdu: (.........0......) Not Indicates that the client supports the Monitor Layout PDU
-//                    Unused2:                 (000000000.......)
-      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-//      ClientDigProductId: 
-(byte)0x00, 
-//      connectionType: invalid connection type
-(byte)0x00, 
-//      pad1octet: 0 (0x0)
-(byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 
-//      ServerSelectedProtocols: TLS 1.0
-//
-//  - TsUd: CS_CLUSTER
-//   - TsUdHeader: Type = CS_CLUSTER, Length = 12
-(byte)0x04, (byte)0xC0, 
-//      Type: CS_CLUSTER
-(byte)0x0C, (byte)0x00, 
-//      Length: 12 (0xC)
-(byte)0x0D, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-//   - TsUdCsCluster: 
-//    - Flags: 13 (0xD)
-//       RedirectedSupported: (...............................1) Support Redirected
-//       SessionIDFieldValid: (..............................0.) SessionID Field not Valid
-//       SupportedVersion:    (..........................0011..) REDIRECTION_VERSION4
-//       RedirectedSmartcard: (.........................0......) Not Logon with Smartcard
-//       Unused:           (0000000000000000000000000.......)
-//      RedirectedSessionID: 0 (0x0)
-//
-//  - TsUd: CS_SECURITY
-//   - TsUdHeader: Type = CS_SECURITY, Length = 12
-(byte)0x02, (byte)0xC0, 
-//      Type: CS_SECURITY
-(byte)0x0C, (byte)0x00, 
-//      Length: 12 (0xC)
-//      
-//   - TsUdCsSec: 
-(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-//    - EncryptionMethod: 
-//       Support40Bit:  (...............................0) Not Support 
-//       Support128Bit: (..............................0.) Not Support 128-bit
-//       Reserved1:     (.............................0..)
-//       Support56Bit:  (............................0...) Not Support 56-bit
-//       SupportFIPS:   (...........................0....) Not Support FIPS Compliant
-//       Reserved2:     (000000000000000000000000000.....)
-(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-//    - ExtEncryptionMethod: 
-//       Support40Bit:  (...............................0) Not Support 
-//       Support128Bit: (..............................0.) Not Support 128-bit
-//       Reserved1:     (.............................0..)
-//       Support56Bit:  (............................0...) Not Support 56-bit
-//       SupportFIPS:   (...........................0....) Not Support FIPS Compliant
-//       Reserved2:     (000000000000000000000000000.....)
-    });
-    /* @formatter:on */
-
-    buf.length = buf.cursor;
-
-    pushDataToOTOut(buf);
-
-    switchOff();
-  }
-
-  /**
-   * Example.
-   * 
-   * @see http://msdn.microsoft.com/en-us/library/cc240836.aspx
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    /* @formatter:off */
-    byte[] packet = new byte[] {
-        // TPKT: TPKT version = 3
-        (byte) 0x03,  (byte) 0x00,  
-        // TPKT: Packet length: 378 bytes
-        (byte) 0x01,  (byte) 0x78, 
-        
-        // X.224: Length indicator = 2
-        (byte) 0x02,  
-        // X.224: Type: Data TPDU
-        (byte) 0xf0,  
-        // X.224: EOT
-        (byte) 0x80,  
-        
-        // Captured packet
-        (byte)0x7f, (byte)0x65, (byte)0x82, (byte)0x01, (byte)0x6c, (byte)0x04, (byte)0x01, (byte)0x01, (byte)0x04,
-        (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0xff, (byte)0x30, (byte)0x1a, (byte)0x02, (byte)0x01, (byte)0x22, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x02, (byte)0x01, (byte)0x00,
-        (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01,
-        (byte)0x02, (byte)0x30, (byte)0x19, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02,
-        (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x02, (byte)0x04, (byte)0x20, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x30, (byte)0x1f, (byte)0x02, (byte)0x03,
-        (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x02, (byte)0xfc, (byte)0x17, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02,
-        (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x82, (byte)0x01,
-        (byte)0x07, (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x14, (byte)0x7c, (byte)0x00, (byte)0x01, (byte)0x80, (byte)0xfe, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x01,
-        (byte)0xc0, (byte)0x00, (byte)0x44, (byte)0x75, (byte)0x63, (byte)0x61, (byte)0x80, (byte)0xf0, (byte)0x01, (byte)0xc0, (byte)0xd8, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x08, (byte)0x00,
-        (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x03, (byte)0x01, (byte)0xca, (byte)0x03, (byte)0xaa, (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x28, (byte)0x0a, (byte)0x00, (byte)0x00,
-        (byte)0x61, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x33, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0xca, (byte)0x01, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x04, (byte)0xc0, (byte)0x0c, (byte)0x00, (byte)0x0d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0xc0, (byte)0x0c, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-    };
-    /* @formatter:on */
-
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-    Element todo = new ClientMCSConnectInitial("ClientMCSConnectInitial");
-    Element x224 = new ClientX224DataPdu("x224");
-    Element tpkt = new ClientTpkt("tpkt");
-
-    Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-
-    Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, todo, x224, tpkt, sink, mainSink);
-    pipeline.link("source", "ClientMCSConnectInitial", "mainSink");
-    pipeline.link("ClientMCSConnectInitial >" + OTOUT, "x224", "tpkt", "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSErectDomainRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSErectDomainRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSErectDomainRequest.java
deleted file mode 100644
index 4a0fd04..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSErectDomainRequest.java
+++ /dev/null
@@ -1,190 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240683.aspx
- */
-public class ClientMCSErectDomainRequest extends OneTimeSwitch {
-
-  public ClientMCSErectDomainRequest(String id) {
-    super(id);
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    throw new RuntimeException("Unexpected packet: " + buf + ".");
-  }
-
-  @Override
-  protected void onStart() {
-    super.onStart();
-
-    int length = 5;
-    ByteBuffer buf = new ByteBuffer(length, true);
-
-    buf.writeByte(0x04); // Erect Domain Request
-    
-    // Client SHOULD initialize both the subHeight and subinterval fields of the MCS Erect Domain Request PDU to zero.
-    
-    buf.writeByte(1); // ErectDomainRequest::subHeight length = 1 byte
-    buf.writeByte(0); // ErectDomainRequest::subHeight
-    
-    buf.writeByte(1); // ErectDomainRequest::subInterval length = 1 byte
-    buf.writeByte(0); // ErectDomainRequest::subInterval
-    
-    
-    pushDataToOTOut(buf);
-
-    switchOff();
-  }
-
-  /**
-   * Example.
-   * @see http://msdn.microsoft.com/en-us/library/cc240837.aspx
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    /* @formatter:off */
-    byte[] packet = new byte[] {
-
-        0x03, 0x00, 0x00, 0x0c,  //  TPKT Header (length = 12 bytes)
-        0x02, (byte) 0xf0, (byte) 0x80,  //  X.224 Data TPDU
-        
-        // PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
-        0x04, 0x01, 0x00, 0x01, 0x00,
-         
-        // 0x04:
-        // 0 - --\
-        // 0 -   |
-        // 0 -   | CHOICE: From DomainMCSPDU select erectDomainRequest (1) 
-        // 0 -   | of type ErectDomainRequest
-        // 0 -   |
-        // 1 - --/
-        // 0 - padding
-        // 0 - padding
-        
-        // 0x01:
-        // 0 - --\
-        // 0 -   |
-        // 0 -   |
-        // 0 -   | ErectDomainRequest::subHeight length = 1 byte
-        // 0 -   |
-        // 0 -   |
-        // 0 -   |
-        // 1 - --/
-        
-        // 0x00:
-        // 0 - --\
-        // 0 -   |
-        // 0 -   |
-        // 0 -   | ErectDomainRequest::subHeight = 0
-        // 0 -   |
-        // 0 -   |
-        // 0 -   |
-        // 0 - --/
-        
-        // 0x01:
-        // 0 - --\
-        // 0 -   |
-        // 0 -   |
-        // 0 -   | ErectDomainRequest::subInterval length = 1 byte
-        // 0 -   |
-        // 0 -   |
-        // 0 -   |
-        // 1 - --/
-        
-        // 0x00:
-        // 0 - --\
-        // 0 -   |
-        // 0 -   |
-        // 0 -   | ErectDomainRequest::subInterval = 0
-        // 0 -   |
-        // 0 -   |
-        // 0 -   |
-        // 0 - --/
-
-        
-    };
-    /* @formatter:on */
-
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-    Element todo = new ClientMCSErectDomainRequest("TODO");
-    Element x224 = new ClientX224DataPdu("x224");
-    Element tpkt = new ClientTpkt("tpkt");
-    Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-    Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, todo, x224, tpkt, sink, mainSink);
-    pipeline.link("source", "TODO", "mainSink");
-    pipeline.link("TODO >" + OTOUT, "x224", "tpkt", "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-
-}
-
-/*
- * 03 00 00 0C 02 F0 80 04 01 00 01 00
-
-  Frame: Number = 14, Captured Frame Length = 69, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 12
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 12 (0xC)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: Erect Domain Request, SubHeight = 0, SubInterval = 0
-  - MCSHeader: Type=Erect Domain Request
-   - Type: Erect Domain Request
-    - RootIndex: 1
-       Value: (000001..) 0x1
-  - MCSErectDomainRequest: SubHeight = 0, SubInterval = 0
-   - SubHeight: 0x0
-    - Length: 1
-     - Align: No Padding
-        Padding2: (00......) 0x0
-       Length: 1
-      Value: 0 (0x0)
-   - SubInterval: 0x0
-    - Length: 1
-       Align: No Padding
-       Length: 1
-      Value: 0 (0x0)
-
- */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientPacketSniffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientPacketSniffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientPacketSniffer.java
deleted file mode 100644
index 651d002..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientPacketSniffer.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-
-/**
- * Try to determine packet content by it header fingerprint.
- */
-public class ClientPacketSniffer extends PacketSniffer {
-
-  private static final Pair[] clientRegexps = new Pair[] {
-// @formatter:off
-    new Pair("Client FastPath input",           "04"),
-    new Pair("Client X224ConnectionRequest",    "03 00 XX XX 27 E0"),
-    new Pair("Client ConnectionRequest",        "03 00 XX XX XX E0"),
-    new Pair("Client MCConnectInitial",         "03 00 XX XX 02 F0 80 7F 65"),
-    new Pair("Client ErectDomainRequest",       "03 00 XX XX 02 F0 80 04"),
-    new Pair("Client AttachUserRequest",        "03 00 XX XX 02 F0 80 28"),
-    new Pair("Client ChannelJoinRequest",       "03 00 XX XX 02 F0 80 38"),
-    new Pair("Client Info",                     "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 00 00"),
-    new Pair("Client ConfirmActivePDU",         "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 13 00"),
-    new Pair("Client SynchronizePDU",           "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX 00 XX XX XX XX 1F"),
-    new Pair("Client ControlPDU",               "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX 00 XX XX XX XX 14"),
-    new Pair("Client FontListPDU",              "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX 00 XX XX XX XX 27"),
-    new Pair("Client BitmapCachePersistentList","03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX XX XX XX XX XX 2b"), 
-//    new Pair("Client TPKT Unknown packet",      "03"),
-//    new Pair("Client UNKNOWN PACKET (ERROR)",   ".*"),
-    // @formatter:on
-
-  };
-
-  public ClientPacketSniffer(String id) {
-    super(id, clientRegexps);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientSynchronizePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientSynchronizePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientSynchronizePDU.java
deleted file mode 100644
index 9631976..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientSynchronizePDU.java
+++ /dev/null
@@ -1,248 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240489.aspx
- */
-public class ClientSynchronizePDU extends OneTimeSwitch {
-
-  public ClientSynchronizePDU(String id) {
-    super(id);
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    throw new RuntimeException("Unexpected packet: " + buf + ".");
-  }
-
-  @Override
-  protected void onStart() {
-    super.onStart();
-
-    int length = 1024; // Large enough
-    ByteBuffer buf = new ByteBuffer(length, true);
-
-    /* @formatter:off */
-    buf.writeBytes(new byte[] {
-        // MCS send data request
-        (byte)0x64,
-        // Initiator: 1004 (1001+3)
-        (byte)0x00, (byte)0x03,
-        // Channel ID: 1003 (I/O Channel)
-        (byte)0x03, (byte)0xeb,
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        (byte)0x70, 
-        // Data length:  22 bytes (0x16, variable length field)
-        (byte)0x80,  (byte)0x16, 
-        
-        // RDP: total length: 22 bytes (LE)
-        (byte)0x16, (byte)0x00, 
-        
-        // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE)
-        (byte)0x17, (byte)0x00,
-        
-        // PDU source: 1007 (LE)
-        (byte)0xec, (byte)0x03,
-        // Share ID: 0x000103ea (LE)
-        (byte)0xea, (byte)0x03, (byte)0x01,  (byte)0x00,
-        // Padding: 1 byte
-        (byte)0x00,
-        // Stream ID: STREAM_LOW (1)
-        (byte)0x01, 
-        // uncompressedLength : 8 bytes (LE)
-        (byte)0x08, (byte)0x00,
-        // pduType2 = PDUTYPE2_SYNCHRONIZE (31)
-        (byte)0x1f, 
-        // generalCompressedType: 0
-        (byte)0x00,
-        // generalCompressedLength: 0 (LE?)
-        (byte)0x00, (byte)0x00,
-        //  messageType: SYNCMSGTYPE_SYNC (1) (LE)
-        (byte)0x01, (byte)0x00, 
-        // targetUser: 0x03ea
-        (byte)0xea, (byte)0x03,
-    });
-    /* @formatter:on */
-
-    // Trim buffer to actual length of data written
-    buf.trimAtCursor();
-
-    pushDataToOTOut(buf);
-
-    switchOff();
-  }
-
-  /**
-   * Example.
-   * 
-   * @see http://msdn.microsoft.com/en-us/library/cc240841.aspx
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    /* @formatter:off */
-    byte[] packet = new byte[] {
-        // TPKT
-        (byte)0x03, (byte)0x00,
-        // TPKT length: 37 bytes
-        (byte)0x00, (byte)0x25,
-        // X224 Data PDU 
-        (byte)0x02, (byte)0xf0, (byte)0x80,
-        
-        // MCS send data request
-        (byte)0x64,
-        // Initiator: 1004 (1001+3)
-        (byte)0x00, (byte)0x03,
-        // Channel ID: 1003 (I/O Channel)
-        (byte)0x03, (byte)0xeb,
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        (byte)0x70, 
-        // Data length:  22 bytes (0x16, variable length field)
-        (byte)0x80,  (byte)0x16, 
-        
-        // RDP: total length: 22 bytes (LE)
-        (byte)0x16, (byte)0x00, 
-        // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE)
-        (byte)0x17, (byte)0x00,
-        // PDU source: 1007 (LE)
-        (byte)0xec, (byte)0x03,
-        // Share ID: 0x000103ea (LE)
-        (byte)0xea, (byte)0x03, (byte)0x01,  (byte)0x00,
-        // Padding: 1 byte
-        (byte)0x00,
-        // Stream ID: STREAM_LOW (1)
-        (byte)0x01, 
-        // uncompressedLength : 8 bytes (LE)
-        (byte)0x08, (byte)0x00,
-        // pduType2 = PDUTYPE2_SYNCHRONIZE (31)
-        (byte)0x1f, 
-        // generalCompressedType: 0
-        (byte)0x00,
-        // generalCompressedLength: 0 (LE?)
-        (byte)0x00, (byte)0x00,
-        //  messageType: SYNCMSGTYPE_SYNC (1) (LE)
-        (byte)0x01, (byte)0x00, 
-        // targetUser: 0x03ea
-        (byte)0xea, (byte)0x03,
-        
-    };
-    /* @formatter:on */
-
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-    Element todo = new ClientSynchronizePDU("TODO");
-    Element x224 = new ClientX224DataPdu("x224");
-    Element tpkt = new ClientTpkt("tpkt");
-    Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-    Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, todo, x224, tpkt, sink, mainSink);
-    pipeline.link("source", "TODO", "mainSink");
-    pipeline.link("TODO >" + OTOUT, "x224", "tpkt", "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-
-}
-
-/*
- * @formatting:off
-
- * 03 00 00 25 02 F0 80 64 00 03 03 EB 70 80 16 16 00 17 00 EC 03 EA 03 01 00 00 01 08 00 1F 00 00 00 01 00 EA 03 
-
-  Frame: Number = 40, Captured Frame Length = 94, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 37
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 37 (0x25)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: Data Packet
-  - MCSHeader: Type=Send Data Request, UserID=1004, ChannelID=1003
-   - Type: Send Data Request
-    - RootIndex: 25
-       Value: (011001..) 0x19
-   - UserID: 0x3ec
-    - UserID: 0x3ec
-     - ChannelId: 1004
-      - Align: No Padding
-         Padding2: (00......) 0x0
-        Value: 3 (0x3)
-   - Channel: 0x3eb
-    - ChannelId: 1003
-       Align: No Padding
-       Value: 1003 (0x3EB)
-   - DataPriority: high
-    - DataPriority: high
-     - RootIndex: 1
-        Value: (01......) 0x1
-   - Segmentation: Begin End
-      Begin: (1.......) Begin
-      End:   (.1......) End
-   - Length: 22
-    - Align: No Padding
-       Padding4: (0000....) 0x0
-      Length: 22
-    RDP: RDPBCGR
-- RDPBCGR: SynchronizePDU
-  - SlowPathPacket: SynchronizePDU 
-   - SlowPath: Type = TS_PDUTYPE_DATAPDU
-    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
-       TotalLength: 22 (0x16)
-     - PDUType: 23 (0x17)
-        Type:            (............0111) TS_PDUTYPE_DATAPDU
-        ProtocolVersion: (000000000001....) 1
-       PDUSource: 1004 (0x3EC)
-    - SlowPathIoPacket: 0x0
-     - ShareDataHeader: TS_PDUTYPE2_SYNCHRONIZE
-        ShareID: 66538 (0x103EA)
-        Pad1: 0 (0x0)
-        StreamID: TS_STREAM_LOW
-        UncompressedLength: 8 (0x8)
-        PDUType2: TS_PDUTYPE2_SYNCHRONIZE
-      - CompressedType: Not Compressed
-         MPPC:       (....0000) MPPC 8K
-         Reserved:   (...0....)
-         Compressed: (..0.....) Not Compressed
-         Front:      (.0......) Not At Front
-         Flush:      (0.......) Not Flushed
-        CompressedLength: 0 (0x0)
-     - TsSynchronizePDU: 0x1
-        MessageType: 0x1, MUST be set to SYNCMSGTYPE_SYNC (1)
-        TargetUser: 1002 (0x3EA)
- */
-

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientTpkt.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientTpkt.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientTpkt.java
deleted file mode 100644
index c92d832..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientTpkt.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-public class ClientTpkt extends BaseElement {
-
-  public ClientTpkt(String id) {
-    super(id);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    if (buf.length + 4 > 65535)
-      throw new RuntimeException("Packet is too long for TPKT (max length 65535-4): " + buf + ".");
-
-    ByteBuffer data = new ByteBuffer(4);
-    // TPKT version
-    data.writeByte(3);
-    // Reserved
-    data.writeByte(0);
-    // Packet length, including length of the header
-    data.writeShort(buf.length + 4);
-
-    buf.prepend(data);
-    data.unref();
-
-    pushDataToPad(STDOUT, buf);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224ConnectionRequestPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224ConnectionRequestPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224ConnectionRequestPDU.java
deleted file mode 100644
index 48ac089..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224ConnectionRequestPDU.java
+++ /dev/null
@@ -1,156 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240470.aspx
- * @see http://msdn.microsoft.com/en-us/library/cc240663.aspx
- */
-public class ClientX224ConnectionRequestPDU extends OneTimeSwitch {
-
-  public static final int X224_TPDU_CONNECTION_REQUEST = 0xe0;
-  public static final int X224_TPDU_CONNECTION_CONFIRM = 0xd0;
-  public static final int X224_TPDU_DISCONNECTION_REQUEST = 0x80;
-  public static final int X224_TPDU_DISCONNECTION_CONFIRM = 0xc0;
-  public static final int X224_TPDU_EXPEDITED_DATA = 0x10;
-  public static final int X224_TPDU_DATA_ACKNOWLEDGE = 0x61;
-  public static final int X224_TPDU_EXPEDITET_ACKNOWLEDGE = 0x40;
-  public static final int X224_TPDU_REJECT = 0x51;
-  public static final int X224_TPDU_ERROR = 0x70;
-  public static final int X224_TPDU_PROTOCOL_IDENTIFIER = 0x01;
-
-  /**
-   * Reconnection cookie.
-   */
-  protected String userName;
-
-  public ClientX224ConnectionRequestPDU(String id, String userName) {
-    super(id);
-    this.userName = userName;
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    throw new RuntimeException("Unexpected packet: " + buf + ".");
-  }
-
-  @Override
-  protected void onStart() {
-    super.onStart();
-
-    // Length of packet without length field
-    int length = 33 + userName.length();
-    ByteBuffer buf = new ByteBuffer(length, true);
-
-    // Type (high nibble) = 0xe = CR TPDU; credit (low nibble) = 0
-    buf.writeByte(X224_TPDU_CONNECTION_REQUEST);
-
-    buf.writeShort(0); // Destination reference = 0
-    buf.writeShort(0); // Source reference = 0
-    buf.writeByte(0); // Class and options = 0
-    buf.writeString("Cookie: mstshash=" + userName + "\r\n", RdpConstants.CHARSET_8); // Cookie
-
-    // RDP_NEG_REQ::type
-    buf.writeByte(RdpConstants.RDP_NEG_REQ_TYPE_NEG_REQ);
-    // RDP_NEG_REQ::flags (0)
-    buf.writeByte(RdpConstants.RDP_NEG_REQ_FLAGS);
-    // RDP_NEG_REQ::length (constant: 8) short int in LE format
-    buf.writeByte(0x08);
-    buf.writeByte(0x00);
-
-    // RDP_NEG_REQ: Requested protocols: PROTOCOL_SSL
-    buf.writeIntLE(RdpConstants.RDP_NEG_REQ_PROTOCOL_SSL);
-
-    // Calculate length of packet and prepend it to buffer
-    ByteBuffer data = new ByteBuffer(5);
-
-    // Write length
-    data.writeVariableIntLE(buf.length);
-
-    // Reset length of buffer to actual length of data written
-    data.length = data.cursor;
-
-    buf.prepend(data);
-    data.unref();
-
-    pushDataToOTOut(buf);
-
-    switchOff();
-  }
-
-  /**
-   * Example.
-   * 
-   * @see http://msdn.microsoft.com/en-us/library/cc240842.aspx
-   * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    String cookie = "eltons";
-
-    byte[] packet = new byte[] {
-
-    0x03, // TPKT Header: version = 3
-        0x00, // TPKT Header: Reserved = 0
-        0x00, // TPKT Header: Packet length - high part
-        0x2c, // TPKT Header: Packet length - low part (total = 44 bytes)
-        0x27, // X.224: Length indicator (39 bytes)
-        (byte) 0xe0, // X.224: Type (high nibble) = 0xe = CR TPDU;
-                     // credit (low nibble) = 0
-        0x00, 0x00, // X.224: Destination reference = 0
-        0x00, 0x00, // X.224: Source reference = 0
-        0x00, // X.224: Class and options = 0
-
-        'C', 'o', 'o', 'k', 'i', 'e', ':', ' ', 'm', 's', 't', 's', 'h', 'a', 's', 'h', '=', 'e', 'l', 't', 'o', 'n', 's', // "Cookie: mstshash=eltons"
-        '\r', '\n', // -Cookie terminator sequence
-
-        0x01, // RDP_NEG_REQ::type (TYPE_RDP_NEG_REQ)
-        0x00, // RDP_NEG_REQ::flags (0)
-        0x08, 0x00, // RDP_NEG_REQ::length (8 bytes)
-        0x01, 0x00, 0x00, 0x00 // RDP_NEG_REQ: Requested protocols
-                               // (PROTOCOL_SSL in little endian format)
-    };
-
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-    Element cr = new ClientX224ConnectionRequestPDU("cr", cookie);
-    Element tpkt = new ClientTpkt("tpkt");
-    Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-    Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, cr, tpkt, sink, mainSink);
-    pipeline.link("source", "cr", "mainSink");
-    pipeline.link("cr >" + OTOUT, "tpkt", "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224DataPdu.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224DataPdu.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224DataPdu.java
deleted file mode 100644
index 2cf9b72..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224DataPdu.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-public class ClientX224DataPdu extends BaseElement {
-
-  public static final int X224_TPDU_DATA = 0xF0;
-  public static final int X224_TPDU_LAST_DATA_UNIT = 0x80;
-
-  public ClientX224DataPdu(String id) {
-    super(id);
-  }
-  
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    ByteBuffer data = new ByteBuffer(3);
-    // X224 header
-    data.writeByte(2); // Header length indicator
-    data.writeByte(X224_TPDU_DATA);
-    data.writeByte(X224_TPDU_LAST_DATA_UNIT);
-
-    buf.prepend(data);
-    data.unref();
-
-    pushDataToPad(STDOUT, buf);
-  }
-
-
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/HandshakeEnd.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/HandshakeEnd.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/HandshakeEnd.java
deleted file mode 100644
index 62242de..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/HandshakeEnd.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.BaseElement;
-
-public class HandshakeEnd extends BaseElement {
-
-  public HandshakeEnd(String id) {
-    super(id);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/MockServer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/MockServer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/MockServer.java
deleted file mode 100644
index b141917..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/MockServer.java
+++ /dev/null
@@ -1,197 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.Arrays;
-
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-
-public class MockServer implements Runnable {
-
-    private boolean shutdown = false;
-    private ServerSocket serverSocket;
-    private Packet[] packets;
-    private Throwable exception;
-    private boolean shutdowned;
-
-    /**
-     * Set to true to enable debugging messages.
-     */
-    protected boolean verbose = System.getProperty("rdpclient.MockServer.debug", "false").equals("true");
-
-    public MockServer(Packet packets[]) {
-	this.packets = packets;
-    }
-
-    public void start() throws IOException {
-	serverSocket = new ServerSocket(0);
-
-	shutdown = false;
-	exception = null;
-	shutdowned = false;
-
-	new Thread(this).start();
-    }
-
-    public void run() {
-
-	try {
-	    Socket socket = serverSocket.accept();
-
-	    InputStream is = socket.getInputStream();
-	    OutputStream os = socket.getOutputStream();
-
-	    try {
-		for (int i = 0; i < packets.length && !shutdown; i++) {
-
-		    Packet packet = packets[i];
-		    switch (packet.type) {
-		    case CLIENT: {
-			// Read client data and compare it with mock data
-			// (unless "ignore" option is set)
-			byte actualData[] = new byte[packet.data.length];
-			int actualDataLength = is.read(actualData);
-
-			if (verbose)
-			    System.out.println("[" + this + "] INFO: Data is read: {" + Arrays.toString(Arrays.copyOf(actualData, actualDataLength)) + "}.");
-
-			if (!packet.ignore) {
-			    // Compare actual data with expected data
-			    if (actualDataLength != packet.data.length) {
-				throw new AssertionError("Actual length of client request for packet #" + (i + 1) + " (\"" + packet.id + "\")"
-					+ " does not match length of expected client request. Actual length: " + actualDataLength + ", expected legnth: "
-					+ packet.data.length + ".");
-			    }
-
-			    for (int j = 0; j < packet.data.length; j++) {
-
-				if (packet.data[j] != actualData[j]) {
-				    throw new AssertionError("Actual byte #" + (j + 1) + " of client request for packet #" + (i + 1) + " (\"" + packet.id
-					    + "\")" + " does not match corresponding byte of expected client request. Actual byte: " + actualData[j]
-					    + ", expected byte: " + packet.data[j] + ".");
-				}
-			    }
-			}
-			break;
-		    }
-		    case SERVER: {
-			// Send mock data to client
-			os.write(packet.data);
-
-			if (verbose)
-			    System.out.println("[" + this + "] INFO: Data is written: {" + Arrays.toString(packet.data) + "}.");
-
-			break;
-		    }
-		    case UPGRADE_TO_SSL: {
-			// Attach SSL context to socket
-
-			final SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
-			SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, null, serverSocket.getLocalPort(), true);
-			sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
-			sslSocket.setUseClientMode(false);
-			sslSocket.startHandshake();
-			is = sslSocket.getInputStream();
-			os = sslSocket.getOutputStream();
-
-			break;
-		    }
-		    default:
-			throw new RuntimeException("Unknown packet type: " + packet.type);
-		    }
-
-		}
-	    } finally {
-		try {
-		    is.close();
-		} catch (Throwable e) {
-		}
-		try {
-		    os.close();
-		} catch (Throwable e) {
-		}
-		try {
-		    socket.close();
-		} catch (Throwable e) {
-		}
-		try {
-		    serverSocket.close();
-		} catch (Throwable e) {
-		}
-	    }
-	} catch (Throwable e) {
-	    System.err.println("Error in mock server: " + e.getMessage());
-	    e.printStackTrace(System.err);
-	    exception = e;
-	}
-	shutdowned = true;
-	if (verbose)
-	    System.out.println("[" + this + "] INFO: Mock server shutdowned.");
-
-    }
-
-    public void shutdown() {
-	shutdown = true;
-    }
-
-    public InetSocketAddress getAddress() {
-	return (InetSocketAddress) serverSocket.getLocalSocketAddress();
-    }
-
-    public Throwable getException() {
-	return exception;
-    }
-
-    public static class Packet {
-	public static enum PacketType {
-	    SERVER, CLIENT, UPGRADE_TO_SSL;
-	}
-
-	public String id = "";
-
-	public Packet() {
-	}
-
-	public Packet(String id) {
-	    this.id = id;
-	}
-
-	public PacketType type;
-
-	public boolean ignore = false;
-
-	public byte data[];
-    }
-
-    public boolean isShutdowned() {
-	return shutdowned;
-    }
-
-    public void waitUntilShutdowned(long timeToWaitMiliseconds) throws InterruptedException {
-	long deadline = System.currentTimeMillis() + timeToWaitMiliseconds;
-	while (!shutdowned && System.currentTimeMillis() < deadline) {
-	    Thread.sleep(10);
-	}
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/PacketSniffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/PacketSniffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/PacketSniffer.java
deleted file mode 100644
index 9fe2499..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/PacketSniffer.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import java.util.regex.Pattern;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-/**
- * Try to determine packet content by it header fingerprint.
- */
-public class PacketSniffer  extends BaseElement {
-
-  protected Pair regexps[]=null;
-
-  public PacketSniffer(String id, Pair[] regexps) {
-    super(id);
-    this.regexps=regexps;
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-
-    matchPacket(buf);
-
-    super.handleData(buf, link);
-  }
-
-  private void matchPacket(ByteBuffer buf) {
-    String header = buf.toPlainHexString(100);
-    for (Pair pair : regexps) {
-      if (pair.regexp.matcher(header).find()) {
-        System.out.println("[" + this + "] INFO: Packet: " + pair.name + ".");
-        return;
-      }
-    }
-
-    System.out.println("[" + this + "] INFO: Unknown packet: " + header + ".");
-  }
-
-  protected static class Pair {
-    String name;
-    Pattern regexp;
-
-    protected Pair(String name, String regexp) {
-      this.name = name;
-      this.regexp = Pattern.compile("^" + replaceShortcuts(regexp), Pattern.CASE_INSENSITIVE);
-    }
-
-    private static String replaceShortcuts(String regexp) {
-      String result = regexp; 
-      result = result.replaceAll("XX\\*", "([0-9a-fA-F]{2} )*?");
-      result = result.replaceAll("XX\\?", "([0-9a-fA-F]{2} )?");
-      result = result.replaceAll("XX", "[0-9a-fA-F]{2}");
-      return result;
-    }
-  }
-
-}


[06/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ByteBuffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ByteBuffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ByteBuffer.java
old mode 100644
new mode 100755
index 832c731..969f747
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ByteBuffer.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ByteBuffer.java
@@ -19,808 +19,1103 @@ package streamer;
 import java.nio.charset.Charset;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * This class represents a slice in a buffer.
  */
 public class ByteBuffer {
 
-  public static final String SEQUENCE_NUMBER = "seq";
-
-  public byte data[];
-  public int offset = 0;
-  public int length = 0;
-  public int cursor = 0;
-
-  private int refCount = 1;
-  private ByteBuffer parentByteBuffer = null;
-
-  private Order order;
-
-  /**
-   * Create buffer of size no less than length. Buffer can be a bit larger than
-   * length. Offset also can be set to non-zero value to leave some place for
-   * future headers.
-   */
-  public ByteBuffer(int minLength) {
-    // Get buffer of acceptable size from buffer pool
-    this.data = BufferPool.allocateNewBuffer(minLength);
-    this.offset = 0;
-    this.length = minLength;
-  }
-
-  public ByteBuffer(byte data[]) {
-    if (data == null)
-      throw new NullPointerException("Data must be non-null.");
-
-    this.data = data;
-    this.offset = 0;
-    this.length = data.length;
-  }
-
-  public ByteBuffer(byte[] data, int offset, int length) {
-    if (data == null)
-      throw new NullPointerException("Data must be non-null.");
-
-    this.data = data;
-    this.offset = offset;
-    this.length = length;
-  }
-
-  /**
-   * Create byte buffer of requested size with some space reserved for future
-   * headers.
-   */
-  public ByteBuffer(int minLength, boolean reserveSpaceForHeader) {
-    // Get buffer of acceptable size from buffer pool
-    this.data = BufferPool.allocateNewBuffer(128 + minLength);
-    this.offset = 128; // 100 bytes should be enough for headers
-    this.length = minLength;
-  }
-
-  /**
-   * Create empty buffer with given order only.
-   */
-  public ByteBuffer(Order order) {
-    this.order = order;
-  }
-
-  public void setOrder(Order order) {
-    this.order = order;
-  }
-
-  public Order getOrder() {
-    return order;
-  }
-
-  @Override
-  public String toString() {
-    return toString(100);
-  }
-
-  /**
-   * Return string representation of this byte buffer.
-   * 
-   * @param maxLength
-   *          number of bytes to show in string
-   */
-  public String toString(int maxLength) {
-    return "ByteRange(){offset=" + offset + ", length=" + length + ", cursor=" + cursor + ", data=" + ((data == null) ? "null" : toHexString(maxLength))
-        + ((metadata == null || metadata.size() == 0) ? "" : ", metadata=" + metadata) + "}";
-  }
-
-  /**
-   * Return string representation of this byte buffer as hexadecimal numbers,
-   * e.g. "[0x01, 0x02]".
-   * 
-   * @param maxLength
-   *          number of bytes to show in string
-   */
-  public String toHexString(int maxLength) {
-    StringBuilder builder = new StringBuilder(maxLength * 6);
-    builder.append('[');
-    for (int i = 0; i < maxLength && i < length; i++) {
-      if (i > 0)
-        builder.append(", ");
-      int b = data[offset + i] & 0xff;
-      builder.append("0x" + ((b < 16) ? "0" : "") + Integer.toString(b, 16));
-    }
-    builder.append(']');
-    return builder.toString();
-  }
-
-  /**
-   * Return string representation of this byte buffer as hexadecimal numbers,
-   * e.g. "01 02".
-   * 
-   * @param maxLength
-   *          number of bytes to show in string
-   */
-  public String toPlainHexString(int maxLength) {
-    StringBuilder builder = new StringBuilder(maxLength * 3);
-    for (int i = 0; i < maxLength && i < length; i++) {
-      if (i > 0)
-        builder.append(" ");
-      int b = data[offset + i] & 0xff;
-      builder.append(((b < 16) ? "0" : "") + Integer.toString(b, 16));
-    }
-    return builder.toString();
-  }
-
-  public void dump() {
-    System.out.println(toString(length));
-  }
-
-  public void extend(int newLength) {
-    if (data.length < newLength)
-      Arrays.copyOf(data, newLength);
-  }
-
-  public void ref() {
-    refCount++;
-  }
-
-  public void unref() {
-    refCount--;
-
-    if (refCount == 0) {
-
-      if (parentByteBuffer != null) {
-        parentByteBuffer.unref();
-        parentByteBuffer = null;
-      } else {
-        // Return buffer to buffer pool
-        BufferPool.recycleBuffer(data);
-      }
-
-      data = null;
-    }
-
-  }
-
-  public boolean isSoleOwner() {
-    return refCount == 1 && (parentByteBuffer == null);
-  }
-
-  /**
-   * Create shared lightweight copy of part of this buffer.
-   */
-  public ByteBuffer slice(int offset, int length, boolean copyMetadata) {
-    ref();
-
-    if (this.length < (offset + length))
-      throw new RuntimeException("Length of region is larger that length of this buffer. Buffer length: " + this.length + ", offset: " + offset
-          + ", new region length: " + length + ".");
-
-    ByteBuffer slice = new ByteBuffer(data, this.offset + offset, length);
-
-    if (copyMetadata && this.metadata != null)
-      slice.metadata = new HashMap<String, Object>(metadata);
-
-    return slice;
-  }
-
-  private Map<String, Object> metadata = null;
-
-  public Object putMetadata(String key, Object value) {
-    if (metadata == null)
-      metadata = new HashMap<String, Object>();
-    return metadata.put(key, value);
-  }
-
-  public Object getMetadata(String key) {
-    return (metadata != null) ? metadata.get(key) : null;
-  }
-
-  /**
-   * Create new buffer, which holds data from both buffers. Expensive operation.
-   * 
-   * @TODO if only one reference to this ByteBuffer exists, then extend this
-   *       buffer instead of creating new buffer
-   * @TODO support list of buffers to avoid expensive joins until absolute
-   *       necessary
-   */
-  public ByteBuffer join(ByteBuffer buf) {
-    // Extend byte array for new data
-    int newLength = length + buf.length;
-    byte newData[] = new byte[newLength];
-
-    // Copy data from our buffer
-    System.arraycopy(data, offset, newData, 0, length);
-
-    // Copy data from other buffer
-    System.arraycopy(buf.data, buf.offset, newData, length, buf.length);
-
-    ByteBuffer newBuf = new ByteBuffer(newData);
-
-    // Copy our (older) metadata to new buffer, because handler might store some
-    // metadata in buffer, which is pushed back.
-    if (metadata != null)
-      newBuf.metadata = new HashMap<String, Object>(metadata);
-
-    return newBuf;
-  }
-
-  /**
-   * Copy used portion of buffer to new byte array. Expensive operation.
-   */
-  public byte[] toByteArray() {
-    return Arrays.copyOfRange(data, offset, offset + length);
-  }
-
-  public short[] toShortArray() {
-    if (length % 2 != 0)
-      throw new ArrayIndexOutOfBoundsException("Length of byte array must be dividable by 2 without remainder. Array length: " + length + ", remainder: "
-          + (length % 2) + ".");
-
-    short[] buf = new short[length / 2];
-
-    for (int i = 0, j = offset; i < buf.length; i++, j += 2) {
-      buf[i] = (short) ((data[j + 0] & 0xFF) | ((data[j + 1] & 0xFF) << 8));
-    }
-    return buf;
-  }
-
-  /**
-   * Return array of int's in little endian order.
-   */
-  public int[] toIntLEArray() {
-    if (length % 4 != 0)
-      throw new ArrayIndexOutOfBoundsException("Length of byte array must be dividable by 4 without remainder. Array length: " + length + ", remainder: "
-          + (length % 4) + ".");
-
-    int[] buf = new int[length / 4];
-
-    for (int i = 0, j = offset; i < buf.length; i++, j += 4) {
-      buf[i] = (data[j + 0] & 0xFF) | ((data[j + 1] & 0xFF) << 8) | ((data[j + 2] & 0xFF) << 16) | ((data[j + 3] & 0xFF) << 24);
-    }
-    return buf;
-  }
-
-  /**
-   * Return array of int's in little endian order, but use only 3 bytes per int (3RGB).
-   */
-  public int[] toInt3LEArray() {
-    if (length % 3 != 0)
-      throw new ArrayIndexOutOfBoundsException("Length of byte array must be dividable by 3 without remainder. Array length: " + length + ", remainder: "
-          + (length % 3) + ".");
-
-    int[] buf = new int[length / 3];
-
-    for (int i = 0, j = offset; i < buf.length; i++, j += 3) {
-      buf[i] = (data[j + 0] & 0xFF) | ((data[j + 1] & 0xFF) << 8) | ((data[j + 2] & 0xFF) << 16);
-    }
-    return buf;
-  }
-
-  /**
-   * Helper method for test cases to convert array of byte arrays to array of
-   * byte buffers.
-   */
-  public static ByteBuffer[] convertByteArraysToByteBuffers(byte[]... bas) {
-    ByteBuffer bufs[] = new ByteBuffer[bas.length];
-
-    int i = 0;
-    for (byte[] ba : bas) {
-      bufs[i++] = new ByteBuffer(ba);
-    }
-    return bufs;
-  }
-
-  /**
-   * Read signed int in network order. Cursor is advanced by 4.
-   */
-  public int readSignedInt() {
-    if (cursor + 4 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot read 4 bytes from this buffer: " + this + ".");
-
-    int result = (((data[offset + cursor] & 0xff) << 24) + ((data[offset + cursor + 1] & 0xff) << 16) + ((data[offset + cursor + 2] & 0xff) << 8) + (data[offset
-        + cursor + 3] & 0xff));
-    cursor += 4;
-    return result;
-  }
-
-  /**
-   * Read signed int in little endian order. Cursor is advanced by 4.
-   */
-  public int readSignedIntLE() {
-    if (cursor + 4 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot read 4 bytes from this buffer: " + this + ".");
-
-    int result = (((data[offset + cursor + 3] & 0xff) << 24) + ((data[offset + cursor + 2] & 0xff) << 16) + ((data[offset + cursor + 1] & 0xff) << 8) + (data[offset
-        + cursor] & 0xff));
-    cursor += 4;
-    return result;
-  }
-
-  /**
-   * Read unsigned int in little endian order. Cursor is advanced by 4.
-   */
-  public long readUnsignedIntLE() {
-    if (cursor + 4 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot read 4 bytes from this buffer: " + this + ".");
-
-    long result = (((long) (data[offset + cursor + 3] & 0xff) << 24) + ((long) (data[offset + cursor + 2] & 0xff) << 16)
-        + ((long) (data[offset + cursor + 1] & 0xff) << 8) + (long) (data[offset + cursor] & 0xff));
-    cursor += 4;
-    return result;
-  }
-
-  /**
-   * Read signed int in variable length format. Top most bit of each byte
-   * indicates that next byte contains additional bits. Cursor is advanced by
-   * 1-5 bytes.
-   */
-  public int readVariableSignedIntLE() {
-    int result = 0;
-
-    for (int shift = 0; shift < 32; shift += 7) {
-      int b = readUnsignedByte();
-      result |= (b & 0x7f) << shift;
-      if ((b & 0x80) == 0)
-        break;
-    }
-
-    return result;
-  }
-
-  /**
-   * Read unsigned int in network order in variable length format. Cursor is
-   * advanced by 1 to 4 bytes.
-   * 
-   * Two most significant bits of first byte indicates length of field: 0x00 - 1
-   * byte, 0x40 - 2 bytes, 0x80 - 3 bytes, 0xc0 - 4 bytes.
-   * 
-   * @see http://msdn.microsoft.com/en-us/library/cc241614.aspx
-   */
-  public int readEncodedUnsignedInt() {
-    int firstByte = readUnsignedByte();
-    int result;
-    switch (firstByte & 0xc0) {
-    default:
-    case 0x00:
-      result = firstByte & 0x3f;
-      break;
-    case 0x40:
-      result = (firstByte & 0x3f << 8) | readUnsignedByte();
-      break;
-    case 0x80:
-      result = (((firstByte & 0x3f << 8) | readUnsignedByte()) << 8) | readUnsignedByte();
-      break;
-    case 0xc0:
-      result = ((((firstByte & 0x3f << 8) | readUnsignedByte()) << 8) | readUnsignedByte() << 8) | readUnsignedByte();
-      break;
-    }
-
-    return result;
-  }
-
-  /**
-   * Read unsigned byte. Cursor is advanced by 1.
-   */
-  public int readUnsignedByte() {
-    if (cursor + 1 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot read 1 byte from this buffer: " + this + ".");
-
-    int b = data[offset + cursor] & 0xff;
-    cursor += 1;
-    return b;
-  }
-
-  /**
-   * Read signed byte. Cursor is advanced by 1.
-   */
-  public byte readSignedByte() {
-    if (cursor + 1 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot read 1 byte from this buffer: " + this + ".");
-
-    byte b = data[offset + cursor];
-    cursor += 1;
-    return b;
-  }
-
-  /**
-   * Read unsigned short in network order. Cursor is advanced by 2.
-   */
-  public int readUnsignedShort() {
-    if (cursor + 2 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot read 2 bytes from this buffer: " + this + ".");
-
-    int result = (((data[offset + cursor] & 0xff) << 8) | (data[offset + cursor + 1] & 0xff));
-    cursor += 2;
-    return result;
-  }
-
-  /**
-   * Read signed short in little endian order. Cursor is advanced by 2.
-   */
-  public short readSignedShortLE() {
-    if (cursor + 2 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot read 2 bytes from this buffer: " + this + ".");
-
-    short result = (short) (((data[offset + cursor + 1] & 0xff) << 8) | (data[offset + cursor] & 0xff));
-    cursor += 2;
-    return result;
-  }
-
-  /**
-   * Read unsigned short in network order in variable length format. Cursor is
-   * advanced by 1 or 2 bytes.
-   * 
-   * Most significant bit of first byte indicates length of field: 0 - 1 byte, 1
-   * - 2 bytes.
-   */
-  public int readVariableUnsignedShort() {
-    int firstByte = readUnsignedByte();
-
-    int result;
-    if ((firstByte & 0x80) == 0)
-      result = firstByte & 0x7f;
-    else {
-      int secondByte = readUnsignedByte();
-      result = (((firstByte & 0x7f) << 8) | secondByte);
-    }
-
-    return result;
-  }
-
-  /**
-   * Read unsigned short in little endian order. Cursor is advanced by 2.
-   */
-  public int readUnsignedShortLE() {
-    if (cursor + 2 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot read 2 bytes from this buffer: " + this + ".");
-
-    int result = (((data[offset + cursor + 1] & 0xff) << 8) | (data[offset + cursor] & 0xff));
-    cursor += 2;
-    return result;
-  }
-
-  /**
-   * Read unsigned short in network order in variable length format. Cursor is
-   * advanced by 1 or 2 bytes.
-   * 
-   * Most significant bit of first byte indicates length of field: 0x00 - 1
-   * byte, 0x80 - 2 bytes.
-   * 
-   * @see http://msdn.microsoft.com/en-us/library/cc241612.aspx
-   */
-  public int readEncodedUnsignedShort() {
-    int firstByte = readUnsignedByte();
-
-    int result;
-    if ((firstByte & 0x80) == 0)
-      result = firstByte & 0x7f;
-    else {
-      int secondByte = readUnsignedByte();
-      result = (((firstByte & 0x7f) << 8) | secondByte);
-    }
-
-    return result;
-  }
-
-  /**
-   * Read signed short in network order in variable length format. Cursor is
-   * advanced by 1 or 2 bytes.
-   * 
-   * Most significant bit of first byte indicates length of field: 0x00 - 1
-   * byte, 0x80 - 2 bytes. Second most significant bit indicates is value
-   * positive or negative.
-   * 
-   * @see http://msdn.microsoft.com/en-us/library/cc241613.aspx
-   */
-  public int readEncodedSignedShort() {
-    int firstByte = readUnsignedByte();
-
-    int result;
-    if ((firstByte & 0x80) == 0)
-      result = firstByte & 0x3f;
-    else {
-      int secondByte = readUnsignedByte();
-      result = (((firstByte & 0x3f) << 8) | secondByte);
-    }
-
-    if ((firstByte & 0x40) > 0)
-      return -result;
-    else
-      return result;
-  }
-
-  /**
-   * Read signed long in little endian order. Cursor is advanced by 8 bytes.
-   */
-  public long readSignedLongLE() {
-    return (((long) readSignedIntLE()) & 0xffFFffFFL) | (((long) readSignedIntLE()) << 32);
-  }
-
-  /**
-   * Read string from buffer. Cursor is advanced by string length.
-   */
-  public String readString(int length, Charset charset) {
-    if (cursor + length > this.length)
-      throw new ArrayIndexOutOfBoundsException("Cannot read " + length + " bytes from this buffer: " + this + ".");
-
-    String string = new String(data, offset + cursor, length, charset);
-    cursor += length;
-    return string;
-  }
-
-  /**
-   * Get bytes as lightweight slice. Cursor is advanced by data length.
-   */
-  public ByteBuffer readBytes(int dataLength) {
-    if (cursor + dataLength > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot read " + dataLength + " bytes from this buffer: " + this + ".");
-
-    ByteBuffer slice = slice(cursor, dataLength, false);
-    cursor += dataLength;
-    return slice;
-  }
-
-  /**
-   * Cursor is advanced by given number of bytes.
-   */
-  public void skipBytes(int numOfBytes) {
-    if (cursor + numOfBytes > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot read " + numOfBytes + " bytes from this buffer: " + this + ".");
-
-    cursor += numOfBytes;
-  }
-
-  /**
-   * Write byte. Cursor is advanced by 1.
-   */
-  public void writeByte(int b) {
-    if (cursor + 1 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot write 1 byte to this buffer: " + this + ".");
-
-    data[offset + cursor] = (byte) b;
-    cursor += 1;
-  }
-
-  /**
-   * Write short in network order. Cursor is advanced by 2.
-   */
-  public void writeShort(int x) {
-    if (cursor + 2 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot write 2 bytes to this buffer: " + this + ".");
-
-    data[offset + cursor] = (byte) (x >> 8);
-    data[offset + cursor + 1] = (byte) x;
-    cursor += 2;
-  }
-
-  /**
-   * Write short in little endian order. Cursor is advanced by 2.
-   */
-  public void writeShortLE(int x) {
-    if (cursor + 2 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot write 2 bytes to this buffer: " + this + ".");
-
-    data[offset + cursor + 1] = (byte) (x >> 8);
-    data[offset + cursor] = (byte) x;
-    cursor += 2;
-  }
-
-  /**
-   * Write int in network order. Cursor is advanced by 4.
-   */
-  public void writeInt(int i) {
-    if (cursor + 4 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot write 4 bytes to this buffer: " + this + ".");
-
-    data[offset + cursor] = (byte) (i >> 24);
-    data[offset + cursor + 1] = (byte) (i >> 16);
-    data[offset + cursor + 2] = (byte) (i >> 8);
-    data[offset + cursor + 3] = (byte) i;
-    cursor += 4;
-  }
-
-  public void writeIntLE(int i) {
-    if (cursor + 4 > length)
-      throw new ArrayIndexOutOfBoundsException("Cannot write 4 bytes to this buffer: " + this + ".");
-
-    data[offset + cursor] = (byte) i;
-    data[offset + cursor + 1] = (byte) (i >> 8);
-    data[offset + cursor + 2] = (byte) (i >> 16);
-    data[offset + cursor + 3] = (byte) (i >> 24);
-    cursor += 4;
-  }
-
-  /**
-   * Write int in variable length format. Cursor is advanced by number of bytes
-   * written (1-5).
-   * 
-   * Topmost bit of each byte is set to 1 to indicate that next byte has data.
-   */
-  public void writeVariableIntLE(int i) {
-    while (i != 0) {
-      // Get lower bits of number
-      int b = i & 0x7f;
-      i >>= 7;
-
-      if (i > 0)
-        // Set topmost bit of byte to indicate that next byte(s) contains
-        // remainder bits
-        b |= 0x80;
-
-      writeByte(b);
-    }
-  }
-
-  /**
-   * Write short in variable length format. Cursor is advanced by number of
-   * bytes written (1-2).
-   * 
-   * Topmost bit of first byte is set to 1 to indicate that next byte has data.
-   */
-  public void writeVariableShort(int length) {
-    if (length > 0x7f | length < 0)
-      writeShort(length | 0x8000);
-    else
-      writeByte(length);
-  }
-
-  /**
-   * Prepend given data to this byte buffer.
-   */
-  public void prepend(ByteBuffer buf) {
-    prepend(buf.data, buf.offset, buf.length);
-  }
-
-  /**
-   * Prepend given data to this byte buffer.
-   */
-  public void prepend(byte[] data) {
-    prepend(data, 0, data.length);
-  }
-
-  /**
-   * Prepend given data to this byte buffer.
-   */
-  public void prepend(byte[] data, int offset, int length) {
-    if (!isSoleOwner()) {
-      throw new RuntimeException("Create full copy of this byte buffer data for modification. refCount: " + refCount + ", parentByteBuffer: "
-          + parentByteBuffer + ".");
-    }
-
-    // If there is no enough space for header to prepend
-    if (!(this.offset >= length)) {
-      throw new RuntimeException("Reserve data to have enough space for header.");
-    }
-
-    // Copy header
-    System.arraycopy(data, offset, this.data, this.offset - length, length);
-
-    // Extend byte range to include header
-    this.offset -= length;
-    this.length += length;
-    this.cursor += length;
-  }
-
-  public void writeString(String str, Charset charset) {
-    writeBytes(str.getBytes(charset));
-  }
-
-  /**
-   * Write string of fixed size. When string is shorted, empty space is filled
-   * with zeros. When string is larger, it is truncated.
-   */
-  public void writeFixedString(int length, String str, Charset charset) {
-    byte[] bytes = str.getBytes(charset);
-    writeBytes(bytes, 0, Math.min(bytes.length, length));
-
-    for (int i = bytes.length; i < length; i++)
-      writeByte(0);
-  }
-
-  public void writeBytes(ByteBuffer buf) {
-    writeBytes(buf.data, buf.offset, buf.length);
-  }
-
-  public void writeBytes(byte[] bytes) {
-    writeBytes(bytes, 0, bytes.length);
-  }
-
-  public void writeBytes(byte[] bytes, int offset, int length) {
-    System.arraycopy(bytes, offset, this.data, this.offset + this.cursor, length);
-    cursor += length;
-  }
-
-  // /**
-  // * Write BER encoded definite long variant of the ASN.1 length field.
-  // */
-  // public void writeBerLength(int value) {
-  // int fieldLength;
-  // if (value > 0xFFffFF)
-  // fieldLength = 4;
-  // else if (value > 0xFFff)
-  // fieldLength = 3;
-  // else if (value > 0xFF)
-  // fieldLength = 2;
-  // else
-  // fieldLength = 1;
-  //
-  // if (cursor + fieldLength + 1 > length)
-  // throw new ArrayIndexOutOfBoundsException("Cannot write " + (fieldLength +
-  // 1) + " byte(s) to this buffer: " + this + ".");
-  //
-  // // Write length of length field itself
-  // writeByte(0x80 | fieldLength);
-  //
-  // switch (fieldLength) {
-  // case 4:
-  // data[offset + cursor++] = (byte) (value >> 24);
-  // case 3:
-  // data[offset + cursor++] = (byte) (value >> 16);
-  // case 2:
-  // data[offset + cursor++] = (byte) (value >> 8);
-  // case 1:
-  // data[offset + cursor++] = (byte) value;
-  // }
-  //
-  // }
-
-  /**
-   * Reduce length of buffer to cursor position.
-   */
-  public void trimAtCursor() {
-    length = cursor;
-  }
-
-  /**
-   * Rewind cursor to beginning of buffer.
-   */
-  public void rewindCursor() {
-    cursor = 0;
-  }
-
-  /**
-   * Read RGB color in LE order. Cursor is advanced by 3.
-   * 
-   * @return color as int, with red in lowest octet.
-   */
-  public int readRGBColor() {
-    return readUnsignedByte() | (readUnsignedByte() << 8) | (readUnsignedByte() << 16);
-  }
-
-  public void assertThatBufferIsFullyRead() {
-    if (cursor != length)
-      throw new RuntimeException("Data in buffer is not read fully. Buf: " + this + ".");
-  }
-
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-
-    int end = offset + length;
-    for (int i = offset; i < end; i++)
-      result = 31 * result + data[i];
-
-    result = prime * result + length;
-    return result;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (this == obj)
-      return true;
-    if (obj == null)
-      return false;
-    if (getClass() != obj.getClass())
-      return false;
-
-    ByteBuffer other = (ByteBuffer) obj;
-    if (length != other.length)
-      return false;
-
-    for (int i = 0; i < length; i++)
-      if (data[offset + i] != other.data[other.offset + i])
-        return false;
-
-    return true;
-  }
+    public static final String SEQUENCE_NUMBER = "seq";
 
+    public byte data[];
+    public int offset = 0;
+    public int length = 0;
+    public int cursor = 0;
+
+    private int refCount = 1;
+    private ByteBuffer parentByteBuffer = null;
+
+    private Order order;
+
+    /**
+     * Create buffer of size no less than length. Buffer can be a bit larger than
+     * length. Offset also can be set to non-zero value to leave some place for
+     * future headers.
+     */
+    public ByteBuffer(int minLength) {
+        // Get buffer of acceptable size from buffer pool
+        this.data = BufferPool.allocateNewBuffer(minLength);
+        this.offset = 0;
+        this.length = minLength;
+    }
+
+    public ByteBuffer(byte data[]) {
+        if (data == null)
+            throw new NullPointerException("Data must be non-null.");
+
+        this.data = data;
+        this.offset = 0;
+        this.length = data.length;
+    }
+
+    public ByteBuffer(byte[] data, int offset, int length) {
+        if (data == null)
+            throw new NullPointerException("Data must be non-null.");
+
+        this.data = data;
+        this.offset = offset;
+        this.length = length;
+    }
+
+    /**
+     * Create byte buffer of requested size with some space reserved for future
+     * headers.
+     */
+    public ByteBuffer(int minLength, boolean reserveSpaceForHeader) {
+        // Get buffer of acceptable size from buffer pool
+        this.data = BufferPool.allocateNewBuffer(128 + minLength);
+        this.offset = 128; // 100 bytes should be enough for headers
+        this.length = minLength;
+    }
+
+    /**
+     * Create empty buffer with given order only.
+     */
+    public ByteBuffer(Order order) {
+        this.order = order;
+    }
+
+    public void setOrder(Order order) {
+        this.order = order;
+    }
+
+    public Order getOrder() {
+        return order;
+    }
+
+    @Override
+    public String toString() {
+        return toString(length);
+    }
+
+    /**
+     * Return string representation of this byte buffer.
+     * 
+     * @param maxLength
+     *          number of bytes to show in string
+     */
+    public String toString(int maxLength) {
+        return "ByteRange(){offset=" + offset + ", length=" + length + ", cursor=" + cursor + ", data=" + ((data == null) ? "null" : toHexString(maxLength))
+                + ((metadata == null || metadata.size() == 0) ? "" : ", metadata=" + metadata) + "}";
+    }
+
+    /**
+     * Return string representation of this byte buffer as hexadecimal numbers,
+     * e.g. "[0x01, 0x02]".
+     * 
+     * @param maxLength
+     *          number of bytes to show in string
+     */
+    public String toHexString(int maxLength) {
+        StringBuilder builder = new StringBuilder(maxLength * 6);
+        builder.append('[');
+        for (int i = 0; i < maxLength && i < length; i++) {
+            if (i > 0)
+                builder.append(", ");
+            int b = data[offset + i] & 0xff;
+            builder.append("0x" + ((b < 16) ? "0" : "") + Integer.toString(b, 16));
+        }
+        builder.append(']');
+        return builder.toString();
+    }
+
+    /**
+     * Return string representation of this byte buffer as hexadecimal numbers,
+     * e.g. "01 02".
+     * 
+     * @param maxLength
+     *          number of bytes to show in string
+     */
+    public String toPlainHexString(int maxLength) {
+        StringBuilder builder = new StringBuilder(maxLength * 3);
+        for (int i = 0; i < maxLength && i < length; i++) {
+            if (i > 0)
+                builder.append(" ");
+            int b = data[offset + i] & 0xff;
+            builder.append(String.format("%02x", b));
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Return string representation of this byte buffer as dump, e.g.
+     * "0000  01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 .................".
+     * 
+     * @param maxLength
+     *          number of bytes to show in string
+     */
+    public String dump() {
+        StringBuilder builder = new StringBuilder(length * 4);
+        int i = 0;
+        for (; i < length && i < length; i++) {
+            if (i % 16 == 0) {
+                builder.append(String.format("%04x", i));
+            }
+
+            builder.append(' ');
+            int b = data[offset + i] & 0xff;
+            builder.append(String.format("%02x", b));
+
+            if (i % 16 == 15) {
+                builder.append(' ');
+                builder.append(toASCIIString(i - 15, i));
+                builder.append('\n');
+            }
+        }
+        int end = i - 1;
+        if (end % 16 != 15) {
+            int begin = end & ~0xf;
+            for (int j = 0; j < (15 - (end % 16)); j++) {
+                builder.append("   ");
+            }
+            builder.append(' ');
+            builder.append(toASCIIString(begin, end));
+            builder.append('\n');
+        }
+        return builder.toString();
+    }
+
+    private String toASCIIString(int start, int finish) {
+        StringBuffer sb = new StringBuffer(16);
+        for (int i = start; i <= finish; i++) {
+            char ch = (char)data[offset + i];
+            if (ch < ' ' || ch >= 0x7f) {
+                sb.append('.');
+            } else {
+                sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Return string representation of this byte buffer as hexadecimal numbers,
+     * e.g. "01 02".
+     */
+    public String toPlainHexString() {
+        return toPlainHexString(length);
+    }
+
+    public void extend(int newLength) {
+        if (data.length < newLength)
+            Arrays.copyOf(data, newLength);
+    }
+
+    public void ref() {
+        refCount++;
+    }
+
+    public void unref() {
+        refCount--;
+
+        if (refCount == 0) {
+
+            if (parentByteBuffer != null) {
+                parentByteBuffer.unref();
+                parentByteBuffer = null;
+            } else {
+                // Return buffer to buffer pool
+                BufferPool.recycleBuffer(data);
+            }
+
+            data = null;
+        }
+
+    }
+
+    public boolean isSoleOwner() {
+        return refCount == 1 && (parentByteBuffer == null);
+    }
+
+    /**
+     * Create shared lightweight copy of part of this buffer.
+     */
+    public ByteBuffer slice(int offset, int length, boolean copyMetadata) {
+        ref();
+
+        if (this.length < (offset + length))
+            throw new RuntimeException("Length of region is larger that length of this buffer. Buffer length: " + this.length + ", offset: " + offset
+                    + ", new region length: " + length + ".");
+
+        ByteBuffer slice = new ByteBuffer(data, this.offset + offset, length);
+
+        if (copyMetadata && this.metadata != null)
+            slice.metadata = new HashMap<String, Object>(metadata);
+
+        return slice;
+    }
+
+    private Map<String, Object> metadata = null;
+
+    public Object putMetadata(String key, Object value) {
+        if (metadata == null)
+            metadata = new HashMap<String, Object>();
+        return metadata.put(key, value);
+    }
+
+    public Object getMetadata(String key) {
+        return (metadata != null) ? metadata.get(key) : null;
+    }
+
+    /**
+     * Create new buffer, which holds data from both buffers. Expensive operation.
+     * 
+     * @TODO if only one reference to this ByteBuffer exists, then extend this
+     *       buffer instead of creating new buffer
+     * @TODO support list of buffers to avoid expensive joins until absolute
+     *       necessary
+     */
+    public ByteBuffer join(ByteBuffer buf) {
+        // Extend byte array for new data
+        int newLength = length + buf.length;
+        byte newData[] = new byte[newLength];
+
+        // Copy data from our buffer
+        System.arraycopy(data, offset, newData, 0, length);
+
+        // Copy data from other buffer
+        System.arraycopy(buf.data, buf.offset, newData, length, buf.length);
+
+        ByteBuffer newBuf = new ByteBuffer(newData);
+
+        // Copy our (older) metadata to new buffer, because handler might store some
+        // metadata in buffer, which is pushed back.
+        if (metadata != null)
+            newBuf.metadata = new HashMap<String, Object>(metadata);
+
+        return newBuf;
+    }
+
+    /**
+     * Copy used portion of buffer to new byte array. Expensive operation.
+     */
+    public byte[] toByteArray() {
+        return Arrays.copyOfRange(data, offset, offset + length);
+    }
+
+    public short[] toShortArray() {
+        if (length % 2 != 0)
+            throw new ArrayIndexOutOfBoundsException("Length of byte array must be dividable by 2 without remainder. Array length: " + length + ", remainder: "
+                    + (length % 2) + ".");
+
+        short[] buf = new short[length / 2];
+
+        for (int i = 0, j = offset; i < buf.length; i++, j += 2) {
+            buf[i] = (short)((data[j + 0] & 0xFF) | ((data[j + 1] & 0xFF) << 8));
+        }
+        return buf;
+    }
+
+    /**
+     * Return array of int's in little endian order.
+     */
+    public int[] toIntLEArray() {
+        if (length % 4 != 0)
+            throw new ArrayIndexOutOfBoundsException("Length of byte array must be dividable by 4 without remainder. Array length: " + length + ", remainder: "
+                    + (length % 4) + ".");
+
+        int[] buf = new int[length / 4];
+
+        for (int i = 0, j = offset; i < buf.length; i++, j += 4) {
+            buf[i] = (data[j + 0] & 0xFF) | ((data[j + 1] & 0xFF) << 8) | ((data[j + 2] & 0xFF) << 16) | ((data[j + 3] & 0xFF) << 24);
+        }
+        return buf;
+    }
+
+    /**
+     * Return array of int's in little endian order, but use only 3 bytes per int
+     * (3RGB).
+     */
+    public int[] toInt3LEArray() {
+        if (length % 3 != 0)
+            throw new ArrayIndexOutOfBoundsException("Length of byte array must be dividable by 3 without remainder. Array length: " + length + ", remainder: "
+                    + (length % 3) + ".");
+
+        int[] buf = new int[length / 3];
+
+        for (int i = 0, j = offset; i < buf.length; i++, j += 3) {
+            buf[i] = (data[j + 0] & 0xFF) | ((data[j + 1] & 0xFF) << 8) | ((data[j + 2] & 0xFF) << 16);
+        }
+        return buf;
+    }
+
+    /**
+     * Helper method for test cases to convert array of byte arrays to array of
+     * byte buffers.
+     */
+    public static ByteBuffer[] convertByteArraysToByteBuffers(byte[]... bas) {
+        ByteBuffer bufs[] = new ByteBuffer[bas.length];
+
+        int i = 0;
+        for (byte[] ba : bas) {
+            bufs[i++] = new ByteBuffer(ba);
+        }
+        return bufs;
+    }
+
+    /**
+     * Read signed int in network order. Cursor is advanced by 4.
+     */
+    public int readSignedInt() {
+        if (cursor + 4 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read 4 bytes from this buffer: " + this + ".");
+
+        int result = (((data[offset + cursor] & 0xff) << 24) + ((data[offset + cursor + 1] & 0xff) << 16) + ((data[offset + cursor + 2] & 0xff) << 8) + (data[offset
+                + cursor + 3] & 0xff));
+        cursor += 4;
+        return result;
+    }
+
+    /**
+     * Read signed int in little endian order. Cursor is advanced by 4.
+     */
+    public int readSignedIntLE() {
+        if (cursor + 4 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read 4 bytes from this buffer: " + this + ".");
+
+        int result = (((data[offset + cursor + 3] & 0xff) << 24) + ((data[offset + cursor + 2] & 0xff) << 16) + ((data[offset + cursor + 1] & 0xff) << 8) + (data[offset
+                + cursor] & 0xff));
+        cursor += 4;
+        return result;
+    }
+
+    /**
+     * Read unsigned int in little endian order. Cursor is advanced by 4.
+     */
+    public long readUnsignedIntLE() {
+        if (cursor + 4 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read 4 bytes from this buffer: " + this + ".");
+
+        long result = (((long)(data[offset + cursor + 3] & 0xff) << 24) + ((long)(data[offset + cursor + 2] & 0xff) << 16)
+                + ((long)(data[offset + cursor + 1] & 0xff) << 8) + (long)(data[offset + cursor + 0] & 0xff));
+        cursor += 4;
+        return result;
+    }
+
+    /**
+     * Read unsigned int in network order. Cursor is advanced by 4.
+     */
+    public long readUnsignedInt() {
+        if (cursor + 4 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read 4 bytes from this buffer: " + this + ".");
+
+        long result = (((long)(data[offset + cursor + 0] & 0xff) << 24) + ((long)(data[offset + cursor + 1] & 0xff) << 16)
+                + ((long)(data[offset + cursor + 2] & 0xff) << 8) + (long)(data[offset + cursor + 3] & 0xff));
+        cursor += 4;
+        return result;
+    }
+
+    /**
+     * Read signed int in variable length format. Top most bit of each byte
+     * indicates that next byte contains additional bits. Cursor is advanced by
+     * 1-5 bytes.
+     */
+    public int readVariableSignedIntLE() {
+        int result = 0;
+
+        for (int shift = 0; shift < 32; shift += 7) {
+            int b = readUnsignedByte();
+            result |= (b & 0x7f) << shift;
+            if ((b & 0x80) == 0)
+                break;
+        }
+
+        return result;
+    }
+
+    /**
+     * Read unsigned int in network order in variable length format. Cursor is
+     * advanced by 1 to 4 bytes.
+     * 
+     * Two most significant bits of first byte indicates length of field: 0x00 - 1
+     * byte, 0x40 - 2 bytes, 0x80 - 3 bytes, 0xc0 - 4 bytes.
+     * 
+     * @see http://msdn.microsoft.com/en-us/library/cc241614.aspx
+     */
+    public int readEncodedUnsignedInt() {
+        int firstByte = readUnsignedByte();
+        int result;
+        switch (firstByte & 0xc0) {
+        default:
+        case 0x00:
+            result = firstByte & 0x3f;
+            break;
+        case 0x40:
+            result = (firstByte & 0x3f << 8) | readUnsignedByte();
+            break;
+        case 0x80:
+            result = (((firstByte & 0x3f << 8) | readUnsignedByte()) << 8) | readUnsignedByte();
+            break;
+        case 0xc0:
+            result = ((((firstByte & 0x3f << 8) | readUnsignedByte()) << 8) | readUnsignedByte() << 8) | readUnsignedByte();
+            break;
+        }
+
+        return result;
+    }
+
+    /**
+     * Read unsigned byte. Cursor is advanced by 1.
+     */
+    public int readUnsignedByte() {
+        if (cursor + 1 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read 1 byte from this buffer: " + this + ".");
+
+        int b = data[offset + cursor] & 0xff;
+        cursor += 1;
+        return b;
+    }
+
+    /**
+     * Read signed byte. Cursor is advanced by 1.
+     */
+    public byte readSignedByte() {
+        if (cursor + 1 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read 1 byte from this buffer: " + this + ".");
+
+        byte b = data[offset + cursor];
+        cursor += 1;
+        return b;
+    }
+
+    /**
+     * Read unsigned short in network order. Cursor is advanced by 2.
+     */
+    public int readUnsignedShort() {
+        if (cursor + 2 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read 2 bytes from this buffer: " + this + ".");
+
+        int result = (((data[offset + cursor] & 0xff) << 8) | (data[offset + cursor + 1] & 0xff));
+        cursor += 2;
+        return result;
+    }
+
+    /**
+     * Read signed short in little endian order. Cursor is advanced by 2.
+     */
+    public short readSignedShortLE() {
+        if (cursor + 2 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read 2 bytes from this buffer: " + this + ".");
+
+        short result = (short)(((data[offset + cursor + 1] & 0xff) << 8) | (data[offset + cursor] & 0xff));
+        cursor += 2;
+        return result;
+    }
+
+    /**
+     * Read signed short in network order. Cursor is advanced by 2.
+     */
+    public short readSignedShort() {
+        if (cursor + 2 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read 2 bytes from this buffer: " + this + ".");
+
+        short result = (short)(((data[offset + cursor + 0] & 0xff) << 8) | (data[offset + cursor + 1] & 0xff));
+        cursor += 2;
+        return result;
+    }
+
+    /**
+     * Read unsigned short in network order in variable length format. Cursor is
+     * advanced by 1 or 2 bytes.
+     * 
+     * Most significant bit of first byte indicates length of field: 0 - 1 byte, 1
+     * - 2 bytes.
+     */
+    public int readVariableUnsignedShort() {
+        int firstByte = readUnsignedByte();
+
+        int result;
+        if ((firstByte & 0x80) == 0) {
+            result = firstByte & 0x7f;
+        } else {
+            int secondByte = readUnsignedByte();
+            result = (((firstByte & 0x7f) << 8) | secondByte);
+        }
+
+        return result;
+    }
+
+    /**
+     * Read integer in BER format.
+     * 
+     * Most significant bit of first byte indicates type of date in first byte: if
+     * 0, then byte contains length (up to 7f), if 1, then byte contains number of
+     * following bytes with value in network order. Value 0x80 means unlimited
+     * length, which ends with two zero bytes (0x00 0x00) sequence.
+     * 
+     * If -1 is returned by this method, then caller must seek two consecutive
+     * zeroes in buffer and consume all that data from buffer, including these two
+     * zeroes, but caller should not parse these two zeroes.
+     * 
+     * @return length or -1, for unlimited length
+     */
+    public long readBerLength() {
+        int firstByte = readUnsignedByte();
+
+        long result;
+        if ((firstByte & 0x80) == 0) {
+            result = firstByte & 0x7f;
+        } else {
+            int intLength = firstByte & 0x7f;
+            if (intLength != 0)
+                result = readUnsignedVarInt(intLength);
+            else
+                return -1;
+        }
+
+        return result;
+    }
+
+    /**
+     * Read integer in BER format.
+     * 
+     * Most significant bit of first byte indicates type of date in first byte: if
+     * 0, then byte contains length (up to 7f), if 1, then byte contains number of
+     * following bytes with value in network order.
+     */
+    public void writeBerLength(long length) {
+        if (length < 0)
+            throw new RuntimeException("Length cannot be less than zero: " + length + ". Data: " + this + ".");
+
+        if (length < 0x80) {
+            writeByte((int)length);
+        } else {
+            if (length < 0xff) {
+                writeByte(0x81);
+                writeByte((int)length);
+            } else if (length <= 0xffFF) {
+                writeByte(0x82);
+                writeShort((int)length);
+            } else if (length <= 0xffFFff) {
+                writeByte(0x83);
+                writeByte((int)(length >> 16));
+                writeShort((int)length);
+            } else if (length <= 0xffFFffFFL) {
+                writeByte(0x84);
+                writeInt((int)length);
+            } else if (length <= 0xffFFffFFffL) {
+                writeByte(0x85);
+                writeByte((int)(length >> 32));
+                writeInt((int)length);
+            } else if (length <= 0xffFFffFFffFFL) {
+                writeByte(0x86);
+                writeShort((int)(length >> 32));
+                writeInt((int)length);
+            } else if (length <= 0xffFFffFFffFFffL) {
+                writeByte(0x87);
+                writeByte((int)(length >> (32 + 16)));
+                writeShort((int)(length >> 32));
+                writeInt((int)length);
+            } else {
+                writeByte(0x88);
+                writeInt((int)(length >> 32));
+                writeInt((int)length);
+            }
+        }
+
+    }
+
+    /**
+     * Read signed variable length integers in network order.
+     * 
+     * @param len
+     *          length of integer
+     */
+    public long readSignedVarInt(int len) {
+        long value = 0;
+        switch (len) {
+        case 0:
+            value = 0;
+            break;
+        case 1:
+            value = readSignedByte();
+            break;
+        case 2:
+            value = readSignedShort();
+            break;
+        case 3:
+            value = (readSignedByte() << 16) | readUnsignedShort();
+            break;
+        case 4:
+            value = readSignedInt();
+            break;
+        case 5:
+            value = (readSignedByte() << 32) | readUnsignedInt();
+            break;
+        case 6:
+            value = (readSignedShort() << 32) | readUnsignedInt();
+            break;
+        case 7:
+            value = (readSignedByte() << 32 + 24) | (readUnsignedShort() << 32) | readUnsignedInt();
+            break;
+        case 8:
+            value = readSignedLong();
+            break;
+        default:
+            throw new RuntimeException("Cannot read integers which are more than 8 bytes long. Length: " + len + ". Data: " + this + ".");
+        }
+
+        return value;
+    }
+
+    /**
+     * Read unsigned variable length integers in network order. Values, which are
+     * larger than 0x7FffFFffFFffFFff cannot be parsed by this method.
+     */
+    public long readUnsignedVarInt(int len) {
+        long value = 0;
+        switch (len) {
+        case 0:
+            value = 0;
+            break;
+        case 1:
+            value = readUnsignedByte();
+            break;
+        case 2:
+            value = readUnsignedShort();
+            break;
+        case 3:
+            value = (readUnsignedByte() << 16) | readUnsignedShort();
+            break;
+        case 4:
+            value = readUnsignedInt();
+            break;
+        case 5:
+            value = (readUnsignedByte() << 32) | readUnsignedInt();
+            break;
+        case 6:
+            value = (readUnsignedShort() << 32) | readUnsignedInt();
+            break;
+        case 7:
+            value = (readUnsignedByte() << 32 + 16) | (readUnsignedShort() << 32) | readUnsignedInt();
+            break;
+        case 8:
+            value = readSignedLong();
+            if (value < 0)
+                throw new RuntimeException(
+                        "Cannot read 64 bit integers which are larger than 0x7FffFFffFFffFFff, because of lack of unsinged long type in Java. Value: " + value + ". Data: "
+                                + this + ".");
+            break;
+        default:
+            throw new RuntimeException("Cannot read integers which are more than 8 bytes long. Length: " + len + ". Data: " + this + ".");
+        }
+
+        return value;
+    }
+
+    /**
+     * Read unsigned short in little endian order. Cursor is advanced by 2.
+     */
+    public int readUnsignedShortLE() {
+        if (cursor + 2 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read 2 bytes from this buffer: " + this + ".");
+
+        int result = (((data[offset + cursor + 1] & 0xff) << 8) | (data[offset + cursor] & 0xff));
+        cursor += 2;
+        return result;
+    }
+
+    /**
+     * Read unsigned short in network order in variable length format. Cursor is
+     * advanced by 1 or 2 bytes.
+     * 
+     * Most significant bit of first byte indicates length of field: 0x00 - 1
+     * byte, 0x80 - 2 bytes.
+     * 
+     * @see http://msdn.microsoft.com/en-us/library/cc241612.aspx
+     */
+    public int readEncodedUnsignedShort() {
+        int firstByte = readUnsignedByte();
+
+        int result;
+        if ((firstByte & 0x80) == 0)
+            result = firstByte & 0x7f;
+        else {
+            int secondByte = readUnsignedByte();
+            result = (((firstByte & 0x7f) << 8) | secondByte);
+        }
+
+        return result;
+    }
+
+    /**
+     * Read signed short in network order in variable length format. Cursor is
+     * advanced by 1 or 2 bytes.
+     * 
+     * Most significant bit of first byte indicates length of field: 0x00 - 1
+     * byte, 0x80 - 2 bytes. Second most significant bit indicates is value
+     * positive or negative.
+     * 
+     * @see http://msdn.microsoft.com/en-us/library/cc241613.aspx
+     */
+    public int readEncodedSignedShort() {
+        int firstByte = readUnsignedByte();
+
+        int result;
+        if ((firstByte & 0x80) == 0)
+            result = firstByte & 0x3f;
+        else {
+            int secondByte = readUnsignedByte();
+            result = (((firstByte & 0x3f) << 8) | secondByte);
+        }
+
+        if ((firstByte & 0x40) > 0)
+            return -result;
+        else
+            return result;
+    }
+
+    /**
+     * Read signed long in little endian order. Cursor is advanced by 8 bytes.
+     */
+    public long readSignedLongLE() {
+        return (((long)readSignedIntLE()) & 0xffFFffFFL) | (((long)readSignedIntLE()) << 32);
+    }
+
+    /**
+     * Read signed long in network order. Cursor is advanced by 8 bytes.
+     */
+    public long readSignedLong() {
+        return (((long)readSignedInt()) << 32) | (((long)readSignedInt()) & 0xffFFffFFL);
+    }
+
+    /**
+     * Read string from buffer. Cursor is advanced by string length.
+     */
+    public String readString(int length, Charset charset) {
+        if (cursor + length > this.length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read " + length + " bytes from this buffer: " + this + ".");
+
+        String string = new String(data, offset + cursor, length, charset);
+        cursor += length;
+        return string;
+    }
+
+    /**
+     * Read string with '\0' character at end.
+     */
+    public String readVariableString(Charset charset) {
+
+        int start = cursor;
+
+        // Find end of string
+        while (readUnsignedByte() != 0) {
+        }
+
+        String string = new String(data, offset + start, cursor - start - 1, charset);
+
+        return string;
+    }
+
+    /**
+     * Read wide string with wide '\0' character at end.
+     */
+    public String readVariableWideString(Charset charset) {
+
+        int start = cursor;
+
+        // Find end of string
+        while (readUnsignedShortLE() != 0) {
+        }
+
+        String string = new String(data, offset + start, cursor - start - 2, charset);
+
+        return string;
+    }
+
+    /**
+     * Get bytes as lightweight slice. Cursor is advanced by data length.
+     */
+    public ByteBuffer readBytes(int dataLength) {
+        if (cursor + dataLength > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read " + dataLength + " bytes from this buffer: " + this + ".");
+
+        ByteBuffer slice = slice(cursor, dataLength, false);
+        cursor += dataLength;
+        return slice;
+    }
+
+    /**
+     * Cursor is advanced by given number of bytes.
+     */
+    public void skipBytes(int numOfBytes) {
+        if (cursor + numOfBytes > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read " + numOfBytes + " bytes from this buffer: " + this + ".");
+
+        cursor += numOfBytes;
+    }
+
+    /**
+     * Write byte. Cursor is advanced by 1.
+     */
+    public void writeByte(int b) {
+        if (cursor + 1 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot write 1 byte to this buffer: " + this + ".");
+
+        data[offset + cursor] = (byte)b;
+        cursor += 1;
+    }
+
+    /**
+     * Write short in network order. Cursor is advanced by 2.
+     */
+    public void writeShort(int x) {
+        if (cursor + 2 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot write 2 bytes to this buffer: " + this + ".");
+
+        data[offset + cursor] = (byte)(x >> 8);
+        data[offset + cursor + 1] = (byte)x;
+        cursor += 2;
+    }
+
+    /**
+     * Write short in little endian order. Cursor is advanced by 2.
+     */
+    public void writeShortLE(int x) {
+        if (cursor + 2 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot write 2 bytes to this buffer: " + this + ".");
+
+        data[offset + cursor + 1] = (byte)(x >> 8);
+        data[offset + cursor] = (byte)x;
+        cursor += 2;
+    }
+
+    /**
+     * Write int in network order. Cursor is advanced by 4.
+     */
+    public void writeInt(int i) {
+        if (cursor + 4 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot write 4 bytes to this buffer: " + this + ".");
+
+        data[offset + cursor] = (byte)(i >> 24);
+        data[offset + cursor + 1] = (byte)(i >> 16);
+        data[offset + cursor + 2] = (byte)(i >> 8);
+        data[offset + cursor + 3] = (byte)i;
+        cursor += 4;
+    }
+
+    public void writeIntLE(int i) {
+        if (cursor + 4 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot write 4 bytes to this buffer: " + this + ".");
+
+        data[offset + cursor] = (byte)i;
+        data[offset + cursor + 1] = (byte)(i >> 8);
+        data[offset + cursor + 2] = (byte)(i >> 16);
+        data[offset + cursor + 3] = (byte)(i >> 24);
+        cursor += 4;
+    }
+
+    /**
+     * Write int in variable length format. Cursor is advanced by number of bytes
+     * written (1-5).
+     * 
+     * Topmost bit of each byte is set to 1 to indicate that next byte has data.
+     */
+    public void writeVariableIntLE(int i) {
+        while (i != 0) {
+            // Get lower bits of number
+            int b = i & 0x7f;
+            i >>= 7;
+
+            if (i > 0)
+                // Set topmost bit of byte to indicate that next byte(s) contains
+                // remainder bits
+                b |= 0x80;
+
+            writeByte(b);
+        }
+    }
+
+    /**
+     * Write short in variable length format. Cursor is advanced by number of
+     * bytes written (1-2).
+     * 
+     * Topmost bit of first byte is set to 1 to indicate that next byte has data.
+     */
+    public void writeVariableShort(int length) {
+        if (length > 0x7f | length < 0)
+            writeShort(length | 0x8000);
+        else
+            writeByte(length);
+    }
+
+    /**
+     * Prepend given data to this byte buffer.
+     */
+    public void prepend(ByteBuffer buf) {
+        prepend(buf.data, buf.offset, buf.length);
+    }
+
+    /**
+     * Prepend given data to this byte buffer.
+     */
+    public void prepend(byte[] data) {
+        prepend(data, 0, data.length);
+    }
+
+    /**
+     * Prepend given data to this byte buffer.
+     */
+    public void prepend(byte[] data, int offset, int length) {
+        if (!isSoleOwner()) {
+            throw new RuntimeException("Create full copy of this byte buffer data for modification. refCount: " + refCount + ", parentByteBuffer: "
+                    + parentByteBuffer + ".");
+        }
+
+        // If there is no enough space for header to prepend
+        if (!(this.offset >= length)) {
+            throw new RuntimeException("Reserve data to have enough space for header.");
+        }
+
+        // Copy header
+        System.arraycopy(data, offset, this.data, this.offset - length, length);
+
+        // Extend byte range to include header
+        this.offset -= length;
+        this.length += length;
+        this.cursor += length;
+    }
+
+    /**
+     * Write byte representation of given string, without string terminators (zero
+     * or zeroes at end of string).
+     */
+    public void writeString(String str, Charset charset) {
+        writeBytes(str.getBytes(charset));
+    }
+
+    /**
+     * Write string of fixed size. When string is shorted, empty space is filled
+     * with zeros. When string is larger, it is truncated.
+     */
+    public void writeFixedString(int length, String str, Charset charset) {
+        byte[] bytes = str.getBytes(charset);
+        writeBytes(bytes, 0, Math.min(bytes.length, length));
+
+        for (int i = bytes.length; i < length; i++)
+            writeByte(0);
+    }
+
+    public void writeBytes(ByteBuffer buf) {
+        writeBytes(buf.data, buf.offset, buf.length);
+    }
+
+    public void writeBytes(byte[] bytes) {
+        writeBytes(bytes, 0, bytes.length);
+    }
+
+    public void writeBytes(byte[] bytes, int offset, int length) {
+        System.arraycopy(bytes, offset, this.data, this.offset + this.cursor, length);
+        cursor += length;
+    }
+
+    /**
+     * Reduce length of buffer to cursor position.
+     */
+    public void trimAtCursor() {
+        length = cursor;
+    }
+
+    /**
+     * Rewind cursor to beginning of the buffer.
+     */
+    public void rewindCursor() {
+        cursor = 0;
+    }
+
+    /**
+     * Read RGB color in LE order. Cursor is advanced by 3.
+     * 
+     * @return color as int, with red in lowest octet.
+     */
+    public int readRGBColor() {
+        return readUnsignedByte() | (readUnsignedByte() << 8) | (readUnsignedByte() << 16);
+    }
+
+    public void assertThatBufferIsFullyRead() {
+        if (cursor != length)
+            throw new RuntimeException("Data in buffer is not read fully. Buf: " + this + ".");
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            result = 31 * result + data[i];
+
+        result = prime * result + length;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+
+        // Does not work in case of anonymous type(s)
+        if (getClass() != obj.getClass())
+            return false;
+
+        ByteBuffer other = (ByteBuffer)obj;
+        if (length != other.length)
+            return false;
+
+        for (int i = 0; i < length; i++)
+            if (data[offset + i] != other.data[other.offset + i])
+                return false;
+
+        return true;
+    }
+
+    /**
+     * Return length of data left after cursor.
+     */
+    public int remainderLength() {
+        if (length >= cursor)
+            return length - cursor;
+        else
+            throw new RuntimeException("Inconsistent state of buffer: cursor is after end of buffer: " + this + ".");
+    }
+
+    public Set<String> getMetadataKeys() {
+        if (metadata != null)
+            return metadata.keySet();
+        else
+            return new HashSet<String>(0);
+    }
+
+    /**
+     * Return unsigned value of byte at given position relative to cursor. Cursor
+     * is not advanced.
+     */
+    public int peekUnsignedByte(int i) {
+        return data[offset + cursor + i] & 0xff;
+    }
+
+    /**
+     * Trim few first bytes.
+     */
+    public void trimHeader(int length) {
+        this.offset += length;
+        this.length -= length;
+        rewindCursor();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSink.java
old mode 100644
new mode 100755
index e3de289..becdb36
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSink.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSink.java
@@ -18,7 +18,7 @@ package streamer;
 
 public interface DataSink {
 
-  void sendData(ByteBuffer buf);
+    void sendData(ByteBuffer buf);
 
-  void sendEvent(Event event, Direction direction);
+    void sendEvent(Event event, Direction direction);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSource.java
old mode 100644
new mode 100755
index 152be2e..40064c5
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSource.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSource.java
@@ -18,43 +18,43 @@ package streamer;
 
 public interface DataSource {
 
-  /**
-   * Get data from source.
-   * 
-   * @param block
-   *          if false, then return immediately when no data is available,
-   *          otherwise wait for data
-   * @return new data or null, when no data is available
-   */
-  ByteBuffer pull(boolean block);
+    /**
+     * Get data from source.
+     * 
+     * @param block
+     *          if false, then return immediately when no data is available,
+     *          otherwise wait for data
+     * @return new data or null, when no data is available
+     */
+    ByteBuffer pull(boolean block);
 
-  /**
-   * Hold data temporary to use at next pull or push.
-   * 
-   * @param buf
-   *          a data
-   */
-  void pushBack(ByteBuffer buf);
+    /**
+     * Hold data temporary to use at next pull or push.
+     * 
+     * @param buf
+     *          a data
+     */
+    void pushBack(ByteBuffer buf);
 
-  /**
-   * Hold data temporary to use at next pull. Don't return abything untill given
-   * amount of data will be read from source, because data will be pushed back
-   * anyway.
-   * 
-   * @param buf
-   *          a data
-   * @param lengthOfFullPacket
-   *          length of full block of data to read from source
-   */
-  void pushBack(ByteBuffer buf, int lengthOfFullPacket);
+    /**
+     * Hold data temporary to use at next pull. Don't return abything untill given
+     * amount of data will be read from source, because data will be pushed back
+     * anyway.
+     * 
+     * @param buf
+     *          a data
+     * @param lengthOfFullPacket
+     *          length of full block of data to read from source
+     */
+    void pushBack(ByteBuffer buf, int lengthOfFullPacket);
 
-  /**
-   * Send event to pads.
-   * 
-   * @param event
-   *          a event
-   * @param direction
-   *          pad direction
-   */
-  void sendEvent(Event event, Direction direction);
+    /**
+     * Send event to pads.
+     * 
+     * @param event
+     *          a event
+     * @param direction
+     *          pad direction
+     */
+    void sendEvent(Event event, Direction direction);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Direction.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Direction.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Direction.java
old mode 100644
new mode 100755
index c9dede8..92fc8fd
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Direction.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Direction.java
@@ -17,5 +17,5 @@
 package streamer;
 
 public enum Direction {
-  IN, OUT
+    IN, OUT
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Element.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Element.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Element.java
old mode 100644
new mode 100755
index c927dea..997ec38
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Element.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Element.java
@@ -19,102 +19,102 @@ package streamer;
 import java.util.Set;
 
 /**
- * Element is for processing of data. It has one or more contact pads, which can
+ * Element is basic building block for constructing data processing pipes. It has one or more contact pads, which can
  * be wired with other elements using links.
  */
 public interface Element {
 
-  /**
-   * Name of pad for standard input. Should be set in all elements except pure
-   * sinks.
-   */
-  public static final String STDIN = "stdin";
+    /**
+     * Name of pad for standard input. Should be set in all elements except pure
+     * sinks.
+     */
+    public static final String STDIN = "stdin";
 
-  /**
-   * Name of pad for standard output. Should be set in all elements except pure
-   * sources.
-   */
-  public static final String STDOUT = "stdout";
+    /**
+     * Name of pad for standard output. Should be set in all elements except pure
+     * sources.
+     */
+    public static final String STDOUT = "stdout";
 
-  /**
-   * Get link connected to given pad.
-   * 
-   * @param padName
-   *          Standard pads are "stdin" and "stdout".
-   */
-  Link getLink(String padName);
+    /**
+     * Get link connected to given pad.
+     * 
+     * @param padName
+     *          Standard pads are "stdin" and "stdout".
+     */
+    Link getLink(String padName);
 
-  /**
-   * Get pads of this element.
-   */
-  Set<String> getPads(Direction direction);
+    /**
+     * Get pads of this element.
+     */
+    Set<String> getPads(Direction direction);
 
-  /**
-   * Connect link to given pad.
-   * 
-   * @param padName
-   *          a pad name. Standard pads are "stdin" and "stdout".
-   */
-  void setLink(String padName, Link link, Direction direction);
+    /**
+     * Connect link to given pad.
+     * 
+     * @param padName
+     *          a pad name. Standard pads are "stdin" and "stdout".
+     */
+    void setLink(String padName, Link link, Direction direction);
 
-  /**
-   * Disconnect link from given pad.
-   * 
-   * @param padName
-   *          Standard pads are "stdin" and "stdout".
-   */
-  void dropLink(String padName);
+    /**
+     * Disconnect link from given pad.
+     * 
+     * @param padName
+     *          Standard pads are "stdin" and "stdout".
+     */
+    void dropLink(String padName);
 
-  /**
-   * Pull data from element and handle it. Element should ask one of it input
-   * pads for data, handle data and push result to it sink(s), if any.
-   * 
-   * @param block
-   *          block until data will be available, or do a slight delay at least,
-   *          when data is not available
-   */
-  void poll(boolean block);
+    /**
+     * Pull data from element and handle it. Element should ask one of it input
+     * pads for data, handle data and push result to it sink(s), if any.
+     * 
+     * @param block
+     *          block until data will be available, or do a slight delay at least,
+     *          when data is not available
+     */
+    void poll(boolean block);
 
-  /**
-   * Handle incoming data.
-   * 
-   * @param buf
-   *          a data
-   * @param link
-   *          TODO
-   */
-  void handleData(ByteBuffer buf, Link link);
+    /**
+     * Handle incoming data.
+     * 
+     * @param buf
+     *          a data
+     * @param link
+     *          TODO
+     */
+    void handleData(ByteBuffer buf, Link link);
 
-  /**
-   * Handle event.
-   * 
-   * @param event
-   *          an event
-   * @param direction
-   *          if IN, then send event to input pads, when OUT, then send to
-   *          output pads
-   */
-  void handleEvent(Event event, Direction direction);
+    /**
+     * Handle event.
+     * 
+     * @param event
+     *          an event
+     * @param direction
+     *          if IN, then send event to input pads, when OUT, then send to
+     *          output pads
+     */
+    void handleEvent(Event event, Direction direction);
 
-  /**
-   * Get element ID.
-   */
-  String getId();
+    /**
+     * Get element ID.
+     */
+    String getId();
 
-  /**
-   * Validate element: check is all required pads are connected.
-   */
-  void validate();
+    /**
+     * Validate element: check is all required pads are connected.
+     */
+    void validate();
 
-  /**
-   * Drop link.
-   * 
-   * @param link a link to drop
-   */
-  void dropLink(Link link);
+    /**
+     * Drop link.
+     * 
+     * @param link a link to drop
+     */
+    void dropLink(Link link);
 
-  /**
-   * Drop existing link and replace it by new link.
-   */
-  void replaceLink(Link existingLink, Link newLink);
+    /**
+     * Drop existing link and replace it by new link.
+     */
+    void replaceLink(Link existingLink, Link newLink);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Event.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Event.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Event.java
old mode 100644
new mode 100755
index 5e1a389..998274c
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Event.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Event.java
@@ -17,17 +17,17 @@
 package streamer;
 
 public enum Event {
-  STREAM_START, 
-  STREAM_CLOSE,
-  
-  /**
-   * Upgrade socket to SSL.
-   */
-  SOCKET_UPGRADE_TO_SSL,
-  
-  /**
-   * Switch links to input mode.
-   */
-  LINK_SWITCH_TO_PULL_MODE
+    STREAM_START,
+    STREAM_CLOSE,
+
+    /**
+     * Upgrade socket to SSL.
+     */
+    SOCKET_UPGRADE_TO_SSL,
+
+    /**
+     * Switch links to input mode.
+     */
+    LINK_SWITCH_TO_PULL_MODE
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSink.java
deleted file mode 100644
index 65fb29e..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSink.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 streamer;
-
-public class FakeSink extends BaseElement {
-
-  public FakeSink(String id) {
-    super(id);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Received buf #" + (packetNumber) + " " + buf + ".");
-
-    if (buf == null)
-      return;
-
-    // Use packetNumber variable to count incoming packets
-    packetNumber++;
-
-    buf.unref();
-  }
-
-  @Override
-  public String toString() {
-    return "FakeSink(" + id + ")";
-  }
-
-  @Override
-  public void handleEvent(Event event, Direction direction) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Event received: " + event + ".");
-
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-
-    Element sink = new FakeSink("sink") {
-      {
-        verbose = true;
-      }
-    };
-
-    byte[] data = new byte[] { 1, 2, 3 };
-    ByteBuffer buf = new ByteBuffer(data);
-    sink.setLink(STDIN, new SyncLink(), Direction.IN);
-    sink.getLink(STDIN).sendData(buf);
-
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSource.java
deleted file mode 100644
index 4cf6503..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSource.java
+++ /dev/null
@@ -1,125 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 streamer;
-
-public class FakeSource extends BaseElement {
-
-  /**
-   * Delay for null packets in poll method when blocking is requested, in
-   * milliseconds.
-   */
-  protected long delay = SyncLink.STANDARD_DELAY_FOR_EMPTY_PACKET;
-
-  public FakeSource(String id) {
-    super(id);
-  }
-
-  @Override
-  public void poll(boolean block) {
-    if (numBuffers > 0 && packetNumber >= numBuffers) {
-      // Close stream when limit of packets is reached
-      sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
-      return;
-    }
-
-    // Prepare new packet
-    ByteBuffer buf = initializeData();
-
-    // Push it to output(s)
-    pushDataToAllOuts(buf);
-
-    // Make slight delay when blocking input was requested (to avoid
-    // consuming of 100% in parent loop)
-    if (block)
-      delay();
-
-  }
-
-  /**
-   * Make slight delay. Should be used when blocking input is requested in pull
-   * mode, but null packed was returned by input.
-   */
-  protected void delay() {
-    try {
-      Thread.sleep(delay);
-    } catch (InterruptedException e) {
-    }
-  }
-
-  /**
-   * Initialize data.
-   */
-  public ByteBuffer initializeData() {
-    ByteBuffer buf = new ByteBuffer(incommingBufLength);
-
-    // Set first byte of package to it sequance number
-    buf.data[buf.offset] = (byte) (packetNumber % 128);
-
-    // Initialize rest of bytes with sequential values, which are
-    // corresponding with their position in byte buffer
-    for (int i = buf.offset + 1; i < buf.length; i++)
-      buf.data[i] = (byte) (i % 128);
-
-    buf.putMetadata(ByteBuffer.SEQUENCE_NUMBER, packetNumber);
-    buf.putMetadata("src", id);
-
-    return buf;
-  }
-
-  @Override
-  public String toString() {
-    return "FakeSource(" + id + ")";
-  }
-
-  public static void main(String args[]) {
-
-    Element fakeSource = new FakeSource("source 3/10/100") {
-      {
-        verbose = true;
-        this.incommingBufLength = 3;
-        this.numBuffers = 10;
-        this.delay = 100;
-      }
-    };
-
-    Element fakeSink = new FakeSink("sink") {
-      {
-        this.verbose = true;
-      }
-    };
-
-    Element fakeSink2 = new FakeSink("sink2") {
-      {
-        this.verbose = true;
-      }
-    };
-
-    Link link = new SyncLink();
-
-    fakeSource.setLink(STDOUT, link, Direction.OUT);
-    fakeSink.setLink(STDIN, link, Direction.IN);
-
-    Link link2 = new SyncLink();
-
-    fakeSource.setLink("out2", link2, Direction.OUT);
-    fakeSink2.setLink(STDIN, link2, Direction.IN);
-
-    link.run();
-
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/InputStreamSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/InputStreamSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/InputStreamSource.java
old mode 100644
new mode 100755
index b05637f..0c8c97d
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/InputStreamSource.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/InputStreamSource.java
@@ -20,175 +20,177 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 
+import streamer.debug.FakeSink;
+
 /**
  * Source element, which reads data from InputStream.
  */
 public class InputStreamSource extends BaseElement {
 
-  protected InputStream is;
-  protected SocketWrapper socketWrapper;
-
-  public InputStreamSource(String id) {
-    super(id);
-  }
-
-  public InputStreamSource(String id, InputStream is) {
-    super(id);
-    this.is = is;
-  }
-
-  public InputStreamSource(String id, SocketWrapper socketWrapper) {
-    super(id);
-    this.socketWrapper = socketWrapper;
-  }
-
-  @Override
-  public void handleEvent(Event event, Direction direction) {
-    switch (event) {
-    case SOCKET_UPGRADE_TO_SSL:
-      socketWrapper.upgradeToSsl();
-      break;
-    default:
-      super.handleEvent(event, direction);
+    protected InputStream is;
+    protected SocketWrapperImpl socketWrapper;
+
+    public InputStreamSource(String id) {
+        super(id);
     }
-  }
-
-  @Override
-  public void setLink(String padName, Link link, Direction direction) {
-    switch (direction) {
-    case OUT:
-      super.setLink(padName, link, direction);
-
-      if (is == null) {
-        // Pause links until data stream will be ready
-        link.pause();
-      }
-      break;
-    case IN:
-      throw new RuntimeException("Cannot assign link to input pad in source element. Element: " + this + ", pad: " + padName + ", link: " + link + ".");
+
+    public InputStreamSource(String id, InputStream is) {
+        super(id);
+        this.is = is;
     }
-  }
 
-  public void setInputStream(InputStream is) {
-    this.is = is;
+    public InputStreamSource(String id, SocketWrapperImpl socketWrapper) {
+        super(id);
+        this.socketWrapper = socketWrapper;
+    }
 
-    // Resume links
-    resumeLinks();
-  }
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        switch (event) {
+        case SOCKET_UPGRADE_TO_SSL:
+            socketWrapper.upgradeToSsl();
+            break;
+        default:
+            super.handleEvent(event, direction);
+        }
+    }
 
-  private void resumeLinks() {
-    for (DataSink sink : outputPads.values())
-      ((Link) sink).resume();
-  }
+    @Override
+    public void setLink(String padName, Link link, Direction direction) {
+        switch (direction) {
+        case OUT:
+            super.setLink(padName, link, direction);
+
+            if (is == null) {
+                // Pause links until data stream will be ready
+                link.pause();
+            }
+            break;
+        case IN:
+            throw new RuntimeException("Cannot assign link to input pad in source element. Element: " + this + ", pad: " + padName + ", link: " + link + ".");
+        }
+    }
 
-  /**
-   * Read data from input stream.
-   */
-  @Override
-  public void poll(boolean block) {
-    try {
-      if (!block && is.available() == 0) {
+    public void setInputStream(InputStream is) {
+        this.is = is;
 
-        if (verbose)
-          System.out.println("[" + this + "] INFO: No data in stream is available now, returning.");
+        // Resume links
+        resumeLinks();
+    }
 
-        return;
-      }
+    private void resumeLinks() {
+        for (DataSink sink : outputPads.values())
+            ((Link)sink).resume();
+    }
 
-      // Create buffer of recommended size and with default offset
-      ByteBuffer buf = new ByteBuffer(incommingBufLength);
+    /**
+     * Read data from input stream.
+     */
+    @Override
+    public void poll(boolean block) {
+        try {
+            if (!block && is.available() == 0) {
 
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Reading data from stream.");
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: No data in stream is available now, returning.");
 
-      int actualLength = is.read(buf.data, buf.offset, buf.data.length - buf.offset);
+                return;
+            }
 
-      if (actualLength < 0) {
-        if (verbose)
-          System.out.println("[" + this + "] INFO: End of stream.");
+            // Create buffer of recommended size and with default offset
+            ByteBuffer buf = new ByteBuffer(incommingBufLength);
 
-        buf.unref();
-        closeStream();
-        sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
-        return;
-      }
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Reading data from stream.");
 
-      if (actualLength == 0) {
-        if (verbose)
-          System.out.println("[" + this + "] INFO: Empty buffer is read from stream.");
+            int actualLength = is.read(buf.data, buf.offset, buf.data.length - buf.offset);
+
+            if (actualLength < 0) {
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: End of stream.");
+
+                buf.unref();
+                closeStream();
+                sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
+                return;
+            }
 
-        buf.unref();
-        return;
-      }
+            if (actualLength == 0) {
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: Empty buffer is read from stream.");
 
-      buf.length = actualLength;
+                buf.unref();
+                return;
+            }
 
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Data read from stream: " + buf + ".");
+            buf.length = actualLength;
 
-      pushDataToAllOuts(buf);
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Data read from stream: " + buf + ".");
 
-    } catch (IOException e) {
-      System.err.println("[" + this + "] ERROR: " + e.getMessage());
-      closeStream();
+            pushDataToAllOuts(buf);
+
+        } catch (IOException e) {
+            System.err.println("[" + this + "] ERROR: " + e.getMessage());
+            closeStream();
+        }
     }
-  }
 
-  @Override
-  protected void onClose() {
-    closeStream();
-  }
+    @Override
+    protected void onClose() {
+        closeStream();
+    }
 
-  private void closeStream() {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Closing stream.");
+    private void closeStream() {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Closing stream.");
+
+        try {
+            is.close();
+        } catch (IOException e) {
+        }
+        try {
+            sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
+        } catch (Exception e) {
+        }
+    }
 
-    try {
-      is.close();
-    } catch (IOException e) {
+    @Override
+    public String toString() {
+        return "InputStreamSource(" + id + ")";
     }
-    try {
-      sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
-    } catch (Exception e) {
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        InputStream is = new ByteArrayInputStream(new byte[] {1, 2, 3});
+
+        InputStreamSource source = new InputStreamSource("source") {
+            {
+                verbose = true;
+            }
+        };
+        Element fakeSink = new FakeSink("sink") {
+            {
+                verbose = true;
+            }
+        };
+
+        Link link = new SyncLink() {
+            {
+                verbose = true;
+            }
+        };
+
+        source.setLink(STDOUT, link, Direction.OUT);
+        fakeSink.setLink(STDIN, link, Direction.IN);
+
+        source.setInputStream(is);
+
+        link.sendEvent(Event.STREAM_START, Direction.OUT);
+        link.run();
+
     }
-  }
-
-  @Override
-  public String toString() {
-    return "InputStreamSource(" + id + ")";
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    InputStream is = new ByteArrayInputStream(new byte[] { 1, 2, 3 });
-
-    InputStreamSource source = new InputStreamSource("source") {
-      {
-        verbose = true;
-      }
-    };
-    Element fakeSink = new FakeSink("sink") {
-      {
-        verbose = true;
-      }
-    };
-
-    Link link = new SyncLink() {
-      {
-        verbose = true;
-      }
-    };
-
-    source.setLink(STDOUT, link, Direction.OUT);
-    fakeSink.setLink(STDIN, link, Direction.IN);
-
-    source.setInputStream(is);
-
-    link.sendEvent(Event.STREAM_START, Direction.OUT);
-    link.run();
-
-  }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Link.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Link.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Link.java
old mode 100644
new mode 100755
index bd970f0..d1f747f
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Link.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Link.java
@@ -22,45 +22,45 @@ package streamer;
  */
 public interface Link extends DataSource, DataSink, Runnable {
 
-  /**
-   * Wire this link with given sink.
-   * 
-   * @param sink
-   *          an Element
-   * @return same sink element, for chaining
-   */
-  Element setSink(Element sink);
+    /**
+     * Wire this link with given sink.
+     * 
+     * @param sink
+     *          an Element
+     * @return same sink element, for chaining
+     */
+    Element setSink(Element sink);
 
-  /**
-   * Wire this link with given source.
-   * 
-   * @param source
-   *          an Element
-   * @return same source element, for chaining
-   */
-  Element setSource(Element source);
+    /**
+     * Wire this link with given source.
+     * 
+     * @param source
+     *          an Element
+     * @return same source element, for chaining
+     */
+    Element setSource(Element source);
 
-  Element getSource();
+    Element getSource();
 
-  Element getSink();
+    Element getSink();
 
-  /**
-   * Hold all data in cache, don't pass data to sink until resumed.
-   */
-  void pause();
+    /**
+     * Hold all data in cache, don't pass data to sink until resumed.
+     */
+    void pause();
 
-  /**
-   * Resume transfer.
-   */
-  void resume();
-  
-  /**
-   * Change mode of operation of this link from push mode to pull mode.
-   */
-  void setPullMode();
-  
-  /**
-   * Drop this link.
-   */
-  void drop();
+    /**
+     * Resume transfer.
+     */
+    void resume();
+
+    /**
+     * Change mode of operation of this link from push mode to pull mode.
+     */
+    void setPullMode();
+
+    /**
+     * Drop this link.
+     */
+    void drop();
 }


[03/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtKeyboardEventToVncAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtKeyboardEventToVncAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtKeyboardEventToVncAdapter.java
deleted file mode 100644
index 5537d24..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtKeyboardEventToVncAdapter.java
+++ /dev/null
@@ -1,369 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 vncclient;
-
-import java.awt.event.KeyEvent;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-import common.KeyOrder;
-
-public class AwtKeyboardEventToVncAdapter extends BaseElement {
-
-  protected boolean sh = false;
-  protected boolean caps = false;
-  protected boolean num = false;
-
-  public AwtKeyboardEventToVncAdapter(String id) {
-    super(id);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    KeyOrder order = (KeyOrder) buf.getOrder();
-    buf.unref();
-
-    ByteBuffer outBuf = new ByteBuffer(8);
-    outBuf.writeByte(RfbConstants.CLIENT_KEYBOARD_EVENT);
-
-    outBuf.writeByte((order.pressed) ? RfbConstants.KEY_DOWN : RfbConstants.KEY_UP);
-    outBuf.writeShort(0); // padding
-    outBuf.writeInt(map_en_us(order));
-
-    pushDataToAllOuts(outBuf);
-  }
-
-  /**
-   * Return key scan code (in lower byte) and extended flags (in second byte).
-   */
-  private int map_en_us(KeyOrder order) {
-
-    switch (order.event.getKeyCode()) {
-    // Functional keys
-    case KeyEvent.VK_ESCAPE:
-      return 0xff1b;
-    case KeyEvent.VK_F1:
-      return 0xffbe;
-    case KeyEvent.VK_F2:
-      return 0xffbf;
-    case KeyEvent.VK_F3:
-      return 0xffc0;
-    case KeyEvent.VK_F4:
-      return 0xffc1;
-    case KeyEvent.VK_F5:
-      return 0xffc2;
-    case KeyEvent.VK_F6:
-      return 0xffc3;
-    case KeyEvent.VK_F7:
-      return 0xffc4;
-    case KeyEvent.VK_F8:
-      return 0xffc5;
-    case KeyEvent.VK_F9:
-      return 0xffc6;
-    case KeyEvent.VK_F10:
-      return 0xffc7;
-    case KeyEvent.VK_F11:
-      return 0xffc8;
-    case KeyEvent.VK_F12:
-      return 0xffc9;
-
-      // Row #1
-    case KeyEvent.VK_BACK_QUOTE:
-      return (sh) ? '~' : '`';
-    case KeyEvent.VK_1:
-      return (sh) ? '!' : '1';
-    case KeyEvent.VK_2:
-      return (sh) ? '@' : '2';
-    case KeyEvent.VK_3:
-      return (sh) ? '#' : '3';
-    case KeyEvent.VK_4:
-      return (sh) ? '$' : '4';
-    case KeyEvent.VK_5:
-      return (sh) ? '%' : '5';
-    case KeyEvent.VK_6:
-      return (sh) ? '^' : '6';
-    case KeyEvent.VK_7:
-      return (sh) ? '&' : '7';
-    case KeyEvent.VK_8:
-      return (sh) ? '*' : '8';
-    case KeyEvent.VK_9:
-      return (sh) ? '(' : '9';
-    case KeyEvent.VK_0:
-      return (sh) ? ')' : '0';
-    case KeyEvent.VK_MINUS:
-      return (sh) ? '_' : '-';
-    case KeyEvent.VK_EQUALS:
-      return (sh) ? '+' : '=';
-    case KeyEvent.VK_BACK_SPACE:
-      return 0xff08;
-
-      // Row #2
-    case KeyEvent.VK_TAB:
-      return 0xff09;
-    case KeyEvent.VK_Q:
-      return (sh ^ caps) ? 'Q' : 'q';
-    case KeyEvent.VK_W:
-      return (sh ^ caps) ? 'W' : 'w';
-    case KeyEvent.VK_E:
-      return (sh ^ caps) ? 'E' : 'e';
-    case KeyEvent.VK_R:
-      return (sh ^ caps) ? 'R' : 'r';
-    case KeyEvent.VK_T:
-      return (sh ^ caps) ? 'T' : 't';
-    case KeyEvent.VK_Y:
-      return (sh ^ caps) ? 'Y' : 'y';
-    case KeyEvent.VK_U:
-      return (sh ^ caps) ? 'U' : 'u';
-    case KeyEvent.VK_I:
-      return (sh ^ caps) ? 'I' : 'i';
-    case KeyEvent.VK_O:
-      return (sh ^ caps) ? 'O' : 'o';
-    case KeyEvent.VK_P:
-      return (sh ^ caps) ? 'P' : 'p';
-    case KeyEvent.VK_OPEN_BRACKET:
-      return (sh) ? '{' : '[';
-    case KeyEvent.VK_CLOSE_BRACKET:
-      return (sh) ? '{' : ']';
-    case KeyEvent.VK_ENTER:
-      switch (order.event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_STANDARD:
-        return 0xff0d;
-      case KeyEvent.KEY_LOCATION_NUMPAD:
-        return 0xff8d;
-      }
-
-      // Row #3
-    case KeyEvent.VK_CAPS_LOCK:
-      if (order.pressed)
-        caps = !caps;
-      return 0xFFE5;
-    case KeyEvent.VK_A:
-      return (sh ^ caps) ? 'A' : 'a';
-    case KeyEvent.VK_S:
-      return (sh ^ caps) ? 'S' : 's';
-    case KeyEvent.VK_D:
-      return (sh ^ caps) ? 'D' : 'd';
-    case KeyEvent.VK_F:
-      return (sh ^ caps) ? 'F' : 'f';
-    case KeyEvent.VK_G:
-      return (sh ^ caps) ? 'G' : 'g';
-    case KeyEvent.VK_H:
-      return (sh ^ caps) ? 'H' : 'h';
-    case KeyEvent.VK_J:
-      return (sh ^ caps) ? 'J' : 'j';
-    case KeyEvent.VK_K:
-      return (sh ^ caps) ? 'K' : 'k';
-    case KeyEvent.VK_L:
-      return (sh ^ caps) ? 'L' : 'l';
-    case KeyEvent.VK_SEMICOLON:
-      return (sh) ? ':' : ';';
-    case KeyEvent.VK_QUOTE:
-      return (sh) ? '"' : '\'';
-
-      // Row #4
-    case KeyEvent.VK_SHIFT:
-      sh = !sh;
-      switch (order.event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 0xffe1;
-      case KeyEvent.KEY_LOCATION_RIGHT:
-        return 0xffe2;
-      }
-    case KeyEvent.VK_BACK_SLASH:
-      return (sh) ? '|' : '\\';
-    case KeyEvent.VK_Z:
-      return (sh ^ caps) ? 'Z' : 'z';
-    case KeyEvent.VK_X:
-      return (sh ^ caps) ? 'X' : 'x';
-    case KeyEvent.VK_C:
-      return (sh ^ caps) ? 'C' : 'c';
-    case KeyEvent.VK_V:
-      return (sh ^ caps) ? 'V' : 'v';
-    case KeyEvent.VK_B:
-      return (sh ^ caps) ? 'B' : 'b';
-    case KeyEvent.VK_N:
-      return (sh ^ caps) ? 'N' : 'n';
-    case KeyEvent.VK_M:
-      return (sh ^ caps) ? 'M' : 'M';
-    case KeyEvent.VK_COMMA:
-      return (sh) ? '<' : ',';
-    case KeyEvent.VK_PERIOD:
-      return (sh) ? '>' : '.';
-    case KeyEvent.VK_SLASH:
-      return (sh) ? '?' : '/';
-
-      //
-      // Bottom row
-    case KeyEvent.VK_CONTROL:
-      switch (order.event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 0xFFE3;
-      case KeyEvent.KEY_LOCATION_RIGHT:
-        return 0xFFE4;
-      }
-    case KeyEvent.VK_WINDOWS:
-      switch (order.event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 0xFFED; // HyperL
-      case KeyEvent.KEY_LOCATION_RIGHT:
-        return 0xFFEE; // HyperR
-      }
-    case KeyEvent.VK_META:
-      switch (order.event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 0xFFE7; // MetaL
-      case KeyEvent.KEY_LOCATION_RIGHT:
-        return 0xFFE8; // MetaR
-      }
-
-    case KeyEvent.VK_ALT:
-      switch (order.event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 0xFFE9;
-      case KeyEvent.KEY_LOCATION_RIGHT:
-        return 0xFFEA;
-      }
-    case KeyEvent.VK_ALT_GRAPH:
-      return 0xfe03;
-
-    case KeyEvent.VK_SPACE:
-      return ' ';
-
-    case KeyEvent.VK_CONTEXT_MENU:
-      return 0xff67;
-
-      //
-      // Special keys
-    case KeyEvent.VK_PRINTSCREEN:
-      return (sh) ? 0xFF15/* SysRq */: 0xFF61 /* Print */;
-    case KeyEvent.VK_SCROLL_LOCK:
-      return 0xFF14;
-    case KeyEvent.VK_PAUSE:
-      return (sh) ? 0xFF6B/* Break */: 0xFF13/* Pause */;
-
-      // Text navigation keys
-    case KeyEvent.VK_INSERT:
-      return 0xff63;
-    case KeyEvent.VK_DELETE:
-      return 0xffff;
-    case KeyEvent.VK_HOME:
-      return 0xff50;
-    case KeyEvent.VK_END:
-      return 0xff57;
-    case KeyEvent.VK_PAGE_UP:
-      return 0xff55;
-    case KeyEvent.VK_PAGE_DOWN:
-      return 0xff56;
-
-      // Cursor keys
-    case KeyEvent.VK_LEFT:
-      switch (order.event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 0xff51;
-      case KeyEvent.KEY_LOCATION_NUMPAD:
-        return 0xFF96;
-      }
-    case KeyEvent.VK_UP:
-      switch (order.event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 0xff52;
-      case KeyEvent.KEY_LOCATION_NUMPAD:
-        return 0xFF97;
-      }
-    case KeyEvent.VK_RIGHT:
-      switch (order.event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 0xff53;
-      case KeyEvent.KEY_LOCATION_NUMPAD:
-        return 0xFF98;
-      }
-    case KeyEvent.VK_DOWN:
-      switch (order.event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 0xff54;
-      case KeyEvent.KEY_LOCATION_NUMPAD:
-        return 0xFF99;
-      }
-
-      // Keypad
-    case KeyEvent.VK_NUM_LOCK:
-      if (order.pressed)
-        num = !num;
-      return 0xFF6F;
-    case KeyEvent.VK_DIVIDE:
-      return 0xFFAF;
-    case KeyEvent.VK_MULTIPLY:
-      return 0xFFAA;
-    case KeyEvent.VK_SUBTRACT:
-      return 0xFFAD;
-    case KeyEvent.VK_ADD:
-      return 0xFFAB;
-
-    case KeyEvent.VK_KP_LEFT:
-      return 0xFF96;
-    case KeyEvent.VK_KP_UP:
-      return 0xFF97;
-    case KeyEvent.VK_KP_RIGHT:
-      return 0xFF98;
-    case KeyEvent.VK_KP_DOWN:
-      return 0xFF99;
-
-    case KeyEvent.VK_NUMPAD0:
-      return 0xFFB0;
-    case KeyEvent.VK_NUMPAD1:
-      return 0xFFB1;
-    case KeyEvent.VK_NUMPAD2:
-      return 0xFFB2;
-    case KeyEvent.VK_NUMPAD3:
-      return 0xFFB3;
-    case KeyEvent.VK_NUMPAD4:
-      return 0xFFB4;
-    case KeyEvent.VK_NUMPAD5:
-      return 0xFFB5;
-    case KeyEvent.VK_NUMPAD6:
-      return 0xFFB6;
-    case KeyEvent.VK_NUMPAD7:
-      return 0xFFB7;
-    case KeyEvent.VK_NUMPAD8:
-      return 0xFFB8;
-    case KeyEvent.VK_NUMPAD9:
-      return 0xFFB9;
-    case KeyEvent.VK_DECIMAL:
-      return 0xFFAE;
-
-    default:
-      System.err.println("Key is not mapped: " + order + ".");
-      return ' '; // Space
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtMouseEventToVncAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtMouseEventToVncAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtMouseEventToVncAdapter.java
deleted file mode 100644
index dd93394..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtMouseEventToVncAdapter.java
+++ /dev/null
@@ -1,71 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 vncclient;
-
-import java.awt.event.MouseEvent;
-
-import common.MouseOrder;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-public class AwtMouseEventToVncAdapter extends BaseElement {
-
-  public AwtMouseEventToVncAdapter(String id) {
-    super(id);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    // Get mouse event
-    MouseOrder order = (MouseOrder)buf.getOrder();
-
-    ByteBuffer outBuf = new ByteBuffer(6);
-
-    outBuf.writeByte(RfbConstants.CLIENT_POINTER_EVENT);
-
-    int buttonMask = mapAwtModifiersToVncButtonMask(order.event.getModifiersEx());
-    outBuf.writeByte(buttonMask);
-    outBuf.writeShort(order.event.getX());
-    outBuf.writeShort(order.event.getY());
-    
-    pushDataToAllOuts(outBuf);
-  }
-
-  /**
-   * Current state of buttons 1 to 8 are represented by bits 0 to 7 of
-   * button-mask respectively, 0 meaning up, 1 meaning down (pressed). On a
-   * conventional mouse, buttons 1, 2 and 3 correspond to the left, middle and
-   * right buttons on the mouse. On a wheel mouse, each step of the wheel
-   * upwards is represented by a press and release of button 4, and each step
-   * downwards is represented by a press and release of button 5.
-   * 
-   * @param modifiers
-   *          extended modifiers from AWT mouse event
-   * @return VNC mouse button mask
-   */
-  public static int mapAwtModifiersToVncButtonMask(int modifiers) {
-    int mask = (((modifiers & MouseEvent.BUTTON1_DOWN_MASK) != 0) ? 0x1 : 0) | (((modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0) ? 0x2 : 0)
-        | (((modifiers & MouseEvent.BUTTON3_DOWN_MASK) != 0) ? 0x4 : 0);
-    return mask;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/EncodingsMessage.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/EncodingsMessage.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/EncodingsMessage.java
deleted file mode 100644
index 9ee3566..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/EncodingsMessage.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 vncclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-public class EncodingsMessage extends BaseElement {
-
-  protected final int[] encodings;
-
-  public EncodingsMessage(String id, int[] encodings) {
-    super(id);
-    this.encodings = encodings;
-    declarePads();
-  }
-
-  protected void declarePads() {
-    inputPads.put(STDIN, null);
-    outputPads.put(STDOUT, null);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-    buf.unref();
-
-    ByteBuffer outBuf = new ByteBuffer(4 + encodings.length * 4);
-
-    outBuf.writeByte(RfbConstants.CLIENT_SET_ENCODINGS);
-
-    outBuf.writeByte(0);// padding
-
-    outBuf.writeShort(encodings.length);
-
-    for (int i = 0; i < encodings.length; i++) {
-      outBuf.writeInt(encodings[i]);
-    }
-
-    pushDataToAllOuts(outBuf);
-
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/FrameBufferUpdateRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/FrameBufferUpdateRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/FrameBufferUpdateRequest.java
deleted file mode 100644
index c8fab21..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/FrameBufferUpdateRequest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 vncclient;
-
-import common.ScreenDescription;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class FrameBufferUpdateRequest extends BaseElement {
-  // TODO: use object with fields instead of raw values in map
-  public static final String INCREMENTAL_UPDATE = "incremental";
-  public static final String TARGET_X = "x";
-  public static final String TARGET_Y = "y";
-  public static final String WIDTH = "width";
-  public static final String HEIGHT = "height";
-
-  protected ScreenDescription screen;
-
-  public FrameBufferUpdateRequest(String id, ScreenDescription screen) {
-    super(id);
-    this.screen = screen;
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    Boolean incremental = (Boolean) buf.getMetadata(INCREMENTAL_UPDATE);
-    Integer x = (Integer) buf.getMetadata(TARGET_X);
-    Integer y = (Integer) buf.getMetadata(TARGET_Y);
-    Integer width = (Integer) buf.getMetadata(WIDTH);
-    Integer height = (Integer) buf.getMetadata(HEIGHT);
-    buf.unref();
-
-    // Set default values when parameters are not set
-    if (incremental == null)
-      incremental = false;
-
-    if (x == null)
-      x = 0;
-    if (y == null)
-      y = 0;
-
-    if (width == null)
-      width = screen.getFramebufferWidth();
-    if (height == null)
-      height = screen.getFramebufferHeight();
-
-    ByteBuffer outBuf = new ByteBuffer(10);
-
-    outBuf.writeByte(RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST);
-    outBuf.writeByte((incremental) ? RfbConstants.FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST : RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST);
-    outBuf.writeShort(x);
-    outBuf.writeShort(y);
-    outBuf.writeShort(width);
-    outBuf.writeShort(height);
-
-    if (verbose) {
-      outBuf.putMetadata("sender", this);
-      outBuf.putMetadata("dimensions", width + "x" + height + "@" + x + "x" + y);
-    }
-
-    pushDataToAllOuts(outBuf);
-  }
-
-  public static void main(String args[]) {
-    System.setProperty("streamer.Element.debug", "true");
-
-    ScreenDescription screen = new ScreenDescription();
-    screen.setFramebufferSize(120, 80);
-    Element adapter = new FrameBufferUpdateRequest("renderer", screen);
-
-    Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
-        // Request
-        RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST,
-        // Full update (redraw area)
-        RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST,
-        // X
-        0, 1,
-        // Y
-        0, 2,
-        // Width
-        0, 3,
-        // Height
-        0, 4 }));
-
-    ByteBuffer buf = new ByteBuffer(new byte[0]);
-    buf.putMetadata(TARGET_X, 1);
-    buf.putMetadata(TARGET_Y, 2);
-    buf.putMetadata(WIDTH, 3);
-    buf.putMetadata(HEIGHT, 4);
-
-    Element source = new MockSource("source", new ByteBuffer[] { buf });
-
-    Pipeline pipeline = new PipelineImpl("test");
-
-    pipeline.addAndLink(source, adapter, sink);
-    pipeline.runMainLoop("source", STDOUT, false, false);
-
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RGB888LE32PixelFormatRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RGB888LE32PixelFormatRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RGB888LE32PixelFormatRequest.java
deleted file mode 100644
index 8c691e7..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RGB888LE32PixelFormatRequest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 vncclient;
-
-import common.ScreenDescription;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-public class RGB888LE32PixelFormatRequest extends BaseElement {
-  protected int bitsPerPixel = 32;
-  protected int depth = 24;
-  protected int bigEndianFlag = RfbConstants.LITTLE_ENDIAN;
-  protected int trueColourFlag = RfbConstants.TRUE_COLOR;
-  protected int redMax = 255;
-  protected int greenMax = 255;
-  protected int blueMax = 255;
-  protected int redShift = 0;
-  protected int greenShift = 8;
-  protected int blueShift = 16;
-
-  protected ScreenDescription screen;
-
-  public RGB888LE32PixelFormatRequest(String id, ScreenDescription screen) {
-    super(id);
-    this.screen = screen;
-  }
-
-  protected void declarePads() {
-    inputPads.put(STDIN, null);
-    outputPads.put(STDOUT, null);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-    buf.unref();
-
-    ByteBuffer outBuf = new ByteBuffer(20);
-
-    outBuf.writeByte(RfbConstants.CLIENT_SET_PIXEL_FORMAT);
-
-    // Padding
-    outBuf.writeByte(0);
-    outBuf.writeByte(0);
-    outBuf.writeByte(0);
-
-    // Send pixel format
-    outBuf.writeByte(bitsPerPixel);
-    outBuf.writeByte(depth);
-    outBuf.writeByte(bigEndianFlag);
-    outBuf.writeByte(trueColourFlag);
-    outBuf.writeShort(redMax);
-    outBuf.writeShort(greenMax);
-    outBuf.writeShort(blueMax);
-    outBuf.writeByte(redShift);
-    outBuf.writeByte(greenShift);
-    outBuf.writeByte(blueShift);
-
-    // Padding
-    outBuf.writeByte(0);
-    outBuf.writeByte(0);
-    outBuf.writeByte(0);
-
-    screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag != RfbConstants.LITTLE_ENDIAN, trueColourFlag == RfbConstants.TRUE_COLOR, redMax, greenMax,
-        blueMax, redShift, greenShift, blueShift);
-
-    pushDataToAllOuts(outBuf);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RfbConstants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RfbConstants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RfbConstants.java
deleted file mode 100644
index c2d63bb..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RfbConstants.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 vncclient;
-
-import java.nio.charset.Charset;
-
-public interface RfbConstants {
-
-  public static final String RFB_PROTOCOL_VERSION_MAJOR = "RFB 003.";
-  public static final String VNC_PROTOCOL_VERSION_MINOR = "003";
-  public static final String RFB_PROTOCOL_VERSION = RFB_PROTOCOL_VERSION_MAJOR + VNC_PROTOCOL_VERSION_MINOR;
-
-  /**
-   * Server message types.
-   */
-  final static int SERVER_FRAMEBUFFER_UPDATE = 0, SERVER_SET_COLOURMAP_ENTRIES = 1, SERVER_BELL = 2, SERVER_CUT_TEXT = 3;
-
-  /**
-   * Client message types.
-   */
-  public static final int CLIENT_SET_PIXEL_FORMAT = 0, CLIENT_FIX_COLOURMAP_ENTRIES = 1, CLIENT_SET_ENCODINGS = 2, CLIENT_FRAMEBUFFER_UPDATE_REQUEST = 3,
-      CLIENT_KEYBOARD_EVENT = 4, CLIENT_POINTER_EVENT = 5, CLIENT_CUT_TEXT = 6;
-
-  /**
-   * Server authorization type
-   */
-  public final static int CONNECTION_FAILED = 0, NO_AUTH = 1, VNC_AUTH = 2;
-
-  /**
-   * Server authorization reply.
-   */
-  public final static int VNC_AUTH_OK = 0, VNC_AUTH_FAILED = 1, VNC_AUTH_TOO_MANY = 2;
-
-  /**
-   * Encodings.
-   */
-  public final static int ENCODING_RAW = 0, ENCODING_COPY_RECT = 1, ENCODING_RRE = 2, ENCODING_CO_RRE = 4, ENCODING_HEXTILE = 5, ENCODING_ZRLE = 16;
-
-  /**
-   * Pseudo-encodings.
-   */
-  public final static int ENCODING_CURSOR = -239 /*0xFFFFFF11*/, ENCODING_DESKTOP_SIZE = -223 /*0xFFFFFF21*/;
-
-  /**
-   * Encodings, which we support.
-   */
-  public final static int[] SUPPORTED_ENCODINGS_ARRAY = { ENCODING_RAW, ENCODING_COPY_RECT, ENCODING_DESKTOP_SIZE };
-
-  /**
-   * Frame buffer update request type: update of whole screen or partial update.
-   */
-  public static final int FRAMEBUFFER_FULL_UPDATE_REQUEST = 0, FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST = 1;
-
-  public static final int KEY_UP = 0, KEY_DOWN = 1;
-
-  public static final int LITTLE_ENDIAN = 0, BIG_ENDIAN = 1;
-
-  public static final int EXCLUSIVE_ACCESS = 0, SHARED_ACCESS = 1;
-
-  public static final int PALETTE = 0, TRUE_COLOR = 1;
-
-  /**
-   * Default 8 bit charset to use when communicating with server.
-   */
-  public static final Charset US_ASCII_CHARSET = Charset.availableCharsets().get("US-ASCII");
-  
-  /**
-   * Default 16 bit charset to use when communicating with server.
-   */
-  public static final Charset UCS2_CHARSET = Charset.availableCharsets().get("UTF-16LE");
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncClient.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncClient.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncClient.java
old mode 100644
new mode 100755
index 2b77e0a..1e1a7e5
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncClient.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncClient.java
@@ -18,90 +18,99 @@ package vncclient;
 
 import streamer.PipelineImpl;
 import streamer.Queue;
-
-import common.AwtBellAdapter;
-import common.AwtCanvasAdapter;
-import common.AwtClipboardAdapter;
+import vncclient.adapter.AwtVncKeyboardAdapter;
+import vncclient.adapter.AwtVncMouseAdapter;
+import vncclient.vnc.EncodingsMessage;
+import vncclient.vnc.FrameBufferUpdateRequest;
+import vncclient.vnc.RGB888LE32PixelFormatRequest;
+import vncclient.vnc.RfbConstants;
+import vncclient.vnc.VncInitializer;
+import vncclient.vnc.VncMessageHandler;
+import vncclient.vnc.Vnc_3_3_Authentication;
+import vncclient.vnc.Vnc_3_3_Hello;
 import common.AwtKeyEventSource;
 import common.AwtMouseEventSource;
 import common.BufferedImageCanvas;
 import common.ScreenDescription;
+import common.adapter.AwtBellAdapter;
+import common.adapter.AwtCanvasAdapter;
+import common.adapter.AwtClipboardAdapter;
 
 public class VncClient extends PipelineImpl {
 
-  public VncClient(String id, String password, ScreenDescription screen, BufferedImageCanvas canvas) {
-    super(id);
-    assembleVNCPipeline(password, screen, canvas);
-  }
+    public VncClient(String id, String password, ScreenDescription screen, BufferedImageCanvas canvas) {
+        super(id);
+        assembleVNCPipeline(password, screen, canvas);
+    }
 
-  private void assembleVNCPipeline(String password, ScreenDescription screen, BufferedImageCanvas canvas) {
+    private void assembleVNCPipeline(String password, ScreenDescription screen, BufferedImageCanvas canvas) {
 
-    AwtMouseEventSource mouseEventSource = new AwtMouseEventSource("mouse");
-    AwtKeyEventSource keyEventSource = new AwtKeyEventSource("keyboard");
+        AwtMouseEventSource mouseEventSource = new AwtMouseEventSource("mouse");
+        AwtKeyEventSource keyEventSource = new AwtKeyEventSource("keyboard");
 
-    // Subscribe packet sender to various events
-    canvas.addMouseListener(mouseEventSource);
-    canvas.addMouseMotionListener(mouseEventSource);
-    canvas.addKeyListener(keyEventSource);
+        // Subscribe packet sender to various events
+        canvas.addMouseListener(mouseEventSource);
+        canvas.addMouseMotionListener(mouseEventSource);
+        canvas.addKeyListener(keyEventSource);
 
-    add(
-    // Handshake
+        add(
+                // Handshake
 
-    // RFB protocol version exchanger
-    new Vnc_3_3_Hello("hello"),
-    // Authenticator
-        new Vnc_3_3_Authentication("auth", password),
-        // Initializer
-        new VncInitializer("init", true, screen),
+                // RFB protocol version exchanger
+                new Vnc_3_3_Hello("hello"),
+                // Authenticator
+                new Vnc_3_3_Authentication("auth", password),
+                // Initializer
+                new VncInitializer("init", true, screen),
 
-        new EncodingsMessage("encodings", RfbConstants.SUPPORTED_ENCODINGS_ARRAY),
+                new EncodingsMessage("encodings", RfbConstants.SUPPORTED_ENCODINGS_ARRAY),
 
-        new RGB888LE32PixelFormatRequest("pixel_format", screen),
+                new RGB888LE32PixelFormatRequest("pixel_format", screen),
 
-        // Main
+                // Main
 
-        // Packet receiver
-        new VncMessageHandler("message_handler", screen),
+                // Packet receiver
+                new VncMessageHandler("message_handler", screen),
 
-        new AwtBellAdapter("bell"),
+                new AwtBellAdapter("bell"),
 
-        new AwtClipboardAdapter("clipboard"),
+                new AwtClipboardAdapter("clipboard"),
 
-        new AwtCanvasAdapter("pixels", canvas, screen),
+                new AwtCanvasAdapter("pixels", canvas, screen),
 
-        new Queue("queue"),
+                new Queue("queue"),
 
-        new FrameBufferUpdateRequest("fbur", screen),
+                new FrameBufferUpdateRequest("fbur", screen),
 
-        new AwtKeyboardEventToVncAdapter("keyboard_adapter"),
+                new AwtVncKeyboardAdapter("keyboard_adapter"),
 
-        new AwtMouseEventToVncAdapter("mouse_adapter"),
+                new AwtVncMouseAdapter("mouse_adapter"),
 
-        mouseEventSource, keyEventSource
+                mouseEventSource, keyEventSource
 
-    );
+        );
 
-    // Link handshake elements
-    link("IN", "hello", "auth", "init", "message_handler");
-    link("hello >otout", "hello< OUT");
-    link("auth >otout", "auth< OUT");
-    link("init >otout", "init< OUT");
-    link("init >encodings", "encodings");
-    link("init >pixel_format", "pixel_format");
-    link("encodings", "encodings< OUT");
-    link("pixel_format", "pixel_format< OUT");
+        // Link handshake elements
+        link("IN", "hello", "auth", "init", "message_handler");
+        link("hello >otout", "hello< OUT");
+        link("auth >otout", "auth< OUT");
+        link("init >otout", "init< OUT");
+        link("init >encodings", "encodings");
+        link("init >pixel_format", "pixel_format");
+        link("encodings", "encodings< OUT");
+        link("pixel_format", "pixel_format< OUT");
 
-    // Link main elements
-    link("message_handler >bell", "bell");
-    link("message_handler >clipboard", "clipboard");
-    link("message_handler >pixels", "pixels");
-    link("message_handler >fbur", "fbur");
+        // Link main elements
+        link("message_handler >bell", "bell");
+        link("message_handler >clipboard", "clipboard");
+        link("message_handler >pixels", "pixels");
+        link("message_handler >fbur", "fbur");
 
-    link("fbur", "fbur< queue");
-    link("keyboard", "keyboard_adapter", "keyboard< queue");
-    link("mouse", "mouse_adapter", "mouse< queue");
-    link("queue", "OUT");
+        link("fbur", "fbur< queue");
+        link("keyboard", "keyboard_adapter", "keyboard< queue");
+        link("mouse", "mouse_adapter", "mouse< queue");
+        link("queue", "OUT");
 
-  }
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java
deleted file mode 100644
index 0882d13..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java
+++ /dev/null
@@ -1,244 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 vncclient;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-import common.ScreenDescription;
-
-public class VncInitializer extends OneTimeSwitch {
-
-  // Pad names
-  public static final String CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD = "encodings";
-  public static final String CLIENT_PIXEL_FORMAT_ADAPTER_PAD = "pixel_format";
-
-  protected byte sharedFlag = RfbConstants.EXCLUSIVE_ACCESS;
-
-  /**
-   * Properties of remote screen .
-   */
-  protected ScreenDescription screen;
-
-  public VncInitializer(String id, boolean shared, ScreenDescription screen) {
-    super(id);
-
-    setSharedFlag(shared);
-    this.screen = screen;
-
-    declarePads();
-  }
-
-  @Override
-  protected void declarePads() {
-    super.declarePads();
-    outputPads.put(CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, null);
-    outputPads.put(CLIENT_PIXEL_FORMAT_ADAPTER_PAD, null);
-  }
-
-  public ScreenDescription getScreen() {
-    return screen;
-  }
-
-  public void setScreen(ScreenDescription screen) {
-    this.screen = screen;
-  }
-
-  public void setSharedFlag(boolean shared) {
-    if (shared)
-      sharedFlag = RfbConstants.SHARED_ACCESS;
-    else
-      sharedFlag = RfbConstants.EXCLUSIVE_ACCESS;
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    // Server initialization message is at least 24 bytes long + length of
-    // desktop name
-    if (!cap(buf, 24, UNLIMITED, link, false))
-      return;
-
-    // Read server initialization message
-    // Read frame buffer size
-    int framebufferWidth = buf.readUnsignedShort();
-    int framebufferHeight = buf.readUnsignedShort();
-
-    // Read pixel format
-    int bitsPerPixel = buf.readUnsignedByte();
-    int depth = buf.readUnsignedByte();
-
-    int bigEndianFlag = buf.readUnsignedByte();
-    int trueColorFlag = buf.readUnsignedByte();
-
-    int redMax = buf.readUnsignedShort();
-    int greenMax = buf.readUnsignedShort();
-    int blueMax = buf.readUnsignedShort();
-
-    int redShift = buf.readUnsignedByte();
-    int greenShift = buf.readUnsignedByte();
-    int blueShift = buf.readUnsignedByte();
-
-    // Skip padding
-    buf.skipBytes(3);
-
-    // Read desktop name
-    int length = buf.readSignedInt();
-
-    // Consume exactly $length bytes, push back any extra bytes
-    if (!cap(buf, length, length, link, true))
-      return;
-
-    String desktopName = buf.readString(length, RfbConstants.US_ASCII_CHARSET);
-    buf.unref();
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Desktop name: \"" + desktopName + "\", bpp: " + bitsPerPixel + ", depth: " + depth + ", screen size: "
-          + framebufferWidth + "x" + framebufferHeight + ".");
-
-    // Set screen properties
-    screen.setFramebufferSize(framebufferWidth, framebufferHeight);
-    screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag!=RfbConstants.LITTLE_ENDIAN, trueColorFlag==RfbConstants.TRUE_COLOR, redMax, greenMax, blueMax, redShift, greenShift, blueShift);
-    screen.setDesktopName(desktopName);
-
-    // If sever screen has different parameters than ours, then change it
-    if (!screen.isRGB888_32_LE()) {
-      // Send client pixel format
-      sendClientPixelFormat();
-    }
-
-    // Send encodings supported by client
-    sendSupportedEncodings();
-
-    switchOff();
-
-  }
-
-  @Override
-  protected void onStart() {
-    ByteBuffer buf = new ByteBuffer(new byte[] { sharedFlag });
-    pushDataToOTOut(buf);
-  }
-
-  private void sendClientPixelFormat() {
-    pushDataToPad(CLIENT_PIXEL_FORMAT_ADAPTER_PAD, new ByteBuffer(0));
-  }
-
-  private void sendSupportedEncodings() {
-    pushDataToPad(CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, new ByteBuffer(0));
-  }
-
-  public String toString() {
-    return "VncInit(" + id + ")";
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    final String desktopName = "test";
-
-    Element source = new MockSource("source") {
-      {
-        bufs = ByteBuffer.convertByteArraysToByteBuffers(
-        // Send screen description
-            new byte[] {
-                // Framebuffer width (short)
-                0, (byte) 200,
-                // Framebuffer height (short)
-                0, 100,
-                // Bits per pixel
-                32,
-                // Depth,
-                24,
-                // Endianness flag
-                RfbConstants.LITTLE_ENDIAN,
-                // Truecolor flag
-                RfbConstants.TRUE_COLOR,
-                // Red max (short)
-                0, (byte) 255,
-                // Green max (short)
-                0, (byte) 255,
-                // Blue max (short)
-                0, (byte) 255,
-                // Red shift
-                16,
-                // Green shift
-                8,
-                // Blue shift
-                0,
-                // Padding
-                0, 0, 0,
-                // Desktop name length (int)
-                0, 0, 0, 4,
-                // Desktop name ("test", 4 bytes)
-                't', 'e', 's', 't',
-
-                // Tail
-                1, 2, 3
-
-            },
-            // Tail packet
-            new byte[] { 4, 5, 6 });
-      }
-    };
-
-    ScreenDescription screen = new ScreenDescription();
-    final VncInitializer init = new VncInitializer("init", true, screen);
-    Element initSink = new MockSink("initSink") {
-      {
-        // Expect shared flag
-        bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] { RfbConstants.SHARED_ACCESS });
-      }
-    };
-    Element mainSink = new MockSink("mainSink") {
-      {
-        // Expect two tail packets
-        bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }, new byte[] { 4, 5, 6 });
-      }
-    };
-    ByteBuffer[] emptyBuf = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {});
-    Element encodingsSink = new MockSink("encodings", emptyBuf);
-    Element pixelFormatSink = new MockSink("pixel_format", emptyBuf);
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.addAndLink(source, init, mainSink);
-    pipeline.add(encodingsSink, pixelFormatSink, initSink);
-    pipeline.link("init >otout", "initSink");
-    pipeline.link("init >" + CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, "encodings");
-    pipeline.link("init >" + CLIENT_PIXEL_FORMAT_ADAPTER_PAD, "pixel_format");
-
-    pipeline.runMainLoop("source", STDOUT, false, false);
-
-    if (!screen.isRGB888_32_LE())
-      System.err.println("Screen description was read incorrectly: " + screen + ".");
-    if (!desktopName.equals(screen.getDesktopName()))
-      System.err.println("Screen desktop name was read incorrectly: \"" + screen.getDesktopName() + "\".");
-
-  }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java
deleted file mode 100644
index 758000d..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java
+++ /dev/null
@@ -1,419 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 vncclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-import common.BitmapOrder;
-import common.BitmapRectangle;
-import common.CopyRectOrder;
-import common.ScreenDescription;
-
-public class VncMessageHandler extends BaseElement {
-  protected ScreenDescription screen = null;
-
-  // Pad names
-  public static final String SERVER_BELL_ADAPTER_PAD = "bell";
-  public static final String SERVER_CLIPBOARD_ADAPTER_PAD = "clipboard";
-  public static final String PIXEL_ADAPTER_PAD = "pixels";
-  public static final String FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD = "fbur";
-
-  // Keys for metadata
-  public static final String CLIPBOARD_CONTENT = "content";
-  public static final String TARGET_X = "x";
-  public static final String TARGET_Y = "y";
-  public static final String WIDTH = "width";
-  public static final String HEIGHT = "height";
-  public static final String SOURCE_X = "srcX";
-  public static final String SOURCE_Y = "srcY";
-  public static final String PIXEL_FORMAT = "pixel_format";
-
-  private static final String NUM_OF_PROCESSED_RECTANGLES = "rects";
-  private static final String SAVED_CURSOR_POSITION = "cursor";
-
-  // Pixel format: RGB888 LE 32
-  public static final String RGB888LE32 = "RGB888LE32";
-
-  public VncMessageHandler(String id, ScreenDescription screen) {
-    super(id);
-    this.screen = screen;
-    declarePads();
-  }
-
-  private void declarePads() {
-    outputPads.put(SERVER_BELL_ADAPTER_PAD, null);
-    outputPads.put(SERVER_BELL_ADAPTER_PAD, null);
-    outputPads.put(SERVER_CLIPBOARD_ADAPTER_PAD, null);
-    outputPads.put(PIXEL_ADAPTER_PAD, null);
-    outputPads.put(FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, null);
-
-    inputPads.put("stdin", null);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    try {
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-      if (!cap(buf, 1, UNLIMITED, link, false))
-        return;
-
-      // Read server message type
-      int messageType = buf.readUnsignedByte();
-
-      // Invoke packet handler by packet type.
-      switch (messageType) {
-
-      case RfbConstants.SERVER_FRAMEBUFFER_UPDATE: {
-        // Handle frame buffer update
-        if (!handleFBU(buf, link))
-          return;
-
-        // Frame buffer update is received and fully processed, send request for
-        // another frame buffer update to server.
-        sendFBUR();
-
-        break;
-      }
-
-      case RfbConstants.SERVER_BELL: {
-        if (!handleBell(buf, link))
-          return;
-        break;
-      }
-
-      case RfbConstants.SERVER_CUT_TEXT: {
-        if (!handleClipboard(buf, link))
-          return;
-        break;
-      }
-
-      default:
-        // TODO: allow to extend functionality
-        throw new RuntimeException("Unknown server packet type: " + messageType + ".");
-      }
-
-      // Cut tail, if any
-      cap(buf, 0, 0, link, true);
-    } finally {
-
-      // Return processed buffer back to pool
-      buf.unref();
-    }
-  }
-
-  private boolean handleClipboard(ByteBuffer buf, Link link) {
-    if (!cap(buf, 3 + 4, UNLIMITED, link, true))
-      return false;
-
-    // Skip padding
-    buf.skipBytes(3);
-
-    // Read text length
-    int length = buf.readSignedInt();
-
-    // We need full string to parse it
-    if (!cap(buf, length, UNLIMITED, link, true))
-      return false;
-
-    String content = buf.readString(length, RfbConstants.US_ASCII_CHARSET);
-
-    // Send content in metadata
-    ByteBuffer outBuf = new ByteBuffer(0);
-    outBuf.putMetadata(CLIPBOARD_CONTENT, content);
-
-    pushDataToPad(SERVER_CLIPBOARD_ADAPTER_PAD, outBuf);
-
-    return true;
-  }
-
-  private boolean handleBell(ByteBuffer buf, Link link) {
-    // Send empty packet to bell adapter to produce bell
-    pushDataToPad(SERVER_BELL_ADAPTER_PAD, new ByteBuffer(0));
-
-    return true;
-  }
-
-  // FIXME: this method is too complex
-  private boolean handleFBU(ByteBuffer buf, Link link) {
-
-    // We need at least 3 bytes here, 1 - padding, 2 - number of rectangles
-    if (!cap(buf, 3, UNLIMITED, link, true))
-      return false;
-
-    buf.skipBytes(1);// Skip padding
-
-    // Read number of rectangles
-    int numberOfRectangles = buf.readUnsignedShort();
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Frame buffer update. Number of rectangles: " + numberOfRectangles + ".");
-
-    // Each rectangle must have header at least, header length is 12 bytes.
-    if (!cap(buf, 12 * numberOfRectangles, UNLIMITED, link, true))
-      return false;
-
-    // For all rectangles
-
-    // Restore saved point, to avoid flickering and performance problems when
-    // frame buffer update is split between few incoming packets.
-    int numberOfProcessedRectangles = (buf.getMetadata(NUM_OF_PROCESSED_RECTANGLES) != null) ? (Integer) buf.getMetadata(NUM_OF_PROCESSED_RECTANGLES) : 0;
-    if (buf.getMetadata(SAVED_CURSOR_POSITION) != null)
-      buf.cursor = (Integer) buf.getMetadata(SAVED_CURSOR_POSITION);
-
-    if (verbose && numberOfProcessedRectangles > 0)
-      System.out.println("[" + this + "] INFO: Restarting from saved point. Number of already processed rectangles: " + numberOfRectangles + ", cursor: "
-          + buf.cursor + ".");
-
-    // For all new rectangles
-    for (int i = numberOfProcessedRectangles; i < numberOfRectangles; i++) {
-
-      // We need coordinates of rectangle (2x4 bytes) and encoding type (4
-      // bytes)
-      if (!cap(buf, 12, UNLIMITED, link, true))
-        return false;
-
-      // Read coordinates of rectangle
-      int x = buf.readUnsignedShort();
-      int y = buf.readUnsignedShort();
-      int width = buf.readUnsignedShort();
-      int height = buf.readUnsignedShort();
-
-      // Read rectangle encoding
-      int encodingType = buf.readSignedInt();
-
-      // Process rectangle
-      switch (encodingType) {
-
-      case RfbConstants.ENCODING_RAW: {
-        if (!handleRawRectangle(buf, link, x, y, width, height))
-          return false;
-        break;
-      }
-
-      case RfbConstants.ENCODING_COPY_RECT: {
-        if (!handleCopyRect(buf, link, x, y, width, height))
-          return false;
-        break;
-      }
-
-      case RfbConstants.ENCODING_DESKTOP_SIZE: {
-        if (!handleScreenSizeChangeRect(buf, link, x, y, width, height))
-          return false;
-        break;
-      }
-
-      default:
-        // TODO: allow to extend functionality
-        throw new RuntimeException("Unsupported ecnoding: " + encodingType + ".");
-      }
-
-      // Update information about processed rectangles to avoid handling of same
-      // rectangle multiple times.
-      // TODO: push back partial rectangle only instead
-      buf.putMetadata(NUM_OF_PROCESSED_RECTANGLES, ++numberOfProcessedRectangles);
-      buf.putMetadata(SAVED_CURSOR_POSITION, buf.cursor);
-    }
-
-    return true;
-  }
-
-  private boolean handleScreenSizeChangeRect(ByteBuffer buf, Link link, int x, int y, int width, int height) {
-    // Remote screen size is changed
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Screen size rect. Width: " + width + ", height: " + height + ".");
-
-    screen.setFramebufferSize(width, height);
-
-    return true;
-  }
-
-  private boolean handleCopyRect(ByteBuffer buf, Link link, int x, int y, int width, int height) {
-    // Copy rectangle from one part of screen to another.
-    // Areas may overlap. Antialiasing may cause visible artifacts.
-
-    // We need 4 bytes with coordinates of source rectangle
-    if (!cap(buf, 4, UNLIMITED, link, true))
-      return false;
-
-    CopyRectOrder order = new CopyRectOrder();
-
-    order.srcX = buf.readUnsignedShort();
-    order.srcY = buf.readUnsignedShort();
-    order.x = x;
-    order.y = y;
-    order.width = width;
-    order.height = height;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Copy rect. X: " + x + ", y: " + y + ", width: " + width + ", height: " + height + ", srcX: " + order.srcX
-          + ", srcY: " + order.srcY + ".");
-
-    pushDataToPad(PIXEL_ADAPTER_PAD, new ByteBuffer(order));
-
-    return true;
-  }
-
-  private boolean handleRawRectangle(ByteBuffer buf, Link link, int x, int y, int width, int height) {
-    // Raw rectangle is just array of pixels to draw on screen.
-    int rectDataLength = width * height * screen.getBytesPerPixel();
-
-    // We need at least rectDataLength bytes. Extra bytes may contain other
-    // rectangles.
-    if (!cap(buf, rectDataLength, UNLIMITED, link, true))
-      return false;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Raw rect. X: " + x + ", y: " + y + ", width: " + width + ", height: " + height + ", data length: "
-          + rectDataLength + ".");
-
-    BitmapRectangle rectangle = new BitmapRectangle();
-    rectangle.x = x;
-    rectangle.y = y;
-    rectangle.width = width;
-    rectangle.height = height;
-    rectangle.bufferWidth = width;
-    rectangle.bufferHeight = height;
-    rectangle.bitmapDataStream = buf.readBytes(rectDataLength);
-    rectangle.colorDepth=screen.getColorDeph();
-
-    BitmapOrder order = new BitmapOrder();
-    order.rectangles = new BitmapRectangle[] { rectangle };
-    
-    pushDataToPad(PIXEL_ADAPTER_PAD, new ByteBuffer(order));
-    return true;
-  }
-
-  public void onStart() {
-    // Send Frame Buffer Update request
-    sendFBUR();
-  }
-
-  private void sendFBUR() {
-    ByteBuffer buf = new ByteBuffer(0);
-    buf.putMetadata("incremental", true);
-    pushDataToPad(FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, buf);
-  }
-
-  public String toString() {
-    return "VNCMessageHandler(" + id + ")";
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String[] args) {
-
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    Element source = new MockSource("source") {
-      {
-        // Split messages at random boundaries to check "pushback" logic
-        bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
-            // Message type: server bell
-            RfbConstants.SERVER_BELL,
-
-            // Message type: clipboard text
-            RfbConstants.SERVER_CUT_TEXT,
-            // Padding
-            0, 0, 0,
-            // Length (test)
-            0, 0, 0, 4,
-
-        }, new byte[] {
-            // Clipboard text
-            't', 'e', 's', 't',
-
-            // Message type: frame buffer update
-            RfbConstants.SERVER_FRAMEBUFFER_UPDATE,
-            // Padding
-            0,
-            // Number of rectangles
-            0, 3, },
-
-        new byte[] {
-
-            // x, y, width, height: 0x0@4x4
-            0, 0, 0, 0, 0, 4, 0, 4,
-            // Encoding: desktop size
-            (byte) ((RfbConstants.ENCODING_DESKTOP_SIZE >> 24) & 0xff), (byte) ((RfbConstants.ENCODING_DESKTOP_SIZE >> 16) & 0xff),
-            (byte) ((RfbConstants.ENCODING_DESKTOP_SIZE >> 8) & 0xff), (byte) ((RfbConstants.ENCODING_DESKTOP_SIZE >> 0) & 0xff), },
-
-        new byte[] {
-
-            // x, y, width, height: 0x0@4x4
-            0, 0, 0, 0, 0, 4, 0, 4,
-            // Encoding: raw rect
-            (byte) ((RfbConstants.ENCODING_RAW >> 24) & 0xff), (byte) ((RfbConstants.ENCODING_RAW >> 16) & 0xff),
-            (byte) ((RfbConstants.ENCODING_RAW >> 8) & 0xff), (byte) ((RfbConstants.ENCODING_RAW >> 0) & 0xff),
-            // Raw pixel data 4x4x1 bpp
-            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, }, new byte[] { 11, 12, 13, 14, 15, 16,
-
-            // x, y, width, height: 0x0@2x2
-            0, 0, 0, 0, 0, 2, 0, 2,
-            // Encoding: copy rect
-            (byte) ((RfbConstants.ENCODING_COPY_RECT >> 24) & 0xff), (byte) ((RfbConstants.ENCODING_COPY_RECT >> 16) & 0xff),
-            (byte) ((RfbConstants.ENCODING_COPY_RECT >> 8) & 0xff), (byte) ((RfbConstants.ENCODING_COPY_RECT >> 0) & 0xff),
-            // srcX, srcY: 2x2
-            0, 2, 0, 2, });
-      }
-    };
-
-    ScreenDescription screen = new ScreenDescription() {
-      {
-        this.bytesPerPixel = 1;
-      }
-    };
-
-    final Element handler = new VncMessageHandler("handler", screen);
-
-    ByteBuffer[] emptyBuf = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {});
-    Element fburSink = new MockSink("fbur", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {}, new byte[] {}));
-    Element bellSink = new MockSink("bell", emptyBuf);
-    Element clipboardSink = new MockSink("clipboard", emptyBuf);
-    Element desktopSizeChangeSink = new MockSink("desktop_size", emptyBuf);
-    Element pixelsSink = new MockSink("pixels",
-        ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, }));
-    Element copyRectSink = new MockSink("copy_rect", emptyBuf);
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.addAndLink(source, handler);
-    pipeline.add(fburSink, bellSink, clipboardSink, desktopSizeChangeSink, pixelsSink, copyRectSink);
-
-    pipeline.link("handler >" + FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, "fbur");
-    pipeline.link("handler >" + SERVER_BELL_ADAPTER_PAD, "bell");
-    pipeline.link("handler >" + SERVER_CLIPBOARD_ADAPTER_PAD, "clipboard");
-    pipeline.link("handler >" + PIXEL_ADAPTER_PAD, "pixels");
-
-    pipeline.runMainLoop("source", STDOUT, false, false);
-
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc_3_3_Authentication.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc_3_3_Authentication.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc_3_3_Authentication.java
deleted file mode 100644
index 52d9976..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc_3_3_Authentication.java
+++ /dev/null
@@ -1,291 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 vncclient;
-
-import java.security.spec.KeySpec;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.DESKeySpec;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.FakeSink;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class Vnc_3_3_Authentication extends OneTimeSwitch {
-
-  /**
-   * Password to use when authentication is required.
-   */
-  protected String password = null;
-
-  /**
-   * Authentication stage:
-   * <ul>
-   * <li>0 - challenge received, response must be sent
-   * <li>1 - authentication result received.
-   * </ul>
-   */
-  protected int stage = 0;
-
-  public Vnc_3_3_Authentication(String id) {
-    super(id);
-  }
-
-  public Vnc_3_3_Authentication(String id, String password) {
-    super(id);
-    this.password = password;
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    switch (stage) {
-    case 0: // Read security with optional challenge and response
-      stage0(buf, link);
-
-      break;
-    case 1: // Read authentication response
-      stage1(buf, link);
-      break;
-    }
-
-  }
-
-  /**
-   * Read security type. If connection type is @see
-   * RfbConstants.CONNECTION_FAILED, then throw exception. If connection type is @see
-   * RfbConstants.NO_AUTH, then switch off this element. If connection type is @see
-   * RfbConstants.VNC_AUTH, then read challenge, send encoded password, and read
-   * authentication response.
-   */
-  private void stage0(ByteBuffer buf, Link link) {
-    // At least 4 bytes are necessary
-    if (!cap(buf, 4, UNLIMITED, link, true))
-      return;
-
-    // Read security type
-    int authType = buf.readSignedInt();
-
-    switch (authType) {
-    case RfbConstants.CONNECTION_FAILED: {
-      // Server forbids to connect. Read reason and throw exception
-
-      int length = buf.readSignedInt();
-      String reason = new String(buf.data, buf.offset, length, RfbConstants.US_ASCII_CHARSET);
-
-      throw new RuntimeException("Authentication to VNC server is failed. Reason: " + reason);
-    }
-
-    case RfbConstants.NO_AUTH: {
-      // Client can connect without authorization. Nothing to do.
-      // Switch off this element from circuit
-      switchOff();
-      break;
-    }
-
-    case RfbConstants.VNC_AUTH: {
-      // Read challenge and generate response
-      responseToChallenge(buf, link);
-      break;
-    }
-
-    default:
-      throw new RuntimeException("Unsupported VNC protocol authorization scheme, scheme code: " + authType + ".");
-    }
-
-  }
-
-  private void responseToChallenge(ByteBuffer buf, Link link) {
-    // Challenge is exactly 16 bytes long
-    if (!cap(buf, 16, 16, link, true))
-      return;
-
-    ByteBuffer challenge = buf.slice(buf.cursor, 16, true);
-    buf.unref();
-
-    // Encode challenge with password
-    ByteBuffer response;
-    try {
-      response = encodePassword(challenge, password);
-      challenge.unref();
-    } catch (Exception e) {
-      throw new RuntimeException("Cannot encrypt client password to send to server: " + e.getMessage());
-    }
-
-    if (verbose) {
-      response.putMetadata("sender", this);
-    }
-
-    // Send encoded challenge
-    nextStage();
-    pushDataToOTOut(response);
-
-  }
-
-  private void nextStage() {
-    stage++;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Next stage: " + stage + ".");
-  }
-
-  /**
-   * Encode password using DES encryption with given challenge.
-   * 
-   * @param challenge
-   *          a random set of bytes.
-   * @param password
-   *          a password
-   * @return DES hash of password and challenge
-   */
-  public ByteBuffer encodePassword(ByteBuffer challenge, String password) {
-    if (challenge.length != 16)
-      throw new RuntimeException("Challenge must be exactly 16 bytes long.");
-
-    // VNC password consist of up to eight ASCII characters.
-    byte[] key = { 0, 0, 0, 0, 0, 0, 0, 0 }; // Padding
-    byte[] passwordAsciiBytes = password.getBytes(RfbConstants.US_ASCII_CHARSET);
-    System.arraycopy(passwordAsciiBytes, 0, key, 0, Math.min(password.length(), 8));
-
-    // Flip bytes (reverse bits) in key
-    for (int i = 0; i < key.length; i++) {
-      key[i] = flipByte(key[i]);
-    }
-
-    try {
-      KeySpec desKeySpec = new DESKeySpec(key);
-      SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
-      SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
-      Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
-      cipher.init(Cipher.ENCRYPT_MODE, secretKey);
-
-      ByteBuffer buf = new ByteBuffer(cipher.doFinal(challenge.data, challenge.offset, challenge.length));
-
-      return buf;
-    } catch (Exception e) {
-      throw new RuntimeException("Cannot encode password.", e);
-    }
-  }
-
-  /**
-   * Reverse bits in byte, so least significant bit will be most significant
-   * bit. E.g. 01001100 will become 00110010.
-   * 
-   * See also: http://www.vidarholen.net/contents/junk/vnc.html ,
-   * http://bytecrafter .blogspot.com/2010/09/des-encryption-as-used-in-vnc.html
-   * 
-   * @param b
-   *          a byte
-   * @return byte in reverse order
-   */
-  private static byte flipByte(byte b) {
-    int b1_8 = (b & 0x1) << 7;
-    int b2_7 = (b & 0x2) << 5;
-    int b3_6 = (b & 0x4) << 3;
-    int b4_5 = (b & 0x8) << 1;
-    int b5_4 = (b & 0x10) >>> 1;
-    int b6_3 = (b & 0x20) >>> 3;
-    int b7_2 = (b & 0x40) >>> 5;
-    int b8_1 = (b & 0x80) >>> 7;
-    byte c = (byte) (b1_8 | b2_7 | b3_6 | b4_5 | b5_4 | b6_3 | b7_2 | b8_1);
-    return c;
-  }
-
-  /**
-   * Read authentication result, send nothing.
-   */
-  private void stage1(ByteBuffer buf, Link link) {
-    // Read authentication response
-    if (!cap(buf, 4, 4, link, false))
-      return;
-
-    int authResult = buf.readSignedInt();
-
-    switch (authResult) {
-    case RfbConstants.VNC_AUTH_OK: {
-      // Nothing to do
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Authentication successfull.");
-      break;
-    }
-
-    case RfbConstants.VNC_AUTH_TOO_MANY:
-      throw new RuntimeException("Connection to VNC server failed: too many wrong attempts.");
-
-    case RfbConstants.VNC_AUTH_FAILED:
-      throw new RuntimeException("Connection to VNC server failed: wrong password.");
-
-    default:
-      throw new RuntimeException("Connection to VNC server failed, reason code: " + authResult);
-    }
-
-    switchOff();
-
-  }
-
-  public String toString() {
-    return "VNC3.3 Authentication(" + id + ")";
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    final String password = "test";
-
-    Element source = new MockSource("source") {
-      {
-        bufs = ByteBuffer.convertByteArraysToByteBuffers(
-        // Request authentication and send 16 byte challenge
-            new byte[] { 0, 0, 0, RfbConstants.VNC_AUTH, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
-            // Respond to challenge with AUTH_OK
-            new byte[] { 0, 0, 0, RfbConstants.VNC_AUTH_OK });
-      }
-    };
-
-    Element mainSink = new FakeSink("mainSink");
-    final Vnc_3_3_Authentication auth = new Vnc_3_3_Authentication("auth", password);
-    Element initSink = new MockSink("initSink") {
-      {
-        // Expect encoded password
-        bufs = new ByteBuffer[] { auth.encodePassword(new ByteBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }), password) };
-      }
-    };
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.addAndLink(source, auth, mainSink);
-    pipeline.add(initSink);
-    pipeline.link("auth >otout", "initSink");
-
-    pipeline.runMainLoop("source", STDOUT, false, false);
-
-  }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc_3_3_Hello.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc_3_3_Hello.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc_3_3_Hello.java
deleted file mode 100644
index 323380b..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc_3_3_Hello.java
+++ /dev/null
@@ -1,115 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 vncclient;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-
-import streamer.ByteBuffer;
-import streamer.InputStreamSource;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-import streamer.OutputStreamSink;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * VNC server sends hello packet with RFB protocol version, e.g.
- * "RFB 003.007\n". We need to send response packet with supported protocol
- * version, e.g. "RFB 003.003\n".
- */
-public class Vnc_3_3_Hello extends OneTimeSwitch {
-
-  public Vnc_3_3_Hello(String id) {
-    super(id);
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    // Initial packet is exactly 12 bytes long
-    if (!cap(buf, 12, 12, link, false))
-      return;
-
-    // Read protocol version
-    String rfbProtocol = new String(buf.data, buf.offset, buf.length, RfbConstants.US_ASCII_CHARSET);
-    buf.unref();
-
-    // Server should use RFB protocol 3.x
-    if (!rfbProtocol.contains(RfbConstants.RFB_PROTOCOL_VERSION_MAJOR))
-      throw new RuntimeException("Cannot handshake with VNC server. Unsupported protocol version: \"" + rfbProtocol + "\".");
-
-    // Send response: we support RFB 3.3 only
-    String ourProtocolString = RfbConstants.RFB_PROTOCOL_VERSION + "\n";
-
-    ByteBuffer outBuf = new ByteBuffer(ourProtocolString.getBytes(RfbConstants.US_ASCII_CHARSET));
-
-    if (verbose) {
-      outBuf.putMetadata("sender", this);
-      outBuf.putMetadata("version", RfbConstants.RFB_PROTOCOL_VERSION);
-    }
-
-    pushDataToOTOut(outBuf);
-
-    // Switch off this element from circuit
-    switchOff();
-
-  }
-
-  public String toString() {
-    return "Vnc3.3 Hello(" + id + ")";
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    InputStream is = new ByteArrayInputStream("RFB 003.007\ntest".getBytes(RfbConstants.US_ASCII_CHARSET));
-    ByteArrayOutputStream initOS = new ByteArrayOutputStream();
-    ByteArrayOutputStream mainOS = new ByteArrayOutputStream();
-    InputStreamSource inputStreamSource = new InputStreamSource("source", is);
-    OutputStreamSink outputStreamSink = new OutputStreamSink("mainSink", mainOS);
-
-    Vnc_3_3_Hello hello = new Vnc_3_3_Hello("hello");
-
-    Pipeline pipeline = new PipelineImpl("test");
-
-    pipeline.addAndLink(inputStreamSource, hello, outputStreamSink);
-    pipeline.add(new OutputStreamSink("initSink", initOS));
-
-    pipeline.link("hello >" + OneTimeSwitch.OTOUT, "initSink");
-
-    pipeline.runMainLoop("source", STDOUT, false, false);
-
-    String initOut = new String(initOS.toByteArray(), RfbConstants.US_ASCII_CHARSET);
-    String mainOut = new String(mainOS.toByteArray(), RfbConstants.US_ASCII_CHARSET);
-
-    if (!"RFB 003.003\n".equals(initOut))
-      System.err.println("Unexpected value for hello response: \"" + initOut + "\".");
-
-    if (!"test".equals(mainOut))
-      System.err.println("Unexpected value for main data: \"" + mainOut + "\".");
-
-  }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java
new file mode 100755
index 0000000..4c309cf
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java
@@ -0,0 +1,370 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 vncclient.adapter;
+
+import java.awt.event.KeyEvent;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+import vncclient.vnc.RfbConstants;
+
+import common.KeyOrder;
+
+public class AwtVncKeyboardAdapter extends BaseElement {
+
+    protected boolean sh = false;
+    protected boolean caps = false;
+    protected boolean num = false;
+
+    public AwtVncKeyboardAdapter(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        KeyOrder order = (KeyOrder)buf.getOrder();
+        buf.unref();
+
+        ByteBuffer outBuf = new ByteBuffer(8);
+        outBuf.writeByte(RfbConstants.CLIENT_KEYBOARD_EVENT);
+
+        outBuf.writeByte((order.pressed) ? RfbConstants.KEY_DOWN : RfbConstants.KEY_UP);
+        outBuf.writeShort(0); // padding
+        outBuf.writeInt(map_en_us(order));
+
+        pushDataToAllOuts(outBuf);
+    }
+
+    /**
+     * Return key scan code (in lower byte) and extended flags (in second byte).
+     */
+    private int map_en_us(KeyOrder order) {
+
+        switch (order.event.getKeyCode()) {
+        // Functional keys
+        case KeyEvent.VK_ESCAPE:
+            return 0xff1b;
+        case KeyEvent.VK_F1:
+            return 0xffbe;
+        case KeyEvent.VK_F2:
+            return 0xffbf;
+        case KeyEvent.VK_F3:
+            return 0xffc0;
+        case KeyEvent.VK_F4:
+            return 0xffc1;
+        case KeyEvent.VK_F5:
+            return 0xffc2;
+        case KeyEvent.VK_F6:
+            return 0xffc3;
+        case KeyEvent.VK_F7:
+            return 0xffc4;
+        case KeyEvent.VK_F8:
+            return 0xffc5;
+        case KeyEvent.VK_F9:
+            return 0xffc6;
+        case KeyEvent.VK_F10:
+            return 0xffc7;
+        case KeyEvent.VK_F11:
+            return 0xffc8;
+        case KeyEvent.VK_F12:
+            return 0xffc9;
+
+            // Row #1
+        case KeyEvent.VK_BACK_QUOTE:
+            return (sh) ? '~' : '`';
+        case KeyEvent.VK_1:
+            return (sh) ? '!' : '1';
+        case KeyEvent.VK_2:
+            return (sh) ? '@' : '2';
+        case KeyEvent.VK_3:
+            return (sh) ? '#' : '3';
+        case KeyEvent.VK_4:
+            return (sh) ? '$' : '4';
+        case KeyEvent.VK_5:
+            return (sh) ? '%' : '5';
+        case KeyEvent.VK_6:
+            return (sh) ? '^' : '6';
+        case KeyEvent.VK_7:
+            return (sh) ? '&' : '7';
+        case KeyEvent.VK_8:
+            return (sh) ? '*' : '8';
+        case KeyEvent.VK_9:
+            return (sh) ? '(' : '9';
+        case KeyEvent.VK_0:
+            return (sh) ? ')' : '0';
+        case KeyEvent.VK_MINUS:
+            return (sh) ? '_' : '-';
+        case KeyEvent.VK_EQUALS:
+            return (sh) ? '+' : '=';
+        case KeyEvent.VK_BACK_SPACE:
+            return 0xff08;
+
+            // Row #2
+        case KeyEvent.VK_TAB:
+            return 0xff09;
+        case KeyEvent.VK_Q:
+            return (sh ^ caps) ? 'Q' : 'q';
+        case KeyEvent.VK_W:
+            return (sh ^ caps) ? 'W' : 'w';
+        case KeyEvent.VK_E:
+            return (sh ^ caps) ? 'E' : 'e';
+        case KeyEvent.VK_R:
+            return (sh ^ caps) ? 'R' : 'r';
+        case KeyEvent.VK_T:
+            return (sh ^ caps) ? 'T' : 't';
+        case KeyEvent.VK_Y:
+            return (sh ^ caps) ? 'Y' : 'y';
+        case KeyEvent.VK_U:
+            return (sh ^ caps) ? 'U' : 'u';
+        case KeyEvent.VK_I:
+            return (sh ^ caps) ? 'I' : 'i';
+        case KeyEvent.VK_O:
+            return (sh ^ caps) ? 'O' : 'o';
+        case KeyEvent.VK_P:
+            return (sh ^ caps) ? 'P' : 'p';
+        case KeyEvent.VK_OPEN_BRACKET:
+            return (sh) ? '{' : '[';
+        case KeyEvent.VK_CLOSE_BRACKET:
+            return (sh) ? '{' : ']';
+        case KeyEvent.VK_ENTER:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_STANDARD:
+                return 0xff0d;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xff8d;
+            }
+
+            // Row #3
+        case KeyEvent.VK_CAPS_LOCK:
+            if (order.pressed)
+                caps = !caps;
+            return 0xFFE5;
+        case KeyEvent.VK_A:
+            return (sh ^ caps) ? 'A' : 'a';
+        case KeyEvent.VK_S:
+            return (sh ^ caps) ? 'S' : 's';
+        case KeyEvent.VK_D:
+            return (sh ^ caps) ? 'D' : 'd';
+        case KeyEvent.VK_F:
+            return (sh ^ caps) ? 'F' : 'f';
+        case KeyEvent.VK_G:
+            return (sh ^ caps) ? 'G' : 'g';
+        case KeyEvent.VK_H:
+            return (sh ^ caps) ? 'H' : 'h';
+        case KeyEvent.VK_J:
+            return (sh ^ caps) ? 'J' : 'j';
+        case KeyEvent.VK_K:
+            return (sh ^ caps) ? 'K' : 'k';
+        case KeyEvent.VK_L:
+            return (sh ^ caps) ? 'L' : 'l';
+        case KeyEvent.VK_SEMICOLON:
+            return (sh) ? ':' : ';';
+        case KeyEvent.VK_QUOTE:
+            return (sh) ? '"' : '\'';
+
+            // Row #4
+        case KeyEvent.VK_SHIFT:
+            sh = !sh;
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xffe1;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xffe2;
+            }
+        case KeyEvent.VK_BACK_SLASH:
+            return (sh) ? '|' : '\\';
+        case KeyEvent.VK_Z:
+            return (sh ^ caps) ? 'Z' : 'z';
+        case KeyEvent.VK_X:
+            return (sh ^ caps) ? 'X' : 'x';
+        case KeyEvent.VK_C:
+            return (sh ^ caps) ? 'C' : 'c';
+        case KeyEvent.VK_V:
+            return (sh ^ caps) ? 'V' : 'v';
+        case KeyEvent.VK_B:
+            return (sh ^ caps) ? 'B' : 'b';
+        case KeyEvent.VK_N:
+            return (sh ^ caps) ? 'N' : 'n';
+        case KeyEvent.VK_M:
+            return (sh ^ caps) ? 'M' : 'M';
+        case KeyEvent.VK_COMMA:
+            return (sh) ? '<' : ',';
+        case KeyEvent.VK_PERIOD:
+            return (sh) ? '>' : '.';
+        case KeyEvent.VK_SLASH:
+            return (sh) ? '?' : '/';
+
+            //
+            // Bottom row
+        case KeyEvent.VK_CONTROL:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xFFE3;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xFFE4;
+            }
+        case KeyEvent.VK_WINDOWS:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xFFED; // HyperL
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xFFEE; // HyperR
+            }
+        case KeyEvent.VK_META:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xFFE7; // MetaL
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xFFE8; // MetaR
+            }
+
+        case KeyEvent.VK_ALT:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xFFE9;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xFFEA;
+            }
+        case KeyEvent.VK_ALT_GRAPH:
+            return 0xfe03;
+
+        case KeyEvent.VK_SPACE:
+            return ' ';
+
+        case KeyEvent.VK_CONTEXT_MENU:
+            return 0xff67;
+
+            //
+            // Special keys
+        case KeyEvent.VK_PRINTSCREEN:
+            return (sh) ? 0xFF15/* SysRq */: 0xFF61 /* Print */;
+        case KeyEvent.VK_SCROLL_LOCK:
+            return 0xFF14;
+        case KeyEvent.VK_PAUSE:
+            return (sh) ? 0xFF6B/* Break */: 0xFF13/* Pause */;
+
+            // Text navigation keys
+        case KeyEvent.VK_INSERT:
+            return 0xff63;
+        case KeyEvent.VK_DELETE:
+            return 0xffff;
+        case KeyEvent.VK_HOME:
+            return 0xff50;
+        case KeyEvent.VK_END:
+            return 0xff57;
+        case KeyEvent.VK_PAGE_UP:
+            return 0xff55;
+        case KeyEvent.VK_PAGE_DOWN:
+            return 0xff56;
+
+            // Cursor keys
+        case KeyEvent.VK_LEFT:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xff51;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xFF96;
+            }
+        case KeyEvent.VK_UP:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xff52;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xFF97;
+            }
+        case KeyEvent.VK_RIGHT:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xff53;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xFF98;
+            }
+        case KeyEvent.VK_DOWN:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xff54;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xFF99;
+            }
+
+            // Keypad
+        case KeyEvent.VK_NUM_LOCK:
+            if (order.pressed)
+                num = !num;
+            return 0xFF6F;
+        case KeyEvent.VK_DIVIDE:
+            return 0xFFAF;
+        case KeyEvent.VK_MULTIPLY:
+            return 0xFFAA;
+        case KeyEvent.VK_SUBTRACT:
+            return 0xFFAD;
+        case KeyEvent.VK_ADD:
+            return 0xFFAB;
+
+        case KeyEvent.VK_KP_LEFT:
+            return 0xFF96;
+        case KeyEvent.VK_KP_UP:
+            return 0xFF97;
+        case KeyEvent.VK_KP_RIGHT:
+            return 0xFF98;
+        case KeyEvent.VK_KP_DOWN:
+            return 0xFF99;
+
+        case KeyEvent.VK_NUMPAD0:
+            return 0xFFB0;
+        case KeyEvent.VK_NUMPAD1:
+            return 0xFFB1;
+        case KeyEvent.VK_NUMPAD2:
+            return 0xFFB2;
+        case KeyEvent.VK_NUMPAD3:
+            return 0xFFB3;
+        case KeyEvent.VK_NUMPAD4:
+            return 0xFFB4;
+        case KeyEvent.VK_NUMPAD5:
+            return 0xFFB5;
+        case KeyEvent.VK_NUMPAD6:
+            return 0xFFB6;
+        case KeyEvent.VK_NUMPAD7:
+            return 0xFFB7;
+        case KeyEvent.VK_NUMPAD8:
+            return 0xFFB8;
+        case KeyEvent.VK_NUMPAD9:
+            return 0xFFB9;
+        case KeyEvent.VK_DECIMAL:
+            return 0xFFAE;
+
+        default:
+            System.err.println("Key is not mapped: " + order + ".");
+            return ' '; // Space
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
new file mode 100755
index 0000000..a5215e6
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
@@ -0,0 +1,72 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 vncclient.adapter;
+
+import java.awt.event.MouseEvent;
+
+import common.MouseOrder;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+import vncclient.vnc.RfbConstants;
+
+public class AwtVncMouseAdapter extends BaseElement {
+
+    public AwtVncMouseAdapter(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Get mouse event
+        MouseOrder order = (MouseOrder)buf.getOrder();
+
+        ByteBuffer outBuf = new ByteBuffer(6);
+
+        outBuf.writeByte(RfbConstants.CLIENT_POINTER_EVENT);
+
+        int buttonMask = mapAwtModifiersToVncButtonMask(order.event.getModifiersEx());
+        outBuf.writeByte(buttonMask);
+        outBuf.writeShort(order.event.getX());
+        outBuf.writeShort(order.event.getY());
+
+        pushDataToAllOuts(outBuf);
+    }
+
+    /**
+     * Current state of buttons 1 to 8 are represented by bits 0 to 7 of
+     * button-mask respectively, 0 meaning up, 1 meaning down (pressed). On a
+     * conventional mouse, buttons 1, 2 and 3 correspond to the left, middle and
+     * right buttons on the mouse. On a wheel mouse, each step of the wheel
+     * upwards is represented by a press and release of button 4, and each step
+     * downwards is represented by a press and release of button 5.
+     * 
+     * @param modifiers
+     *          extended modifiers from AWT mouse event
+     * @return VNC mouse button mask
+     */
+    public static int mapAwtModifiersToVncButtonMask(int modifiers) {
+        int mask = (((modifiers & MouseEvent.BUTTON1_DOWN_MASK) != 0) ? 0x1 : 0) | (((modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0) ? 0x2 : 0)
+                | (((modifiers & MouseEvent.BUTTON3_DOWN_MASK) != 0) ? 0x4 : 0);
+        return mask;
+    }
+
+}


[22/22] git commit: updated refs/heads/4.3 to 4f3611f

Posted by de...@apache.org.
CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/4f3611f9
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/4f3611f9
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/4f3611f9

Branch: refs/heads/4.3
Commit: 4f3611f9c769d5b462f3ceec64e6219ee8df694a
Parents: 105e27b
Author: Anshul Gangwar <an...@citrix.com>
Authored: Wed Dec 18 15:41:37 2013 +0530
Committer: Devdeep Singh <de...@gmail.com>
Committed: Mon Dec 23 14:23:19 2013 +0530

----------------------------------------------------------------------
 .../console-proxy-rdp/rdpconsole/README.txt     |   54 +-
 services/console-proxy-rdp/rdpconsole/pom.xml   |    9 +-
 .../console-proxy-rdp/rdpconsole/rdp-config.bat |    2 +-
 .../src/main/java/common/AwtBellAdapter.java    |   76 -
 .../src/main/java/common/AwtCanvasAdapter.java  |  164 --
 .../main/java/common/AwtClipboardAdapter.java   |   55 -
 .../src/main/java/common/AwtKeyEventSource.java |   38 +-
 .../main/java/common/AwtMouseEventSource.java   |   70 +-
 .../src/main/java/common/BitmapOrder.java       |   33 +-
 .../src/main/java/common/BitmapRectangle.java   |   78 +-
 .../main/java/common/BufferedImageCanvas.java   |   96 +-
 .../common/BufferedImageCopyRectAdapter.java    |  187 +-
 .../java/common/BufferedImagePixelsAdapter.java |  174 +-
 .../rdpconsole/src/main/java/common/Client.java |  423 +++-
 .../src/main/java/common/CopyRectOrder.java     |   27 +-
 .../src/main/java/common/KeyOrder.java          |   41 +-
 .../src/main/java/common/MouseOrder.java        |   29 +-
 .../src/main/java/common/OrderType.java         |    2 +-
 .../src/main/java/common/ScreenDescription.java |  268 +--
 .../main/java/common/SizeChangeListener.java    |    2 +-
 .../java/common/adapter/AwtBellAdapter.java     |   76 +
 .../java/common/adapter/AwtCanvasAdapter.java   |  171 ++
 .../common/adapter/AwtClipboardAdapter.java     |   56 +
 .../src/main/java/common/asn1/Any.java          |   78 +
 .../main/java/common/asn1/Asn1Constants.java    |   83 +
 .../src/main/java/common/asn1/Asn1Integer.java  |  116 ++
 .../src/main/java/common/asn1/BerType.java      |   40 +
 .../src/main/java/common/asn1/BitString.java    |   67 +
 .../src/main/java/common/asn1/ObjectID.java     |   67 +
 .../src/main/java/common/asn1/OctetString.java  |   80 +
 .../src/main/java/common/asn1/Sequence.java     |  143 ++
 .../src/main/java/common/asn1/SequenceOf.java   |   81 +
 .../src/main/java/common/asn1/Tag.java          |  462 +++++
 .../main/java/common/opt/IncrementalOption.java |   28 +
 .../src/main/java/common/opt/IntOption.java     |   41 +
 .../opt/NoArgumentForOptionException.java       |   26 +
 .../src/main/java/common/opt/Option.java        |  102 +
 .../src/main/java/common/opt/OptionParser.java  |  147 ++
 .../common/opt/OptionRequiredException.java     |   26 +
 .../main/java/common/opt/StringArrayOption.java |   38 +
 .../common/opt/StringEnumerationOption.java     |   72 +
 .../src/main/java/common/opt/StringOption.java  |   41 +
 .../java/common/opt/UnknownOptionException.java |   27 +
 .../java/rdpclient/AwtRdpKeyboardAdapter.java   |  351 ----
 .../main/java/rdpclient/AwtRdpMouseAdapter.java |  180 --
 .../java/rdpclient/ClientConfirmActivePDU.java  | 1132 -----------
 .../main/java/rdpclient/ClientFastPathPDU.java  |   55 -
 .../src/main/java/rdpclient/ClientInfoPDU.java  |  456 -----
 .../rdpclient/ClientMCSAttachUserRequest.java   |  102 -
 ...JoinRequest_ServerMCSChannelConfirmPDUs.java |  222 ---
 .../java/rdpclient/ClientMCSConnectInitial.java |  669 -------
 .../rdpclient/ClientMCSErectDomainRequest.java  |  190 --
 .../java/rdpclient/ClientPacketSniffer.java     |   50 -
 .../java/rdpclient/ClientSynchronizePDU.java    |  248 ---
 .../src/main/java/rdpclient/ClientTpkt.java     |   54 -
 .../ClientX224ConnectionRequestPDU.java         |  156 --
 .../main/java/rdpclient/ClientX224DataPdu.java  |   54 -
 .../src/main/java/rdpclient/HandshakeEnd.java   |   27 -
 .../src/main/java/rdpclient/MockServer.java     |  197 --
 .../src/main/java/rdpclient/PacketSniffer.java  |   75 -
 .../java/rdpclient/RLEBitmapDecompression.java  | 1014 ----------
 .../src/main/java/rdpclient/RdpClient.java      |  415 ++--
 .../src/main/java/rdpclient/RdpConstants.java   |   74 -
 .../src/main/java/rdpclient/RdpState.java       |   33 -
 .../main/java/rdpclient/ServerBitmapUpdate.java |  201 --
 .../java/rdpclient/ServerChannel1003Router.java |  530 -----
 .../rdpclient/ServerControlPDUCooperate.java    |  117 --
 .../ServerControlPDUGrantedControl.java         |  114 --
 .../java/rdpclient/ServerDemandActivePDU.java   |  661 ------
 .../src/main/java/rdpclient/ServerFastPath.java |  259 ---
 .../ServerLicenseErrorPDUValidClient.java       |  121 --
 .../ServerMCSAttachUserConfirmPDU.java          |  133 --
 .../ServerMCSChannelJoinConfirmPDU.java         |   89 -
 .../rdpclient/ServerMCSConnectResponse.java     |  283 ---
 .../src/main/java/rdpclient/ServerMCSPDU.java   |  149 --
 .../java/rdpclient/ServerPacketSniffer.java     |   52 -
 .../java/rdpclient/ServerPaletteUpdate.java     |   78 -
 .../java/rdpclient/ServerSynchronizePDU.java    |  115 --
 .../src/main/java/rdpclient/ServerTpkt.java     |   70 -
 .../ServerX224ConnectionConfirmPDU.java         |  237 ---
 .../main/java/rdpclient/ServerX224DataPdu.java  |   64 -
 .../rdpclient/TrustAllX509TrustManager.java     |   40 -
 .../main/java/rdpclient/UpgradeSocketToSSL.java |   44 -
 .../adapter/AwtRdpKeyboardAdapter.java          |  351 ++++
 .../rdpclient/adapter/AwtRdpMouseAdapter.java   |  180 ++
 .../rdpclient/clip/ClipboardDataFormat.java     |  143 ++
 .../java/rdpclient/clip/ClipboardState.java     |   70 +
 .../clip/ServerClipRdrChannelRouter.java        |  193 ++
 .../clip/ServerClipboardCapabilitiesPDU.java    |  180 ++
 .../clip/ServerFormatDataResponsePDU.java       |   98 +
 .../rdpclient/clip/ServerFormatListPDU.java     |  237 +++
 .../rdpclient/clip/ServerMonitorReadyPDU.java   |   85 +
 .../rdpclient/debug/ClientPacketSniffer.java    |   50 +
 .../java/rdpclient/debug/PacketSniffer.java     |   75 +
 .../rdpclient/debug/ServerPacketSniffer.java    |   48 +
 .../hyperv/ClientPreConnectionBlob.java         |  121 ++
 .../ntlmssp/ClientNtlmsspNegotiate.java         |  178 ++
 .../ntlmssp/ClientNtlmsspPubKeyAuth.java        |  681 +++++++
 .../ntlmssp/ClientNtlmsspUserCredentials.java   |  128 ++
 .../java/rdpclient/ntlmssp/CryptoAlgos.java     |  361 ++++
 .../main/java/rdpclient/ntlmssp/NegoFlags.java  |  492 +++++
 .../java/rdpclient/ntlmssp/NtlmCompute.java     |   23 +
 .../java/rdpclient/ntlmssp/NtlmConstants.java   |  157 ++
 .../main/java/rdpclient/ntlmssp/NtlmState.java  |  887 ++++++++
 .../main/java/rdpclient/ntlmssp/SecBuffer.java  |   21 +
 .../ntlmssp/ServerNtlmsspChallenge.java         |  293 +++
 .../ntlmssp/ServerNtlmsspPubKeyPlus1.java       |  125 ++
 .../ntlmssp/asn1/AlgorithmIdentifier.java       |   40 +
 .../java/rdpclient/ntlmssp/asn1/NegoData.java   |   64 +
 .../java/rdpclient/ntlmssp/asn1/NegoItem.java   |   73 +
 .../ntlmssp/asn1/SubjectPublicKeyInfo.java      |   35 +
 .../rdpclient/ntlmssp/asn1/TSCredentials.java   |   62 +
 .../rdpclient/ntlmssp/asn1/TSCspDataDetail.java |   98 +
 .../rdpclient/ntlmssp/asn1/TSPasswordCreds.java |   76 +
 .../java/rdpclient/ntlmssp/asn1/TSRequest.java  |  202 ++
 .../ntlmssp/asn1/TSSmartCardCreds.java          |   90 +
 .../java/rdpclient/ntlmssp/package-info.java    |   71 +
 .../rdpclient/rdp/ClientConfirmActivePDU.java   | 1132 +++++++++++
 .../java/rdpclient/rdp/ClientFastPathPDU.java   |   55 +
 .../main/java/rdpclient/rdp/ClientInfoPDU.java  |  456 +++++
 .../rdp/ClientMCSAttachUserRequest.java         |  103 +
 ...JoinRequest_ServerMCSChannelConfirmPDUs.java |  223 +++
 .../rdpclient/rdp/ClientMCSConnectInitial.java  |  696 +++++++
 .../rdp/ClientMCSErectDomainRequest.java        |  189 ++
 .../rdpclient/rdp/ClientSynchronizePDU.java     |  248 +++
 .../src/main/java/rdpclient/rdp/ClientTpkt.java |   54 +
 .../rdp/ClientX224ConnectionRequestPDU.java     |  162 ++
 .../java/rdpclient/rdp/ClientX224DataPDU.java   |   52 +
 .../rdpclient/rdp/RLEBitmapDecompression.java   | 1014 ++++++++++
 .../main/java/rdpclient/rdp/RdpConstants.java   |   91 +
 .../src/main/java/rdpclient/rdp/RdpState.java   |   33 +
 .../java/rdpclient/rdp/ServerBitmapUpdate.java  |  200 ++
 .../rdp/ServerControlPDUCooperate.java          |  117 ++
 .../rdp/ServerControlPDUGrantedControl.java     |  114 ++
 .../rdpclient/rdp/ServerDemandActivePDU.java    |  661 ++++++
 .../main/java/rdpclient/rdp/ServerFastPath.java |  315 +++
 .../rdpclient/rdp/ServerIOChannelRouter.java    |  534 +++++
 .../rdp/ServerLicenseErrorPDUValidClient.java   |  121 ++
 .../rdp/ServerMCSAttachUserConfirmPDU.java      |  116 ++
 .../rdp/ServerMCSChannelJoinConfirmPDU.java     |   89 +
 .../rdpclient/rdp/ServerMCSConnectResponse.java |  283 +++
 .../main/java/rdpclient/rdp/ServerMCSPDU.java   |  149 ++
 .../java/rdpclient/rdp/ServerPaletteUpdate.java |   78 +
 .../rdpclient/rdp/ServerSynchronizePDU.java     |  115 ++
 .../src/main/java/rdpclient/rdp/ServerTpkt.java |   70 +
 .../rdp/ServerX224ConnectionConfirmPDU.java     |  234 +++
 .../java/rdpclient/rdp/ServerX224DataPdu.java   |   64 +
 .../main/java/streamer/AssertingByteBuffer.java |  107 -
 .../src/main/java/streamer/BaseElement.java     |  718 +++----
 .../src/main/java/streamer/BufferPool.java      |   30 +-
 .../src/main/java/streamer/ByteBuffer.java      | 1887 ++++++++++--------
 .../src/main/java/streamer/DataSink.java        |    4 +-
 .../src/main/java/streamer/DataSource.java      |   72 +-
 .../src/main/java/streamer/Direction.java       |    2 +-
 .../src/main/java/streamer/Element.java         |  164 +-
 .../src/main/java/streamer/Event.java           |   24 +-
 .../src/main/java/streamer/FakeSink.java        |   69 -
 .../src/main/java/streamer/FakeSource.java      |  125 --
 .../main/java/streamer/InputStreamSource.java   |  282 +--
 .../rdpconsole/src/main/java/streamer/Link.java |   72 +-
 .../src/main/java/streamer/MockSink.java        |  111 --
 .../src/main/java/streamer/MockSource.java      |   88 -
 .../src/main/java/streamer/OneTimeSwitch.java   |  203 +-
 .../src/main/java/streamer/Order.java           |    2 +-
 .../main/java/streamer/OutputStreamSink.java    |  240 +--
 .../src/main/java/streamer/Pipeline.java        |  120 +-
 .../src/main/java/streamer/PipelineImpl.java    |  519 ++---
 .../src/main/java/streamer/Queue.java           |  214 +-
 .../src/main/java/streamer/SocketWrapper.java   |  222 +--
 .../main/java/streamer/SocketWrapperImpl.java   |  250 +++
 .../src/main/java/streamer/SyncLink.java        |  674 ++++---
 .../main/java/streamer/apr/AprSocketSink.java   |  129 ++
 .../main/java/streamer/apr/AprSocketSource.java |  171 ++
 .../java/streamer/apr/AprSocketWrapperImpl.java |  281 +++
 .../java/streamer/bco/BcoSocketWrapperImpl.java |  119 ++
 .../streamer/debug/AssertingByteBuffer.java     |  109 +
 .../src/main/java/streamer/debug/Dumper.java    |   28 +
 .../src/main/java/streamer/debug/FakeSink.java  |   77 +
 .../main/java/streamer/debug/FakeSource.java    |  138 ++
 .../main/java/streamer/debug/MockServer.java    |  202 ++
 .../src/main/java/streamer/debug/MockSink.java  |  154 ++
 .../main/java/streamer/debug/MockSource.java    |   95 +
 .../src/main/java/streamer/ssl/SSLState.java    |   26 +
 .../streamer/ssl/TrustAllX509TrustManager.java  |   52 +
 .../java/streamer/ssl/UpgradeSocketToSSL.java   |   44 +
 .../vncclient/AwtKeyboardEventToVncAdapter.java |  369 ----
 .../vncclient/AwtMouseEventToVncAdapter.java    |   71 -
 .../main/java/vncclient/EncodingsMessage.java   |   63 -
 .../vncclient/FrameBufferUpdateRequest.java     |  127 --
 .../vncclient/RGB888LE32PixelFormatRequest.java |   90 -
 .../src/main/java/vncclient/RfbConstants.java   |   85 -
 .../src/main/java/vncclient/VncClient.java      |  121 +-
 .../src/main/java/vncclient/VncInitializer.java |  244 ---
 .../main/java/vncclient/VncMessageHandler.java  |  419 ----
 .../java/vncclient/Vnc_3_3_Authentication.java  |  291 ---
 .../src/main/java/vncclient/Vnc_3_3_Hello.java  |  115 --
 .../adapter/AwtVncKeyboardAdapter.java          |  370 ++++
 .../vncclient/adapter/AwtVncMouseAdapter.java   |   72 +
 .../java/vncclient/vnc/EncodingsMessage.java    |   63 +
 .../vncclient/vnc/FrameBufferUpdateRequest.java |  127 ++
 .../vnc/RGB888LE32PixelFormatRequest.java       |   90 +
 .../main/java/vncclient/vnc/RfbConstants.java   |   85 +
 .../main/java/vncclient/vnc/VncInitializer.java |  245 +++
 .../java/vncclient/vnc/VncMessageHandler.java   |  419 ++++
 .../vncclient/vnc/Vnc_3_3_Authentication.java   |  291 +++
 .../main/java/vncclient/vnc/Vnc_3_3_Hello.java  |  115 ++
 .../src/main/resources/jaas_ntlm_config.txt     |   21 +
 .../rdpconsole/src/test/doc/README.txt          |    2 +
 .../rdpconsole/src/test/doc/dev-rdp-config.bat  |   13 +
 .../src/test/doc/freerdp-debug-log.txt          |  772 +++++++
 .../rdpconsole/src/test/doc/rdp.pfx             |  Bin 0 -> 2572 bytes
 .../src/test/java/rdpclient/MockServerTest.java |  273 +--
 212 files changed, 24574 insertions(+), 14966 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/README.txt
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/README.txt b/services/console-proxy-rdp/rdpconsole/README.txt
old mode 100644
new mode 100755
index 15029d4..546746c
--- a/services/console-proxy-rdp/rdpconsole/README.txt
+++ b/services/console-proxy-rdp/rdpconsole/README.txt
@@ -14,28 +14,38 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-This project contains code for basic VNC and RDP clients.
-
-VNC client can be invoked using following command:
-
-  mvn exec:java -Dexec.mainClass="common.Client" -Dexec.args="vnc 192.168.0.101 5901 password"
-
-where
-  * vnc - name of protcol;
-  * 192.168.0.101 - IP of VNC server;
-  * 5901 - port of VNC server screen (5900+display number);
-  * password - VNC server password.
-
-
-RDP client can be invoked using following command:
-
-  mvn exec:java -Dexec.mainClass="common.Client" -Dexec.args="rdp 192.168.0.101 3389 Administrator"
-
-where
-  * rdp - name of protcol;
-  * 192.168.0.101 - IP of RDP server;
-  * 3389 - port of RDP server;
-  * Administrator - user name for loging dialog.
+This project contains code for basic VNC, RDP, and HyperV (RDP) clients.
+
+Usage: 
+  java common.Client vnc|rdp|hyperv OPTIONS
+
+Common options:
+  --help|-h	Show this help text.
+  --debug-link|-DL	Print debugging messages when packets are trasnferred via links.
+  --debug-element|-DE	Print debugging messages when packets are received or sended by elements.
+  --debug-pipeline|-DP	Print debugging messages in pipelines.
+  --host|-n|--host-name VALUE	Name or IP address of host to connect to. Required.
+  --width|-W VALUE	Width of canvas. Default value is "1024".
+  --height|-H VALUE	Height of canvas. Default value is "768".
+
+VNC options:
+  --port|-p VALUE	Port of VNC display server to connect to. Calculate as 5900 + display number, e.g. 5900 for display #0, 5901 for display #1, and so on. Default value is "5901".
+  --password|-P VALUE	Password to use. Required.
+
+RDP options:
+  --ssl-implementation|-j jre|apr|bco	Select SSL engine to use: JRE standard implementation, Apache Portable Runtime native library, BonuncyCastle.org implementation. Default value is "apr".
+  --port|-p VALUE	Port of RDP server to connect to. Default value is "3389".
+  --domain|-D VALUE	NTLM domain to login into. Default value is "Workgroup".
+  --user|-U VALUE	User name to use. Default value is "Administrator".
+  --password|-P VALUE	Password to use. If omitted, then login screen will be shown.
+
+HyperV options:
+  --ssl-implementation|-j jre|apr|bco	Select SSL engine to use: JRE standard implementation, Apache Portable Runtime native library, BonuncyCastle.org implementation. Default value is "apr".
+  --port|-p VALUE	Port of HyperV server to connect to. Default value is "2179".
+  --instance|-i VALUE	HyperV instance ID to use. Required.
+  --domain|-D VALUE	NTLM domain to login into. Default value is "Workgroup".
+  --user|-U VALUE	User name to use. Default value is "Administrator".
+  --password|-P VALUE	Password to use. Required.
 
 
 Limitations of VNC client:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/pom.xml
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/pom.xml b/services/console-proxy-rdp/rdpconsole/pom.xml
old mode 100644
new mode 100755
index 02e469f..f749442
--- a/services/console-proxy-rdp/rdpconsole/pom.xml
+++ b/services/console-proxy-rdp/rdpconsole/pom.xml
@@ -61,11 +61,18 @@
       <version>3.8.1</version>
       <scope>test</scope>
     </dependency>
+    <!-- Apache Portable Runtime implementation of SSL protocol, which is compatible with broken MS RDP SSL suport.
+    NOTE: tomcat-native package with /usr/lib/libtcnative-1.so library is necessary for APR to work. -->
     <dependency>
       <groupId>org.apache.tomcat.embed</groupId>
       <artifactId>tomcat-embed-core</artifactId>
       <version>7.0.30</version>
-      <scope>test</scope>
+    </dependency>
+    <!-- Another implementation of SSL protocol. Does not work with broken MS RDP SSL too. -->
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcprov-jdk16</artifactId>
+      <version>1.46</version>
     </dependency>
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/rdp-config.bat
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/rdp-config.bat b/services/console-proxy-rdp/rdpconsole/rdp-config.bat
old mode 100644
new mode 100755
index e951014..f19b00d
--- a/services/console-proxy-rdp/rdpconsole/rdp-config.bat
+++ b/services/console-proxy-rdp/rdpconsole/rdp-config.bat
@@ -16,7 +16,7 @@ rem specific language governing permissions and limitations
 rem under the License.
 
 rem 
-rem Configure and start RDP service.
+rem Configure and start RDP service. Run this script on RDP server.
 rem 
  
 rem Turn off firewall

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtBellAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtBellAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtBellAdapter.java
deleted file mode 100644
index 3318c09..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtBellAdapter.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 common;
-
-import java.awt.Toolkit;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.FakeSource;
-import streamer.Link;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class AwtBellAdapter extends BaseElement {
-
-  public AwtBellAdapter(String id) {
-    super(id);
-    declarePads();
-  }
-
-  private void declarePads() {
-    inputPads.put(STDIN, null);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    if (buf == null)
-      return;
-
-    Toolkit.getDefaultToolkit().beep();
-  }
-
-  public String toString() {
-    return "Bell(" + id + ")";
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    System.setProperty("streamer.Element.debug", "true");
-
-    Element source = new FakeSource("source") {
-      {
-        this.incommingBufLength = 0;
-        this.delay = 1000;
-        this.numBuffers = 3;
-      }
-    };
-
-    Element sink = new AwtBellAdapter("sink");
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.addAndLink(source, sink);
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtCanvasAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtCanvasAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtCanvasAdapter.java
deleted file mode 100644
index 12dd88b..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtCanvasAdapter.java
+++ /dev/null
@@ -1,164 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 common;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.WritableRaster;
-
-import rdpclient.ServerBitmapUpdate;
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.Order;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class AwtCanvasAdapter extends BaseElement {
-
-  protected ScreenDescription screen;
-
-  public AwtCanvasAdapter(String id, BufferedImageCanvas canvas, ScreenDescription screen) {
-    super(id);
-    this.canvas = canvas;
-    this.screen = screen;
-  }
-
-  protected BufferedImageCanvas canvas;
-
-  public String toString() {
-    return "AwtRdpAdapter(" + id + ")";
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    Order order = (Order) buf.getOrder();
-    switch ((OrderType) order.type) {
-
-    case BITMAP_UPDATE:
-      handleBitmap((BitmapOrder) order, buf);
-      break;
-
-    case COPY_RECT:
-      handleCopyRect((CopyRectOrder) order, buf);
-      break;
-
-    default:
-      throw new RuntimeException("Order is not implemented: " + buf + ".");
-      // break;
-    }
-
-    buf.unref();
-  }
-
-  private void handleCopyRect(CopyRectOrder order, ByteBuffer buf) {
-    // TODO Auto-generated method stub
-    // Copy image
-    canvas.getOfflineGraphics().copyArea(order.srcX, order.srcY, order.width, order.height, order.x - order.srcX, order.y - order.srcY);
-
-    // Request update of repainted area
-    canvas.repaint(order.x, order.y, order.width, order.height);
-
-  }
-
-  private void handleBitmap(BitmapOrder order, ByteBuffer buf) {
-    // Draw rectangle on offline buffer
-    BufferedImage image = canvas.getOfflineImage();
-    Graphics2D g = (Graphics2D) image.getGraphics();
-
-    for (BitmapRectangle rectangle : order.rectangles) {
-      // *DEBUG*/System.out.println("["+this+"] DEBUG: Rectangle: " +
-      // rectangle.toString());
-
-      int x = rectangle.x;
-      int y = rectangle.y;
-      int width = rectangle.width;
-      int height = rectangle.height;
-      int bufferWidth = rectangle.bufferWidth;
-      int bufferHeight = rectangle.bufferHeight;
-
-      BufferedImage rectImage;
-      switch (rectangle.colorDepth) {
-      case 8: {
-        rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_BYTE_INDEXED, screen.colorMap);
-        WritableRaster raster = rectImage.getRaster();
-        raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toByteArray());
-        break;
-      }
-      case 15: {
-        rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_USHORT_555_RGB);
-        WritableRaster raster = rectImage.getRaster();
-        raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toShortArray());
-        break;
-      }
-      case 16: {
-        rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_USHORT_565_RGB);
-        WritableRaster raster = rectImage.getRaster();
-        raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toShortArray());
-        break;
-      }
-      case 24:
-      case 32: {
-        rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_INT_RGB);
-        WritableRaster raster = rectImage.getRaster();
-        raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toIntLEArray());
-        break;
-      }
-      default:
-        throw new RuntimeException("Unsupported color depth: " + rectangle.colorDepth + ".");
-      }
-
-      g.setClip(x, y, width, height);
-      g.drawImage(rectImage, x, y, null);
-
-      // Request update of repainted area
-      canvas.repaint(x, y, width, height);
-    }
-
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    // System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-    ByteBuffer packet = new ByteBuffer(new byte[] { 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x00,
-        0x01, 0x04, 0x0a, 0x00, 0x0c, (byte) 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
-
-    Pipeline pipeline = new PipelineImpl("test");
-
-    Element bitmap = new ServerBitmapUpdate("bitmap");
-
-    BufferedImageCanvas canvas = new BufferedImageCanvas(1024, 768);
-    Element adapter = new AwtCanvasAdapter("test", canvas, null) {
-      {
-        verbose = true;
-      }
-    };
-    pipeline.addAndLink(bitmap, adapter);
-
-    bitmap.handleData(packet, null);
-
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtClipboardAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtClipboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtClipboardAdapter.java
deleted file mode 100644
index aeed41c..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtClipboardAdapter.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 common;
-
-import java.awt.Toolkit;
-import java.awt.datatransfer.StringSelection;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-import vncclient.VncMessageHandler;
-
-public class AwtClipboardAdapter extends BaseElement {
-
-  public AwtClipboardAdapter(String id) {
-    super(id);
-    declarePads();
-  }
-
-  private void declarePads() {
-    inputPads.put(STDIN, null);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    if (buf == null)
-      return;
-
-    String content = (String) buf.getMetadata(VncMessageHandler.CLIPBOARD_CONTENT);
-    StringSelection contents = new StringSelection(content);
-    Toolkit.getDefaultToolkit().getSystemClipboard().setContents(contents, null);
-  }
-
-  public String toString() {
-    return "Clipboard(" + id + ")";
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtKeyEventSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtKeyEventSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtKeyEventSource.java
old mode 100644
new mode 100755
index a754796..89a9008
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtKeyEventSource.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtKeyEventSource.java
@@ -24,30 +24,30 @@ import streamer.ByteBuffer;
 
 public class AwtKeyEventSource extends BaseElement implements KeyListener {
 
-  public AwtKeyEventSource(String id) {
-    super(id);
-  }
+    public AwtKeyEventSource(String id) {
+        super(id);
+    }
 
-  @Override
-  public void keyTyped(KeyEvent e) {
-    // Nothing to do
+    @Override
+    public void keyTyped(KeyEvent e) {
+        // Nothing to do
 
-  }
+    }
 
-  @Override
-  public void keyPressed(KeyEvent e) {
-    sendEvent(e, true);
-  }
+    @Override
+    public void keyPressed(KeyEvent e) {
+        sendEvent(e, true);
+    }
 
-  @Override
-  public void keyReleased(KeyEvent e) {
-    sendEvent(e, false);
-  }
+    @Override
+    public void keyReleased(KeyEvent e) {
+        sendEvent(e, false);
+    }
 
-  private void sendEvent(KeyEvent e, boolean pressed) {
-    ByteBuffer buf=new ByteBuffer(new KeyOrder(e, pressed));
+    private void sendEvent(KeyEvent e, boolean pressed) {
+        ByteBuffer buf = new ByteBuffer(new KeyOrder(e, pressed));
 
-    pushDataToAllOuts(buf);
-  }
+        pushDataToAllOuts(buf);
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtMouseEventSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtMouseEventSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtMouseEventSource.java
old mode 100644
new mode 100755
index f3e58fc..fe4dde6
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtMouseEventSource.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtMouseEventSource.java
@@ -25,47 +25,47 @@ import streamer.ByteBuffer;
 
 public class AwtMouseEventSource extends BaseElement implements MouseListener, MouseMotionListener {
 
-  public AwtMouseEventSource(String id) {
-    super(id);
-  }
+    public AwtMouseEventSource(String id) {
+        super(id);
+    }
 
-  @Override
-  public void mouseClicked(MouseEvent e) {
-    // Nothing to do
-  }
+    @Override
+    public void mouseClicked(MouseEvent e) {
+        // Nothing to do
+    }
 
-  @Override
-  public void mousePressed(MouseEvent e) {
-    MouseOrder order = new MouseOrder(e);
-    order.pressed = true;
-    pushDataToAllOuts(new ByteBuffer(order));
-  }
+    @Override
+    public void mousePressed(MouseEvent e) {
+        MouseOrder order = new MouseOrder(e);
+        order.pressed = true;
+        pushDataToAllOuts(new ByteBuffer(order));
+    }
 
-  @Override
-  public void mouseReleased(MouseEvent e) {
-    MouseOrder order = new MouseOrder(e);
-    order.released = true;
-    pushDataToAllOuts(new ByteBuffer(order));
-  }
+    @Override
+    public void mouseReleased(MouseEvent e) {
+        MouseOrder order = new MouseOrder(e);
+        order.released = true;
+        pushDataToAllOuts(new ByteBuffer(order));
+    }
 
-  @Override
-  public void mouseEntered(MouseEvent e) {
-    // Nothing to do
-  }
+    @Override
+    public void mouseEntered(MouseEvent e) {
+        // Nothing to do
+    }
 
-  @Override
-  public void mouseExited(MouseEvent e) {
-    // Nothing to do
-  }
+    @Override
+    public void mouseExited(MouseEvent e) {
+        // Nothing to do
+    }
 
-  @Override
-  public void mouseDragged(MouseEvent e) {
-    pushDataToAllOuts(new ByteBuffer(new MouseOrder(e)));
-  }
+    @Override
+    public void mouseDragged(MouseEvent e) {
+        pushDataToAllOuts(new ByteBuffer(new MouseOrder(e)));
+    }
 
-  @Override
-  public void mouseMoved(MouseEvent e) {
-    pushDataToAllOuts(new ByteBuffer(new MouseOrder(e)));
-  }
+    @Override
+    public void mouseMoved(MouseEvent e) {
+        pushDataToAllOuts(new ByteBuffer(new MouseOrder(e)));
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapOrder.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapOrder.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapOrder.java
old mode 100644
new mode 100755
index 438755f..e687bf7
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapOrder.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapOrder.java
@@ -18,7 +18,6 @@ package common;
 
 import java.util.Arrays;
 
-
 import streamer.Order;
 
 /**
@@ -28,21 +27,21 @@ import streamer.Order;
  */
 public class BitmapOrder extends Order {
 
-  public BitmapOrder() {
-    type = OrderType.BITMAP_UPDATE;
-  }
-
-  /**
-   * Structures, each of which contains a rectangular clipping taken from the
-   * server-side screen frame buffer.
-   */
-  public BitmapRectangle rectangles[];
-
-  @Override
-  public String toString() {
-    final int maxLen = 10;
-    return String.format("BitmapUpdateOrder [rectangles=%s]", rectangles != null ? Arrays.asList(rectangles).subList(0, Math.min(rectangles.length, maxLen))
-        : null);
-  }
+    public BitmapOrder() {
+        type = OrderType.BITMAP_UPDATE;
+    }
+
+    /**
+     * Structures, each of which contains a rectangular clipping taken from the
+     * server-side screen frame buffer.
+     */
+    public BitmapRectangle rectangles[];
+
+    @Override
+    public String toString() {
+        final int maxLen = 10;
+        return String.format("BitmapUpdateOrder [rectangles=%s]", rectangles != null ? Arrays.asList(rectangles).subList(0, Math.min(rectangles.length, maxLen))
+                : null);
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapRectangle.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapRectangle.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapRectangle.java
old mode 100644
new mode 100755
index f0c178e..1685114
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapRectangle.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapRectangle.java
@@ -23,52 +23,52 @@ import streamer.ByteBuffer;
  */
 public class BitmapRectangle {
 
-  /**
-   * Left bound of the rectangle.
-   */
-  public int x;
+    /**
+     * Left bound of the rectangle.
+     */
+    public int x;
 
-  /**
-   * Top bound of the rectangle.
-   */
-  public int y;
+    /**
+     * Top bound of the rectangle.
+     */
+    public int y;
 
-  /**
-   * Width of the rectangle.
-   */
-  public int width;
+    /**
+     * Width of the rectangle.
+     */
+    public int width;
 
-  /**
-   * Height of the rectangle.
-   */
-  public int height;
+    /**
+     * Height of the rectangle.
+     */
+    public int height;
 
-  /**
-   * Color depth of the rectangle data in bits-per-pixel.
-   */
-  public int colorDepth;
+    /**
+     * Color depth of the rectangle data in bits-per-pixel.
+     */
+    public int colorDepth;
 
-  /**
-   * Variable-length array of bytes describing a raw uncompressed bitmap image.
-   */
-  public ByteBuffer bitmapDataStream;
+    /**
+     * Variable-length array of bytes describing a raw uncompressed bitmap image.
+     */
+    public ByteBuffer bitmapDataStream;
 
-  /**
-   * Size of single horizontal scan line.
-   */
-  public int bufferWidth;
+    /**
+     * Size of single horizontal scan line.
+     */
+    public int bufferWidth;
 
-  /**
-   * Number of horizontal scan lines in buffer.
-   */
-  public int bufferHeight;
+    /**
+     * Number of horizontal scan lines in buffer.
+     */
+    public int bufferHeight;
 
-  @Override
-  public String toString() {
-    return String
-        .format(
-            "BitmapUpdateRectangle [x=%s, y=%s, width=%s, height=%s, bitsPerPixel=%s, bitmapDataStream=%s]",
-            x, y, width, height, colorDepth, bitmapDataStream);
-  }
+    @Override
+    public String toString() {
+        return String
+                .format(
+                        "BitmapUpdateRectangle [x=%s, y=%s, width=%s, height=%s, bitsPerPixel=%s, bitmapDataStream=%s]",
+                        x, y, width, height, colorDepth, bitmapDataStream);
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java
old mode 100644
new mode 100755
index 6e7738f..2418de3
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java
@@ -27,53 +27,53 @@ import java.awt.image.BufferedImage;
  * screen. It also notifies its subscribers when screen is repainted.
  */
 public class BufferedImageCanvas extends Canvas {
-  private static final long serialVersionUID = 1L;
-
-   // Offline screen buffer
-  private BufferedImage offlineImage;
-  
-  // Cached Graphics2D object for offline screen buffer
-  private Graphics2D graphics;
-
-  public BufferedImageCanvas(int width, int height) {
-    super();
-
-    setBackground(Color.black);
-    
-    setFocusable(true);
-
-    // Don't intercept TAB key
-    setFocusTraversalKeysEnabled(false);
-
-    setCanvasSize(width, height);
-  }
-
-  public void setCanvasSize(int width, int height) {
-    this.offlineImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-    graphics = offlineImage.createGraphics();
-
-    setSize(offlineImage.getWidth(), offlineImage.getHeight());
-  }
-
-  @Override
-  public void update(Graphics g) {
-    // Call paint() directly, without clearing screen first
-    paint(g);
-  }
-
-  @Override
-  public void paint(Graphics g) {
-    // Only part of image, requested with repaint(Rectangle), will be
-    // painted on screen.
-    g.drawImage(offlineImage, 0, 0, this);
-  }
-
-  public BufferedImage getOfflineImage() {
-    return offlineImage;
-  }
-
-  public Graphics2D getOfflineGraphics() {
-    return graphics;
-  }
+    private static final long serialVersionUID = 1L;
+
+    // Offline screen buffer
+    private BufferedImage offlineImage;
+
+    // Cached Graphics2D object for offline screen buffer
+    private Graphics2D graphics;
+
+    public BufferedImageCanvas(int width, int height) {
+        super();
+
+        setBackground(Color.black);
+
+        setFocusable(true);
+
+        // Don't intercept TAB key
+        setFocusTraversalKeysEnabled(false);
+
+        setCanvasSize(width, height);
+    }
+
+    public void setCanvasSize(int width, int height) {
+        this.offlineImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        graphics = offlineImage.createGraphics();
+
+        setSize(offlineImage.getWidth(), offlineImage.getHeight());
+    }
+
+    @Override
+    public void update(Graphics g) {
+        // Call paint() directly, without clearing screen first
+        paint(g);
+    }
+
+    @Override
+    public void paint(Graphics g) {
+        // Only part of image, requested with repaint(Rectangle), will be
+        // painted on screen.
+        g.drawImage(offlineImage, 0, 0, this);
+    }
+
+    public BufferedImage getOfflineImage() {
+        return offlineImage;
+    }
+
+    public Graphics2D getOfflineGraphics() {
+        return graphics;
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java
old mode 100644
new mode 100755
index bbd5142..e1993d5
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java
@@ -26,99 +26,98 @@ import streamer.Link;
 
 public class BufferedImageCopyRectAdapter extends BaseElement {
 
-  public static final String SRC_X = "srcX";
-  public static final String SRC_Y = "srcY";
-  public static final String TARGET_X = "x";
-  public static final String TARGET_Y = "y";
-  public static final String WIDTH = "width";
-  public static final String HEIGHT = "height";
-
-  protected BufferedImageCanvas canvas;
-
-  public BufferedImageCopyRectAdapter(String id, BufferedImageCanvas canvas) {
-    super(id);
-    this.canvas = canvas;
-    declarePads();
-  }
-
-  private void declarePads() {
-    inputPads.put(STDIN, null);
-  }
-
-  public String toString() {
-    return "Renderer(" + id + ")";
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-    
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    int x = (Integer) buf.getMetadata(TARGET_X);
-    int y = (Integer) buf.getMetadata(TARGET_Y);
-    int width = (Integer) buf.getMetadata(WIDTH);
-    int height = (Integer) buf.getMetadata(HEIGHT);
-    int srcX = (Integer) buf.getMetadata(SRC_X);
-    int srcY = (Integer) buf.getMetadata(SRC_Y);
-    buf.unref();
-
-    // Copy image
-    canvas.getOfflineGraphics().copyArea(srcX, srcY, width, height, x - srcX, y - srcY);
-
-    // Request update of repainted area
-    canvas.repaint(x, y, width, height);
-  }
-
-  public static void main(String args[]) {
-    System.setProperty("streamer.Element.debug", "true");
-
-    BufferedImageCanvas canvas = new BufferedImageCanvas(4, 4);
-
-    Element renderer = new BufferedImageCopyRectAdapter("renderer", canvas);
-
-    int[] pixelsBeforeCopy = new int[] {
-        // 0
-        1, 2, 3, 4,
-        // 1
-        5, 6, 7, 8,
-        // 2
-        9, 10, 11, 12,
-        // 3
-        13, 14, 15, 16 };
-    int[] pixelsAfterCopy = new int[] {
-        // 0
-        11, 12, 3, 4,
-        // 1
-        15, 16, 7, 8,
-        // 2
-        9, 10, 11, 12,
-        // 3
-        13, 14, 15, 16 };
-
-    
-    // Initalize image
-    int[] data = ((DataBufferInt) canvas.getOfflineImage().getRaster().getDataBuffer()).getData();
-    System.arraycopy(pixelsBeforeCopy, 0, data, 0, pixelsBeforeCopy.length);
-    
-    ByteBuffer buf = new ByteBuffer(new byte[0]);
-    buf.putMetadata(TARGET_X, 0);
-    buf.putMetadata(TARGET_Y, 0);
-    buf.putMetadata(WIDTH, 2);
-    buf.putMetadata(HEIGHT, 2);
-    buf.putMetadata(SRC_X, 2);
-    buf.putMetadata(SRC_Y, 2);
-
-    renderer.handleData(buf, null);
-
-    data = ((DataBufferInt) canvas.getOfflineImage().getRaster().getDataBuffer()).getData();
-    String actualData = Arrays.toString(data);
-    String expectedData = Arrays.toString(pixelsAfterCopy);
-    if (!actualData.equals(expectedData))
-      System.err.println("Actual image:   " + actualData + "\nExpected image: " + expectedData + ".");
-
-  }
+    public static final String SRC_X = "srcX";
+    public static final String SRC_Y = "srcY";
+    public static final String TARGET_X = "x";
+    public static final String TARGET_Y = "y";
+    public static final String WIDTH = "width";
+    public static final String HEIGHT = "height";
+
+    protected BufferedImageCanvas canvas;
+
+    public BufferedImageCopyRectAdapter(String id, BufferedImageCanvas canvas) {
+        super(id);
+        this.canvas = canvas;
+        declarePads();
+    }
+
+    private void declarePads() {
+        inputPads.put(STDIN, null);
+    }
+
+    public String toString() {
+        return "Renderer(" + id + ")";
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        int x = (Integer)buf.getMetadata(TARGET_X);
+        int y = (Integer)buf.getMetadata(TARGET_Y);
+        int width = (Integer)buf.getMetadata(WIDTH);
+        int height = (Integer)buf.getMetadata(HEIGHT);
+        int srcX = (Integer)buf.getMetadata(SRC_X);
+        int srcY = (Integer)buf.getMetadata(SRC_Y);
+        buf.unref();
+
+        // Copy image
+        canvas.getOfflineGraphics().copyArea(srcX, srcY, width, height, x - srcX, y - srcY);
+
+        // Request update of repainted area
+        canvas.repaint(x, y, width, height);
+    }
+
+    public static void main(String args[]) {
+        System.setProperty("streamer.Element.debug", "true");
+
+        BufferedImageCanvas canvas = new BufferedImageCanvas(4, 4);
+
+        Element renderer = new BufferedImageCopyRectAdapter("renderer", canvas);
+
+        int[] pixelsBeforeCopy = new int[] {
+                // 0
+                1, 2, 3, 4,
+                // 1
+                5, 6, 7, 8,
+                // 2
+                9, 10, 11, 12,
+                // 3
+                13, 14, 15, 16};
+        int[] pixelsAfterCopy = new int[] {
+                // 0
+                11, 12, 3, 4,
+                // 1
+                15, 16, 7, 8,
+                // 2
+                9, 10, 11, 12,
+                // 3
+                13, 14, 15, 16};
+
+        // Initalize image
+        int[] data = ((DataBufferInt)canvas.getOfflineImage().getRaster().getDataBuffer()).getData();
+        System.arraycopy(pixelsBeforeCopy, 0, data, 0, pixelsBeforeCopy.length);
+
+        ByteBuffer buf = new ByteBuffer(new byte[0]);
+        buf.putMetadata(TARGET_X, 0);
+        buf.putMetadata(TARGET_Y, 0);
+        buf.putMetadata(WIDTH, 2);
+        buf.putMetadata(HEIGHT, 2);
+        buf.putMetadata(SRC_X, 2);
+        buf.putMetadata(SRC_Y, 2);
+
+        renderer.handleData(buf, null);
+
+        data = ((DataBufferInt)canvas.getOfflineImage().getRaster().getDataBuffer()).getData();
+        String actualData = Arrays.toString(data);
+        String expectedData = Arrays.toString(pixelsAfterCopy);
+        if (!actualData.equals(expectedData))
+            System.err.println("Actual image:   " + actualData + "\nExpected image: " + expectedData + ".");
+
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java
old mode 100644
new mode 100755
index 95e7738..06e41af
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java
@@ -28,120 +28,120 @@ import streamer.Link;
 
 public class BufferedImagePixelsAdapter extends BaseElement {
 
-  public static final String TARGET_X = "x";
-  public static final String TARGET_Y = "y";
-  public static final String WIDTH = "width";
-  public static final String HEIGHT = "height";
-  public static final String RGB888LE32 = "RGB888LE32";
-  public static final String PIXEL_FORMAT = "pixel_format";
-
-  protected BufferedImageCanvas canvas;
-
-  public BufferedImagePixelsAdapter(String id, BufferedImageCanvas canvas) {
-    super(id);
-    this.canvas = canvas;
-    declarePads();
-  }
+    public static final String TARGET_X = "x";
+    public static final String TARGET_Y = "y";
+    public static final String WIDTH = "width";
+    public static final String HEIGHT = "height";
+    public static final String RGB888LE32 = "RGB888LE32";
+    public static final String PIXEL_FORMAT = "pixel_format";
+
+    protected BufferedImageCanvas canvas;
+
+    public BufferedImagePixelsAdapter(String id, BufferedImageCanvas canvas) {
+        super(id);
+        this.canvas = canvas;
+        declarePads();
+    }
 
-  private void declarePads() {
-    inputPads.put(STDIN, null);
-  }
+    private void declarePads() {
+        inputPads.put(STDIN, null);
+    }
 
-  public String toString() {
-    return "Renderer(" + id + ")";
-  }
+    public String toString() {
+        return "Renderer(" + id + ")";
+    }
 
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
 
-    int x = (Integer) buf.getMetadata(TARGET_X);
-    int y = (Integer) buf.getMetadata(TARGET_Y);
-    int rectWidth = (Integer) buf.getMetadata(WIDTH);
-    int rectHeight = (Integer) buf.getMetadata(HEIGHT);
-    String format = (String) buf.getMetadata(PIXEL_FORMAT);
+        int x = (Integer)buf.getMetadata(TARGET_X);
+        int y = (Integer)buf.getMetadata(TARGET_Y);
+        int rectWidth = (Integer)buf.getMetadata(WIDTH);
+        int rectHeight = (Integer)buf.getMetadata(HEIGHT);
+        String format = (String)buf.getMetadata(PIXEL_FORMAT);
 
-    int bpp;
-    // Support RGB888/32 little endian only
-    if (format != null && RGB888LE32.equals(format)) {
-      bpp = 4;
-      // TODO: support more formats
-    } else
-      throw new RuntimeException("Unsupported format: " + format + ". Supported formats: " + RGB888LE32 + ".");
+        int bpp;
+        // Support RGB888/32 little endian only
+        if (format != null && RGB888LE32.equals(format)) {
+            bpp = 4;
+            // TODO: support more formats
+        } else
+            throw new RuntimeException("Unsupported format: " + format + ". Supported formats: " + RGB888LE32 + ".");
 
-    int dataLength = rectWidth * rectHeight * bpp;
-    if (!cap(buf, dataLength, dataLength, link, false))
-      return;
+        int dataLength = rectWidth * rectHeight * bpp;
+        if (!cap(buf, dataLength, dataLength, link, false))
+            return;
 
-    // Draw rectangle on offline buffer
-    BufferedImage image = canvas.getOfflineImage();
+        // Draw rectangle on offline buffer
+        BufferedImage image = canvas.getOfflineImage();
 
-    DataBuffer dataBuf = image.getRaster().getDataBuffer();
+        DataBuffer dataBuf = image.getRaster().getDataBuffer();
 
-    switch (dataBuf.getDataType()) {
+        switch (dataBuf.getDataType()) {
 
-    case DataBuffer.TYPE_INT: {
+        case DataBuffer.TYPE_INT: {
 
-      // Convert array of bytes to array of int's
-      int[] intArray = buf.toIntLEArray();
+            // Convert array of bytes to array of int's
+            int[] intArray = buf.toIntLEArray();
 
-      // We chose RGB888 model, so Raster will use DataBufferInt type
-      DataBufferInt dataBuffer = (DataBufferInt) dataBuf;
+            // We chose RGB888 model, so Raster will use DataBufferInt type
+            DataBufferInt dataBuffer = (DataBufferInt)dataBuf;
 
-      int imageWidth = image.getWidth();
-      int imageHeight = image.getHeight();
+            int imageWidth = image.getWidth();
+            int imageHeight = image.getHeight();
 
-      // Paint rectangle directly on buffer, line by line
-      int[] imageBuffer = dataBuffer.getData();
+            // Paint rectangle directly on buffer, line by line
+            int[] imageBuffer = dataBuffer.getData();
 
-      for (int srcLine = 0, dstLine = y; srcLine < rectHeight && dstLine < imageHeight; srcLine++, dstLine++) {
-        try {
-          System.arraycopy(intArray, srcLine * rectWidth, imageBuffer, x + dstLine * imageWidth, rectWidth);
-        } catch (IndexOutOfBoundsException e) {
+            for (int srcLine = 0, dstLine = y; srcLine < rectHeight && dstLine < imageHeight; srcLine++, dstLine++) {
+                try {
+                    System.arraycopy(intArray, srcLine * rectWidth, imageBuffer, x + dstLine * imageWidth, rectWidth);
+                } catch (IndexOutOfBoundsException e) {
+                }
+            }
+            break;
         }
-      }
-      break;
-    }
 
-    default:
-      throw new RuntimeException("Unsupported data buffer in buffered image: expected data buffer of type int (DataBufferInt). Actual data buffer type: "
-          + dataBuf.getClass().getSimpleName());
-    }
+        default:
+            throw new RuntimeException("Unsupported data buffer in buffered image: expected data buffer of type int (DataBufferInt). Actual data buffer type: "
+                    + dataBuf.getClass().getSimpleName());
+        }
 
-    // Request update of repainted area
-    canvas.repaint(x, y, rectWidth, rectHeight);
+        // Request update of repainted area
+        canvas.repaint(x, y, rectWidth, rectHeight);
 
-    buf.unref();
-  }
+        buf.unref();
+    }
 
-  public static void main(String args[]) {
-    System.setProperty("streamer.Element.debug", "true");
+    public static void main(String args[]) {
+        System.setProperty("streamer.Element.debug", "true");
 
-    BufferedImageCanvas canvas = new BufferedImageCanvas(4, 4);
+        BufferedImageCanvas canvas = new BufferedImageCanvas(4, 4);
 
-    Element renderer = new BufferedImagePixelsAdapter("renderer", canvas);
+        Element renderer = new BufferedImagePixelsAdapter("renderer", canvas);
 
-    byte[] pixels = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5,
-        6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+        byte[] pixels = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5,
+                6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
 
-    int[] pixelsLE = new int[] { 0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d, 0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d, 0x04030201, 0x08070605,
-        0x0c0b0a09, 0x100f0e0d, 0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d };
+        int[] pixelsLE = new int[] {0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d, 0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d, 0x04030201, 0x08070605,
+                0x0c0b0a09, 0x100f0e0d, 0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d};
 
-    ByteBuffer buf = new ByteBuffer(pixels);
-    buf.putMetadata(TARGET_X, 0);
-    buf.putMetadata(TARGET_Y, 0);
-    buf.putMetadata(WIDTH, 4);
-    buf.putMetadata(HEIGHT, 4);
-    buf.putMetadata(PIXEL_FORMAT, RGB888LE32);
+        ByteBuffer buf = new ByteBuffer(pixels);
+        buf.putMetadata(TARGET_X, 0);
+        buf.putMetadata(TARGET_Y, 0);
+        buf.putMetadata(WIDTH, 4);
+        buf.putMetadata(HEIGHT, 4);
+        buf.putMetadata(PIXEL_FORMAT, RGB888LE32);
 
-    renderer.handleData(buf, null);
+        renderer.handleData(buf, null);
 
-    String actualData = Arrays.toString(((DataBufferInt) canvas.getOfflineImage().getRaster().getDataBuffer()).getData());
-    String expectedData = Arrays.toString(pixelsLE);
-    if (!actualData.equals(expectedData))
-      System.err.println("Actual image:   " + actualData + "\nExpected image: " + expectedData + ".");
+        String actualData = Arrays.toString(((DataBufferInt)canvas.getOfflineImage().getRaster().getDataBuffer()).getData());
+        String expectedData = Arrays.toString(pixelsLE);
+        if (!actualData.equals(expectedData))
+            System.err.println("Actual image:   " + actualData + "\nExpected image: " + expectedData + ".");
 
-  }
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/Client.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/Client.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/Client.java
old mode 100644
new mode 100755
index 343fe0a..b590018
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/Client.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/Client.java
@@ -22,116 +22,353 @@ import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.awt.event.WindowListener;
 import java.net.InetSocketAddress;
+import java.util.Arrays;
 
 import rdpclient.RdpClient;
 import streamer.Element;
 import streamer.Pipeline;
 import streamer.PipelineImpl;
 import streamer.SocketWrapper;
+import streamer.SocketWrapperImpl;
+import streamer.apr.AprSocketWrapperImpl;
+import streamer.bco.BcoSocketWrapperImpl;
+import streamer.ssl.SSLState;
 import vncclient.VncClient;
 
+import common.opt.IntOption;
+import common.opt.Option;
+import common.opt.OptionParser;
+import common.opt.StringEnumerationOption;
+import common.opt.StringOption;
+
 public class Client {
 
-  private static Frame frame;
-  private static SocketWrapper socket;
-  private static ScrollPane scroller;
-  private static ScreenDescription screen;
-  private static BufferedImageCanvas canvas;
-
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    // System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    try {
-      if (args.length < 4) {
-        System.out.println("Usage: \n  java common.Client vnc IP PORT PASSWORD\n  java common.Client rdp IP PORT username\n");
-        System.exit(0);
-      }
-
-      String connectionType = args[0];
-      String hostname = args[1];
-      int port = Integer.parseInt(args[2]);
-      String userNameOrPassword = args[3];
-
-      // Create address from arguments
-      InetSocketAddress address = new InetSocketAddress(hostname, port);
-
-      // Create socket wrapper
-      socket = new SocketWrapper("socket");
-
-      screen = new ScreenDescription();
-      canvas = new BufferedImageCanvas(1024, 768);
-      screen.addSizeChangeListener(new SizeChangeListener() {
-        @Override
-        public void sizeChanged(int width, int height) {
-          if (canvas != null) {
-            canvas.setCanvasSize(width, height);
-            if (scroller != null)
-              scroller.setSize(canvas.getWidth(), canvas.getHeight());
-          }
-        }
-      });
-
-      // Assemble pipeline
-      Element main;
-      if ("vnc".equals(connectionType)) {
-        main = new VncClient("client", userNameOrPassword, screen, canvas);
-      } else if ("rdp".equals(connectionType)) {
-        main = new RdpClient("client", userNameOrPassword, screen, canvas);
-      } else {
-        throw new RuntimeException("Unknown connection type. Expected value: \"vnc\" or \"rdp\", actual value: \"" + connectionType + "\".");
-      }
-
-      Pipeline pipeline = new PipelineImpl("Client");
-      pipeline.add(socket, main);
-      pipeline.link("socket", main.getId(), "socket");
-
-      pipeline.validate();
-      
-      frame = createVncClientMainWindow(canvas, "VNC", new WindowAdapter() {
-        public void windowClosing(WindowEvent evt) {
-          shutdown();
-        }
-      });
-
-      try {
-        // Connect socket to remote server and run main loop(s)
-        socket.connect(address);
-      } finally {
-        shutdown();
-      }
-
-    } catch (Exception e) {
-      e.printStackTrace(System.err);
+    enum Protocol {
+        NONE, VNC, RDP, HYPERV
     }
-  }
 
-  protected static void shutdown() {
-    if (frame != null) {
-      frame.setVisible(false);
-      frame.dispose();
+    // Common options
+    private Option help = new Option() {
+        {
+            name = "--help";
+            alias = "-h";
+            description = "Show this help text.";
+        }
+    };
+    private Option debugLink = new Option() {
+        {
+            name = "--debug-link";
+            alias = "-DL";
+            description = "Print debugging messages when packets are trasnferred via links.";
+        }
+    };
+    private Option debugElement = new Option() {
+        {
+            name = "--debug-element";
+            alias = "-DE";
+            description = "Print debugging messages when packets are received or sended by elements.";
+        }
+    };
+    private Option debugPipeline = new Option() {
+        {
+            name = "--debug-pipeline";
+            alias = "-DP";
+            description = "Print debugging messages in pipelines.";
+        }
+    };
+
+    private StringOption hostName = new StringOption() {
+        {
+            name = "--host";
+            alias = "-n";
+            aliases = new String[] {"--host-name"};
+            required = true;
+            description = "Name or IP address of host to connect to.";
+        }
+    };
+    private IntOption canvasWidth = new IntOption() {
+        {
+            name = "--width";
+            alias = "-W";
+            value = 1024;
+            description = "Width of canvas.";
+        }
+    };
+
+    private IntOption canvasHeight = new IntOption() {
+        {
+            name = "--height";
+            alias = "-H";
+            value = 768;
+            description = "Height of canvas.";
+        }
+    };
+
+    // Protocol specific options
+
+    private IntOption vncPort = new IntOption() {
+        {
+            name = "--port";
+            alias = "-p";
+            value = 5901;
+            description = "Port of VNC display server to connect to. Calculate as 5900 + display number, e.g. 5900 for display #0, 5901 for display #1, and so on.";
+        }
+    };
+
+    private IntOption rdpPort = new IntOption() {
+        {
+            name = "--port";
+            alias = "-p";
+            value = 3389;
+            description = "Port of RDP server to connect to.";
+        }
+    };
+
+    private IntOption hyperVPort = new IntOption() {
+        {
+            name = "--port";
+            alias = "-p";
+            value = 2179;
+            description = "Port of HyperV server to connect to.";
+        }
+    };
+
+    private StringOption password = new StringOption() {
+        {
+            name = "--password";
+            alias = "-P";
+            required = true;
+            description = "Password to use.";
+        }
+    };
+
+    private StringOption rdpPassword = new StringOption() {
+        {
+            name = "--password";
+            alias = "-P";
+            required = false;
+            description = "Password to use. If omitted, then login screen will be shown.";
+        }
+    };
+
+    private StringOption userName = new StringOption() {
+        {
+            name = "--user";
+            alias = "-U";
+            value = "Administrator";
+            description = "User name to use.";
+        }
+    };
+
+    private StringOption domain = new StringOption() {
+        {
+            name = "--domain";
+            alias = "-D";
+            value = "Workgroup";
+            description = "NTLM domain to login into.";
+        }
+    };
+
+    private StringOption hyperVInstanceId = new StringOption() {
+        {
+            name = "--instance";
+            alias = "-i";
+            required = true;
+            description = "HyperV instance ID to use.";
+        }
+    };
+    private StringEnumerationOption sslImplementation = new StringEnumerationOption() {
+        {
+            name = "--ssl-implementation";
+            alias = "-j";
+            value = "apr";
+            choices = new String[] {"jre", "apr", "bco"};
+            description = "Select SSL engine to use: JRE standard implementation, Apache Portable Runtime native library, BonuncyCastle.org implementation.";
+        }
+    };
+
+    private final Option[] commonOptions = new Option[] {help, debugLink, debugElement, debugPipeline, hostName, canvasWidth, canvasHeight};
+    private final Option[] vncOptions = new Option[] {vncPort, password};
+    private final Option[] rdpOptions = new Option[] {sslImplementation, rdpPort, domain, userName, rdpPassword};
+    private final Option[] hyperVOptions = new Option[] {sslImplementation, hyperVPort, hyperVInstanceId, domain, userName, password};
+
+    private static Frame frame;
+    private static SocketWrapper socket;
+    private static ScrollPane scroller;
+    private static ScreenDescription screen;
+    private static BufferedImageCanvas canvas;
+
+    private void help() {
+        System.out.println("Usage: \n  java common.Client vnc|rdp|hyperv OPTIONS\n");
+        System.out.println(Option.toHelp("Common options", commonOptions));
+        System.out.println(Option.toHelp("VNC options", vncOptions));
+        System.out.println(Option.toHelp("RDP options", rdpOptions));
+        System.out.println(Option.toHelp("HyperV options", hyperVOptions));
     }
-    if (socket != null)
-      socket.shutdown();
-  }
 
-  protected static Frame createVncClientMainWindow(BufferedImageCanvas canvas, String title, WindowListener windowListener) {
-    // Create AWT windows
-    Frame frame = new Frame(title + " - RDP");
+    public void runClient(String[] args) {
+
+        try {
+
+            Protocol protocol = parseOptions(args);
+            if (protocol == Protocol.NONE)
+                return;
 
-    // Use scrolling pane to support screens, which are larger than ours
-    scroller = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
-    scroller.add(canvas);
-    scroller.setSize(canvas.getWidth(), canvas.getHeight());
+            System.setProperty("streamer.Link.debug", "" + debugLink.used);
+            System.setProperty("streamer.Element.debug", "" + debugElement.used);
+            System.setProperty("streamer.Pipeline.debug", "" + debugPipeline.used);
 
-    frame.add(scroller);
-    frame.pack();
-    frame.setVisible(true);
+            SSLState sslState = new SSLState();
 
-    frame.addWindowListener(windowListener);
+            // Create socket wrapper
+            if ("jre".equals(sslImplementation.value)) {
+                socket = new SocketWrapperImpl("socket", sslState);
+            } else if ("apr".equals(sslImplementation.value)) {
+                socket = new AprSocketWrapperImpl("socket", sslState);
+            } else if ("bco".equals(sslImplementation.value)) {
+                socket = new BcoSocketWrapperImpl("socket", sslState);
+            } else {
+                throw new RuntimeException("Unexpected option value: \"" + sslImplementation.value + "\". " + sslImplementation.help());
+            }
 
-    return frame;
-  }
+            screen = new ScreenDescription();
+            canvas = new BufferedImageCanvas(canvasWidth.value, canvasHeight.value);
+            screen.addSizeChangeListener(new SizeChangeListener() {
+                @Override
+                public void sizeChanged(int width, int height) {
+                    if (canvas != null) {
+                        canvas.setCanvasSize(width, height);
+                        if (scroller != null)
+                            scroller.setSize(canvas.getWidth(), canvas.getHeight());
+                    }
+                }
+            });
 
+            // Assemble pipeline
+            InetSocketAddress address;
+            Element main;
+            switch (protocol) {
+            case VNC:
+                address = new InetSocketAddress(hostName.value, vncPort.value);
+                main = new VncClient("client", password.value, screen, canvas);
+                break;
+            case RDP:
+                address = new InetSocketAddress(hostName.value, rdpPort.value);
+                main = new RdpClient("client", hostName.value, domain.value, userName.value, rdpPassword.value, null, screen, canvas, sslState);
+                break;
+            case HYPERV:
+                address = new InetSocketAddress(hostName.value, hyperVPort.value);
+                main = new RdpClient("client", hostName.value, domain.value, userName.value, password.value, hyperVInstanceId.value, screen, canvas, sslState);
+                break;
+            default:
+                address = null;
+                main = null;
+            }
+
+            Pipeline pipeline = new PipelineImpl("Client");
+            pipeline.add(socket, main);
+            pipeline.link("socket", main.getId(), "socket");
+
+            pipeline.validate();
+
+            frame = createVncClientMainWindow(canvas, protocol.toString() + " " + hostName.value, new WindowAdapter() {
+                public void windowClosing(WindowEvent evt) {
+                    shutdown();
+                }
+            });
+
+            try {
+                // Connect socket to remote server and run main loop(s)
+                socket.connect(address);
+            } finally {
+                shutdown();
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace(System.err);
+        }
+    }
+
+    private Protocol parseOptions(String[] args) {
+        String protocolName = (args.length > 0) ? args[0] : "";
+        Protocol protocol = Protocol.NONE;
+
+        Option[] options;
+        if (protocolName.equals("vnc")) {
+            protocol = Protocol.VNC;
+            options = join(commonOptions, vncOptions);
+        } else if (protocolName.equals("rdp")) {
+            protocol = Protocol.RDP;
+            options = join(commonOptions, rdpOptions);
+        } else if (protocolName.equals("hyperv")) {
+            protocol = Protocol.HYPERV;
+            options = join(commonOptions, hyperVOptions);
+        } else {
+            help();
+            return Protocol.NONE;
+        }
+
+        // Parse all options for given protocol
+        String[] arguments = OptionParser.parseOptions(args, 1, options);
+
+        if (arguments.length > 0) {
+            System.err.println("[Client] ERROR: Arguments are not allowed here. Check command syntax. Extra arguments: \"" + Arrays.toString(arguments) + "\".");
+            help();
+            return Protocol.NONE;
+        }
+
+        if (help.used) {
+            help();
+            return Protocol.NONE;
+        }
+        return protocol;
+    }
+
+    protected static void shutdown() {
+        if (frame != null) {
+            frame.setVisible(false);
+            frame.dispose();
+        }
+        if (socket != null)
+            socket.shutdown();
+    }
+
+    protected static Frame createVncClientMainWindow(BufferedImageCanvas canvas, String title, WindowListener windowListener) {
+        // Create AWT windows
+        Frame frame = new Frame(title + " - RDP");
+
+        // Use scrolling pane to support screens, which are larger than ours
+        scroller = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
+        scroller.add(canvas);
+        scroller.setSize(canvas.getWidth(), canvas.getHeight());
+
+        frame.add(scroller);
+        frame.pack();
+        frame.setVisible(true);
+
+        frame.addWindowListener(windowListener);
+
+        return frame;
+    }
+
+    /**
+     * Join two arrays with options and return new array.
+     */
+    private Option[] join(Option[] a1, Option[] a2) {
+        // Extend first array
+        Option[] result = Arrays.copyOf(a1, a1.length + a2.length);
+
+        // Append second array to first
+        for (int i = 0, p = a1.length; i < a2.length; i++, p++)
+            result[p] = a2[i];
+
+        return result;
+    }
+
+    public static void main(String args[]) {
+        // *DEBUG*/System.setProperty("javax.net.debug", "ssl");
+        // * DEBUG */System.setProperty("javax.net.debug", "ssl:record:packet");
+
+        new Client().runClient(args);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/CopyRectOrder.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/CopyRectOrder.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/CopyRectOrder.java
old mode 100644
new mode 100755
index 5f0c0f7..870a347
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/CopyRectOrder.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/CopyRectOrder.java
@@ -16,24 +16,23 @@
 // under the License.
 package common;
 
-
 import streamer.Order;
 
 public class CopyRectOrder extends Order {
-  public int srcX;
-  public int srcY;
-  public int width;
-  public int height;
-  public int x;
-  public int y;
+    public int srcX;
+    public int srcY;
+    public int width;
+    public int height;
+    public int x;
+    public int y;
 
-  public CopyRectOrder() {
-    type = OrderType.COPY_RECT;
-  }
+    public CopyRectOrder() {
+        type = OrderType.COPY_RECT;
+    }
 
-  @Override
-  public String toString() {
-    return "CopyRectOrder [srcX=" + srcX + ", srcY=" + srcY + ", width=" + width + ", height=" + height + ", x=" + x + ", y=" + y + "]";
-  }
+    @Override
+    public String toString() {
+        return "CopyRectOrder [srcX=" + srcX + ", srcY=" + srcY + ", width=" + width + ", height=" + height + ", x=" + x + ", y=" + y + "]";
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/KeyOrder.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/KeyOrder.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/KeyOrder.java
old mode 100644
new mode 100755
index 726d8a0..5630b35
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/KeyOrder.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/KeyOrder.java
@@ -21,25 +21,24 @@ import java.awt.event.KeyEvent;
 import streamer.Order;
 
 public class KeyOrder extends Order {
-  public KeyOrder() {
-    type = "key event";
-  }
-
-  public KeyOrder(KeyEvent event, boolean pressed) {
-    type = "key event";
-    
-    this.event = event;
-    this.pressed = pressed;
-  }
-
-  public KeyEvent event;
-  
-  public boolean pressed;
-
-  @Override
-  public String toString() {
-    return "KeyOrder [event=" + event + ", pressed=" + pressed + "]";
-  }
-  
-  
+    public KeyOrder() {
+        type = "key event";
+    }
+
+    public KeyOrder(KeyEvent event, boolean pressed) {
+        type = "key event";
+
+        this.event = event;
+        this.pressed = pressed;
+    }
+
+    public KeyEvent event;
+
+    public boolean pressed;
+
+    @Override
+    public String toString() {
+        return "KeyOrder [event=" + event + ", pressed=" + pressed + "]";
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/MouseOrder.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/MouseOrder.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/MouseOrder.java
old mode 100644
new mode 100755
index d6670fa..6c77a87
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/MouseOrder.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/MouseOrder.java
@@ -22,20 +22,21 @@ import streamer.Order;
 
 public class MouseOrder extends Order {
 
-  public MouseOrder() {
-    type = "mouse order";
-  }
+    public MouseOrder() {
+        type = "mouse order";
+    }
 
-  public MouseOrder(MouseEvent event) {
-    type = "mouse order";
-    this.event = event;
-  }
+    public MouseOrder(MouseEvent event) {
+        type = "mouse order";
+        this.event = event;
+    }
 
-  public MouseEvent event;
-  public boolean pressed;
-  public boolean released;
-  @Override
-  public String toString() {
-    return "MouseOrder [event=" + event + ", pressed=" + pressed + ", released=" + released + "]";
-  }
+    public MouseEvent event;
+    public boolean pressed;
+    public boolean released;
+
+    @Override
+    public String toString() {
+        return "MouseOrder [event=" + event + ", pressed=" + pressed + ", released=" + released + "]";
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/OrderType.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/OrderType.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/OrderType.java
old mode 100644
new mode 100755
index 1e77ea9..1c8c425
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/OrderType.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/OrderType.java
@@ -17,6 +17,6 @@
 package common;
 
 public enum OrderType {
-  BITMAP_UPDATE, COPY_RECT,
+    BITMAP_UPDATE, COPY_RECT,
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/ScreenDescription.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/ScreenDescription.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/ScreenDescription.java
old mode 100644
new mode 100755
index a01f22e..86fad47
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/ScreenDescription.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/ScreenDescription.java
@@ -24,145 +24,145 @@ import java.util.Set;
  * VncScreenDescription - contains information about remote VNC screen.
  */
 public class ScreenDescription {
-  
-  protected Set<SizeChangeListener> sizeChangeListeners = new HashSet<SizeChangeListener>();
-
-  // Frame buffer size
-  protected int framebufferWidth = -1;
-  protected int framebufferHeight = -1;
-
-  // Desktop name
-  protected String desktopName = null;
-
-  // Bytes per pixel
-  protected int bytesPerPixel;
-  protected int colorDepth;
-  protected int bitsPerPixel;
-  protected int redShift;
-  protected int greenShift;
-  protected int blueShift;
-  protected int redMax;
-  protected int greenMax;
-  protected int blueMax;
-  protected boolean bigEndianFlag;
-  protected boolean trueColorFlag;
-
-  public IndexColorModel colorMap = null;
-
-  public ScreenDescription() {
-  }
-
-  /**
-   * Store information about server pixel format.
-   */
-  public void setPixelFormat(int bitsPerPixel, int depth, boolean bigEndianFlag, boolean trueColorFlag, int redMax, int greenMax, int blueMax, int redShift,
-      int greenShift, int blueShift) {
-
-    this.bytesPerPixel = (bitsPerPixel + 7) / 8;
-
-    this.bitsPerPixel = bitsPerPixel;
-    this.colorDepth = depth;
-    this.bigEndianFlag = bigEndianFlag;
-    this.trueColorFlag = trueColorFlag;
-
-    this.redMax = redMax;
-    this.greenMax = greenMax;
-    this.blueMax = blueMax;
-    this.redShift = redShift;
-    this.greenShift = greenShift;
-    this.blueShift = blueShift;
-  }
-
-  /**
-   * Store information about server pixel format.
-   */
-  public void setPixelFormatRGBTrueColor(int bitsPerPixel) {
-
-    switch(bitsPerPixel) {
-    case 8:
-      setPixelFormat(8, 8, false, false, -1, -1, -1, -1, -1, -1);
-      break;
-    case 15:
-      setPixelFormat(16, 15, false, true, 31, 31, 31, 0, 5, 10);
-      break;
-    case 16:
-      setPixelFormat(16, 16, false, true, 31, 63, 31, 0, 5, 11);
-      break;
-    case 24:
-      setPixelFormat(24, 24, false, true, 255, 255, 255, 0, 8, 16);
-      break;
-    case 32:
-      setPixelFormat(32, 24, false, true, 255, 255, 255, 0, 8, 16);
-      break;
-    default:
-      throw new RuntimeException("Unknown color depth.");
+
+    protected Set<SizeChangeListener> sizeChangeListeners = new HashSet<SizeChangeListener>();
+
+    // Frame buffer size
+    protected int framebufferWidth = -1;
+    protected int framebufferHeight = -1;
+
+    // Desktop name
+    protected String desktopName = null;
+
+    // Bytes per pixel
+    protected int bytesPerPixel;
+    protected int colorDepth;
+    protected int bitsPerPixel;
+    protected int redShift;
+    protected int greenShift;
+    protected int blueShift;
+    protected int redMax;
+    protected int greenMax;
+    protected int blueMax;
+    protected boolean bigEndianFlag;
+    protected boolean trueColorFlag;
+
+    public IndexColorModel colorMap = null;
+
+    public ScreenDescription() {
+    }
+
+    /**
+     * Store information about server pixel format.
+     */
+    public void setPixelFormat(int bitsPerPixel, int depth, boolean bigEndianFlag, boolean trueColorFlag, int redMax, int greenMax, int blueMax, int redShift,
+            int greenShift, int blueShift) {
+
+        this.bytesPerPixel = (bitsPerPixel + 7) / 8;
+
+        this.bitsPerPixel = bitsPerPixel;
+        this.colorDepth = depth;
+        this.bigEndianFlag = bigEndianFlag;
+        this.trueColorFlag = trueColorFlag;
+
+        this.redMax = redMax;
+        this.greenMax = greenMax;
+        this.blueMax = blueMax;
+        this.redShift = redShift;
+        this.greenShift = greenShift;
+        this.blueShift = blueShift;
     }
 
-  }
+    /**
+     * Store information about server pixel format.
+     */
+    public void setPixelFormatRGBTrueColor(int bitsPerPixel) {
+
+        switch (bitsPerPixel) {
+        case 8:
+            setPixelFormat(8, 8, false, false, -1, -1, -1, -1, -1, -1);
+            break;
+        case 15:
+            setPixelFormat(16, 15, false, true, 31, 31, 31, 0, 5, 10);
+            break;
+        case 16:
+            setPixelFormat(16, 16, false, true, 31, 63, 31, 0, 5, 11);
+            break;
+        case 24:
+            setPixelFormat(24, 24, false, true, 255, 255, 255, 0, 8, 16);
+            break;
+        case 32:
+            setPixelFormat(32, 24, false, true, 255, 255, 255, 0, 8, 16);
+            break;
+        default:
+            throw new RuntimeException("Unknown color depth.");
+        }
 
-  /**
-   * Store information about server screen size.
-   */
-  public void setFramebufferSize(int width, int height) {
-    if (height <= 0 || width <= 0)
-      throw new RuntimeException("Incorrect framebuffer size: " + width + "x" + height + ".");
+    }
+
+    /**
+     * Store information about server screen size.
+     */
+    public void setFramebufferSize(int width, int height) {
+        if (height <= 0 || width <= 0)
+            throw new RuntimeException("Incorrect framebuffer size: " + width + "x" + height + ".");
+
+        this.framebufferWidth = width;
+        this.framebufferHeight = height;
+
+        callSizeChangeListeners(width, height);
+    }
+
+    protected void callSizeChangeListeners(int width, int height) {
+        for (SizeChangeListener listener : sizeChangeListeners) {
+            listener.sizeChanged(width, height);
+        }
+    }
 
-    this.framebufferWidth = width;
-    this.framebufferHeight = height;
-    
-    callSizeChangeListeners(width, height);
-  }
+    /**
+     * Store server desktop name.
+     */
+    public void setDesktopName(String desktopName) {
+        this.desktopName = desktopName;
+    }
+
+    // Getters for variables, as usual
+
+    public String getDesktopName() {
+        return desktopName;
+    }
+
+    public int getBytesPerPixel() {
+        return bytesPerPixel;
+    }
+
+    public int getFramebufferHeight() {
+        return framebufferHeight;
+    }
+
+    public int getFramebufferWidth() {
+        return framebufferWidth;
+    }
+
+    public boolean isRGB888_32_LE() {
+        return (colorDepth == 24 && bitsPerPixel == 32 && redShift == 0 && greenShift == 8 && blueShift == 16 && redMax == 255 && greenMax == 255 && blueMax == 255
+                && !bigEndianFlag && trueColorFlag);
+    }
+
+    @Override
+    public String toString() {
+        return "ScreenDescription [framebufferWidth=" + framebufferWidth + ", framebufferHeight=" + framebufferHeight + ", desktopName=" + desktopName
+                + ", bytesPerPixel=" + bytesPerPixel + ", depth=" + colorDepth + ", bitsPerPixel=" + bitsPerPixel + ", redShift=" + redShift + ", greenShift=" + greenShift
+                + ", blueShift=" + blueShift + ", redMax=" + redMax + ", greenMax=" + greenMax + ", blueMax=" + blueMax + ", bigEndianFlag=" + bigEndianFlag
+                + ", trueColorFlag=" + trueColorFlag + "]";
+    }
+
+    public void addSizeChangeListener(SizeChangeListener sizeChangeListener) {
+        sizeChangeListeners.add(sizeChangeListener);
+    }
 
-  protected void callSizeChangeListeners(int width, int height) {
-    for(SizeChangeListener listener:sizeChangeListeners) {
-      listener.sizeChanged(width, height);
+    public int getColorDeph() {
+        return colorDepth;
     }
-  }
-
-  /**
-   * Store server desktop name.
-   */
-  public void setDesktopName(String desktopName) {
-    this.desktopName = desktopName;
-  }
-
-  // Getters for variables, as usual
-
-  public String getDesktopName() {
-    return desktopName;
-  }
-
-  public int getBytesPerPixel() {
-    return bytesPerPixel;
-  }
-
-  public int getFramebufferHeight() {
-    return framebufferHeight;
-  }
-
-  public int getFramebufferWidth() {
-    return framebufferWidth;
-  }
-
-  public boolean isRGB888_32_LE() {
-    return (colorDepth == 24 && bitsPerPixel == 32 && redShift == 0 && greenShift == 8 && blueShift == 16 && redMax == 255 && greenMax == 255 && blueMax == 255
-        && !bigEndianFlag && trueColorFlag);
-  }
-
-  @Override
-  public String toString() {
-    return "ScreenDescription [framebufferWidth=" + framebufferWidth + ", framebufferHeight=" + framebufferHeight + ", desktopName=" + desktopName
-        + ", bytesPerPixel=" + bytesPerPixel + ", depth=" + colorDepth + ", bitsPerPixel=" + bitsPerPixel + ", redShift=" + redShift + ", greenShift=" + greenShift
-        + ", blueShift=" + blueShift + ", redMax=" + redMax + ", greenMax=" + greenMax + ", blueMax=" + blueMax + ", bigEndianFlag=" + bigEndianFlag
-        + ", trueColorFlag=" + trueColorFlag + "]";
-  }
-
-  public void addSizeChangeListener(SizeChangeListener sizeChangeListener) {
-    sizeChangeListeners.add(sizeChangeListener);
-  }
-
-  public int getColorDeph() {
-    return colorDepth;
-  }
 
 }


[11/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientConfirmActivePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientConfirmActivePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientConfirmActivePDU.java
new file mode 100755
index 0000000..9c0c52e
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientConfirmActivePDU.java
@@ -0,0 +1,1132 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+import common.ScreenDescription;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240488.aspx
+ */
+public class ClientConfirmActivePDU extends BaseElement {
+
+    public static final String SOURCE_DESC = "MSTSC";
+
+    public static final int CAPSTYPE_BITMAP = 0x2;
+
+    protected int numberCapabilities;
+
+    protected RdpState state;
+    protected ScreenDescription screen;
+
+    protected boolean desktopResize = false;
+    protected int prefferedBitsPerPixel = 16;
+
+    public ClientConfirmActivePDU(String id, ScreenDescription screen, RdpState state) {
+        super(id);
+        this.state = state;
+        this.screen = screen;
+    }
+
+    @Override
+    public void handleData(ByteBuffer aBuf, Link link) {
+
+        // Body
+        ByteBuffer buf = new ByteBuffer(1024, true);
+        numberCapabilities = 0;
+        writeCapabilities(buf);
+        buf.trimAtCursor();
+
+        // Header
+        ByteBuffer header = createMCSHeader(buf);
+
+        // Length of source descriptor, including NULL character (LE)
+        header.writeShortLE(SOURCE_DESC.length() + 1);
+
+        // Length of combined capabilities + 4 bytes (number of capabilities and
+        // padding) (LE)
+        header.writeShortLE(buf.length + 4);
+
+        header.writeString(SOURCE_DESC, RdpConstants.CHARSET_8);
+        header.writeByte(0);
+
+        // Number of capabilities
+        header.writeShortLE(numberCapabilities);
+
+        // Padding 2 bytes
+        header.writeShortLE(0);
+
+        header.trimAtCursor();
+
+        // Prepend header to capabilities
+        buf.prepend(header);
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToPad(STDOUT, buf);
+
+        sendOtherRequredPackets();
+
+    }
+
+    private ByteBuffer createMCSHeader(ByteBuffer buf) {
+        ByteBuffer header = new ByteBuffer(100);
+        // MCS Send Data Request
+        header.writeByte(0x64);
+
+        // Initiator: 1004 (1001+3)
+        header.writeShort(3);
+
+        // Channel ID: 1003 (I/O channel)
+        header.writeShort(RdpConstants.CHANNEL_IO);
+
+        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+        header.writeByte(0x70);
+
+        int length = buf.length + 26;
+
+        // User data length: (variable length field, LE)
+        header.writeVariableShort(length);
+
+        // Total length: (LE)
+        header.writeShortLE(length);
+
+        // PDU type: Confirm Active PDU (0x3), TS_PROTOCOL_VERSION (0x10) (LE)
+        header.writeShortLE(0x13);
+
+        // PDU source: 1004 (LE)
+        header.writeShortLE(1004);
+
+        // Share ID, e.g. 0x000103ea (LE)
+        header.writeIntLE((int)state.serverShareId);
+
+        // Originator ID: 1002 (LE)
+        header.writeShortLE(1002);
+        return header;
+    }
+
+    private void sendOtherRequredPackets() {
+        // Send sequence in bulk
+
+        sendSynchronizePDU();
+        sendControlPDUActionCooperate();
+        sendControlPDUActionRequestControl();
+        // sendBitmapCachePersistentListPDU();
+        sendFontListPDU();
+    }
+
+    private void sendFontListPDU() {
+        {
+            int length = 1024; // Large enough
+            ByteBuffer buf = new ByteBuffer(length, true);
+
+            /* @formatter:off */
+      buf.writeBytes(new byte[] {
+          // MCS Send Data Request
+          (byte)0x64,
+          // Initiator: 1004 (1001+3)
+          (byte)0x00, (byte)0x03, 
+          // Channel ID: 1003 (I/O channel)
+          (byte)0x03, (byte)0xeb, 
+          // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+          (byte)0x70, 
+          // User data length: 26 bytes (0x1a, variable length field)
+          (byte)0x80, (byte)0x1a,
+          
+          // Total length: 26 bytes (0x1a, LE)
+          (byte)0x1a, (byte)0x00, 
+          // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE)
+          (byte)0x17, (byte)0x00, 
+          // PDU source: 1004 (LE)
+          (byte)0xec, (byte)0x03, 
+      });
+      // Share ID, 4 bytes  (LE)
+      buf.writeIntLE((int)state.serverShareId);
+      
+      buf.writeBytes(new byte[] {
+          // Padding 1 byte
+          (byte)0x00, 
+          // Stream ID: STREAM_LOW (1)
+          (byte)0x01, 
+          // uncompressedLength : 12 bytes (LE)
+          (byte)0x0c, (byte)0x00,
+          
+          // pduType2: PDUTYPE2_FONTLIST (39)
+          (byte)0x27, 
+          // generalCompressedType: 0
+          (byte)0x00, 
+          // generalCompressedLength: 0 (LE)
+          (byte)0x00, (byte)0x00, 
+
+          // numberEntries (should be set to zero): 0 (LE)
+          (byte)0x00, (byte)0x00,
+          // totalNumEntries (should be set to zero): 0 (LE)
+          (byte)0x00, (byte)0x00,
+          // listFlags  (should be set to 0x3): 0x0003 (LE), FONTLIST_LAST(0x2) | FONTLIST_FIRST(0x1) 
+          (byte)0x03, (byte)0x00,
+          // entrySize: 50 bytes (0x0032, LE)
+          (byte)0x32, (byte)0x00,
+      });
+      /* @formatter:on */
+
+            // Trim buffer to actual length of data written
+            buf.trimAtCursor();
+
+            pushDataToPad(STDOUT, buf);
+        }
+    }
+
+    private void sendControlPDUActionRequestControl() {
+        int length = 1024; // Large enough
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        /* @formatter:off */
+    buf.writeBytes(new byte[] {
+        // MCS Send Data Request
+        (byte)0x64, 
+        // Initiator: 1004 (1001+3)
+        (byte)0x00, (byte)0x03,
+        // Channel ID: 1003 (I/O channel)
+        (byte)0x03, (byte)0xeb, 
+        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+        (byte)0x70, 
+        // User data length: 26 bytes (0x1a, variable length field)
+        (byte)0x80, (byte)0x1a,
+        
+        // Total length: 26 bytes (0x1a, LE)
+        (byte)0x1a, (byte)0x00,
+        // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE)
+        (byte)0x17, (byte)0x00, 
+        // PDU source: 1004 (LE)
+        (byte)0xec, (byte)0x03,
+    });
+        // Share ID, 4 bytes  (LE)
+    buf.writeIntLE((int)state.serverShareId);
+        
+    buf.writeBytes(new byte[] {
+        // Padding 1 byte
+        (byte)0x00, 
+        // Stream ID: STREAM_LOW (1)
+        (byte)0x01, 
+        // uncompressedLength : 12 bytes (LE)
+        (byte)0x0c, (byte)0x00, 
+        // pduType2: PDUTYPE2_CONTROL (20)
+        (byte)0x14, 
+        // generalCompressedType: 0
+        (byte)0x00, 
+        // generalCompressedLength: 0 (LE)
+        (byte)0x00, (byte)0x00,
+        
+        // action: CTRLACTION_REQUEST_CONTROL (1) (LE)
+        (byte)0x01, (byte)0x00,
+        // grantId: 0 (LE)
+        (byte)0x00, (byte)0x00, 
+        // controlId: 0 (LE)
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+    });
+    /* @formatter:on */
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToPad(STDOUT, buf);
+    }
+
+    private void sendControlPDUActionCooperate() {
+        int length = 1024; // Large enough
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        /* @formatter:off */
+    buf.writeBytes(new byte[] {
+        // MCS Send Data Request
+        (byte)0x64, 
+        // Initiator: 1004 (1001+3)
+        (byte)0x00, (byte)0x03, 
+        // Channel ID: 1003 (I/O channel)
+        (byte)0x03, (byte)0xeb, 
+        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+        (byte)0x70, 
+        // User data length: 26 bytes (0x1a, variable length field)
+        (byte)0x80, (byte)0x1a,
+        
+        // Total length: 26 bytes (0x1a, LE)
+        (byte)0x1a,(byte)0x00,
+        // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE)
+        (byte)0x17, (byte)0x00, 
+        // PDU source: 1004 (LE)
+        (byte)0xec, (byte)0x03, 
+    });
+    // Share ID, 4 bytes  (LE)
+    buf.writeIntLE((int)state.serverShareId);
+    
+    buf.writeBytes(new byte[] {
+        // Padding 1 byte
+        (byte)0x00, 
+        // Stream ID: STREAM_LOW (1)
+        (byte)0x01, 
+        // uncompressedLength : 12 bytes (LE)
+        (byte)0x0c, (byte)0x00, 
+        // pduType2: PDUTYPE2_CONTROL (20)
+        (byte)0x14, 
+        // generalCompressedType: 0
+        (byte)0x00, 
+        // generalCompressedLength: 0 (LE?)
+        (byte)0x00, (byte)0x00, 
+        // action: CTRLACTION_COOPERATE (4) (LE)
+        (byte)0x04, (byte)0x00,
+        // grantId: 0 (LE)
+        (byte)0x00, (byte)0x00,
+        // controlId: 0
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+    });
+    /* @formatter:on */
+
+        buf.trimAtCursor();
+
+        pushDataToPad(STDOUT, buf);
+    }
+
+    private void sendSynchronizePDU() {
+
+        ByteBuffer buf = new ByteBuffer(1024, true);
+        /* @formatter:off */
+    buf.writeBytes(new byte[] {
+        // MCS send data request
+        (byte)0x64,
+        // Initiator: 1004 (1001+3)
+        (byte)0x00, (byte)0x03,
+        // Channel ID: 1003 (I/O Channel)
+        (byte)0x03, (byte)0xeb,
+        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+        (byte)0x70, 
+        // Data length:  22 bytes (0x16, variable length field)
+        (byte)0x80,  (byte)0x16, 
+        
+        // RDP: total length: 22 bytes (LE)
+        (byte)0x16, (byte)0x00, 
+        
+        // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE)
+        (byte)0x17, (byte)0x00,
+        
+        // PDU source: 1007 (LE)
+        (byte)0xec, (byte)0x03,
+    });
+    // Share ID, 4 bytes  (LE)
+    buf.writeIntLE((int)state.serverShareId);
+    
+    buf.writeBytes(new byte[] {
+        // Padding: 1 byte
+        (byte)0x00,
+        // Stream ID: STREAM_LOW (1)
+        (byte)0x01, 
+        // uncompressedLength : 8 bytes (LE)
+        (byte)0x08, (byte)0x00,
+        // pduType2 = PDUTYPE2_SYNCHRONIZE (31)
+        (byte)0x1f, 
+        // generalCompressedType: 0
+        (byte)0x00,
+        // generalCompressedLength: 0 (LE?)
+        (byte)0x00, (byte)0x00,
+        //  messageType: SYNCMSGTYPE_SYNC (1) (LE)
+        (byte)0x01, (byte)0x00, 
+        // targetUser: 0x03ea
+        (byte)0xea, (byte)0x03,
+    });
+    /* @formatter:on */
+        buf.trimAtCursor();
+        pushDataToPad(STDOUT, buf);
+    }
+
+    private void writeCapabilities(ByteBuffer buf) {
+        writeGeneralCS(buf);
+
+        writeBitmapCS(buf);
+
+        writeOrderCS(buf);
+
+        writeBitmapCache2CS(buf);
+
+        writeColorTableCacheCS(buf);
+
+        writeWindowActivationCS(buf);
+
+        writeControlCS(buf);
+
+        writePointerCS(buf);
+
+        writeShareCS(buf);
+
+        writeInputCS(buf);
+
+        writeBrushCS(buf);
+
+        writeSoundCS(buf);
+
+        writeFontCS(buf);
+
+        writeOffscreenBitmapCS(buf);
+
+        writeGlyphCacheCS(buf);
+    }
+
+    private void writeBrushCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Brush Capability Set (8 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240564.aspx
+                (byte)0x0f, (byte)0x00, // capability set type: CAPSTYPE_BRUSH (15,
+                                        // LE)
+                (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // brushSupportLevel:
+                                                                // BRUSH_DEFAULT
+                                                                // (0x0, LE)
+
+        });
+    }
+
+    private void writeInputCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Input Capability Set (88 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240563.aspx
+                (byte)0x0d,
+                (byte)0x00, // capability set type: CAPSTYPE_INPUT (13, LE)
+                (byte)0x58,
+                (byte)0x00, // length of capability set: 88 bytes (LE)
+                (byte)0x35,
+                (byte)0x00, // inputFlags: 0x0035 (LE), INPUT_FLAG_FASTPATH_INPUT2
+                            // (0x20), INPUT_FLAG_VKPACKET (0x10), INPUT_FLAG_MOUSEX
+                            // (0x4), INPUT_FLAG_SCANCODES (0x1)
+                (byte)0x00,
+                (byte)0x00, // Padding 2 bytes
+                (byte)0x09,
+                (byte)0x04,
+                (byte)0x00,
+                (byte)0x00, // keyboardLayout: "US" keyboard layout (0x000409, LE)
+                (byte)0x00,
+                (byte)0x00,
+                (byte)0x00,
+                (byte)0x00, // keyboardType: unknown (LE)
+                (byte)0x00,
+                (byte)0x00,
+                (byte)0x00,
+                (byte)0x00, // keyboardSubType: unknown (LE)
+                (byte)0x00,
+                (byte)0x00,
+                (byte)0x00,
+                (byte)0x00, // keyboardFunctionKey: unknown (LE)
+                // imeFileName: "", (64 bytes, including trailing NULL characters, UCS2)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+
+        });
+    }
+
+    private void writeShareCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Share Capability Set (8 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240570.aspx
+                (byte)0x09, (byte)0x00, // capability set type: CAPSTYPE_SHARE (9, LE)
+                (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+                (byte)0x00, (byte)0x00, // nodeID (must be set to 0 by client): 0 (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes (LE)
+
+        });
+    }
+
+    private void writePointerCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Pointer Capability Set (10 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240562.aspx
+                (byte)0x08, (byte)0x00, // capability set type: CAPSTYPE_POINTER (8,
+                                        // LE)
+                (byte)0x0a, (byte)0x00, // length of capability set: 10 bytes (LE)
+                (byte)0x00, (byte)0x00, // colorPointerFlag: FALSE (LE)
+                (byte)0x00, (byte)0x00, // colorPointerCacheSize: 0 (LE)
+                (byte)0x14, (byte)0x00, // pointerCacheSize: 20 (LE)
+
+        });
+    }
+
+    private void writeControlCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Control Capability Set (12 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240568.aspx
+                (byte)0x05, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION
+                                        // (7)
+                (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
+                (byte)0x00, (byte)0x00, // controlFlags (should be set to 0): 0 (LE)
+                (byte)0x00, (byte)0x00, // remoteDetachFlag (should be set to 0): 0
+                                        // (LE)
+                (byte)0x02, (byte)0x00, // controlInterest (should be set to
+                                        // CONTROLPRIORITY_NEVER):
+                                        // CONTROLPRIORITY_NEVER (2) (LE)
+                (byte)0x02, (byte)0x00, // detachInterest (should be set to
+                                        // CONTROLPRIORITY_NEVER):
+                                        // CONTROLPRIORITY_NEVER (2) (LE)
+
+        });
+    }
+
+    private void writeWindowActivationCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Window Activation Capability Set (12 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240569.aspx
+                (byte)0x07, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION
+                                        // (7) (LE)
+                (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
+                (byte)0x00, (byte)0x00, // helpKeyFlag (should be set to FALSE (0)):
+                                        // FALSE (0, LE)
+                (byte)0x00, (byte)0x00, // helpKeyIndexFlag (should be set to FALSE
+                                        // (0)): FALSE (0, LE)
+                (byte)0x00, (byte)0x00, // helpExtendedKeyFlag (should be set to FALSE
+                                        // (0)): FALSE (0, LE)
+                (byte)0x00, (byte)0x00, // windowManagerKeyFlag (should be set to
+                                        // FALSE (0)): FALSE (0, LE)
+
+        });
+    }
+
+    private void writeColorTableCacheCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+
+                //
+                // Color Table Cache Capability Set (8 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc241564.aspx
+                (byte)0x0a, (byte)0x00, // capability set type: CAPSTYPE_COLORCACHE
+                                        // (10) (LE)
+                (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+                (byte)0x06, (byte)0x00, // Color table cache size (must be ignored
+                                        // during capability exchange and is assumed
+                                        // to be 0x0006): 6 (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+
+        });
+    }
+
+    private void writeBitmapCache2CS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Bitmap Cache Rev. 2 Capability Set (40 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240560.aspx
+                (byte)0x13, (byte)0x00, // capability set type:
+                                        // CAPSTYPE_BITMAPCACHE_REV2 (19) (LE)
+                (byte)0x28, (byte)0x00, // length of capability set: 40 bytes (LE)
+                (byte)0x00, (byte)0x00, // Cache flags: 0 (LE)
+                (byte)0x00, // Padding 1 byte
+                (byte)0x00, // Number of cell caches: 0
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache0
+                                                                // cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache1
+                                                                // cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache2
+                                                                // cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache3
+                                                                // cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache4
+                                                                // cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 12 bytes
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
+        });
+    }
+
+    private void writeGeneralCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                // Capabilities, see
+                // http://msdn.microsoft.com/en-us/library/cc240486.aspx
+
+                //
+                // General capability set (24 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240549.aspx
+                (byte)0x01, (byte)0x00, // capability set type: CAPSTYPE_GENERAL (1)
+                                        // (LE)
+                (byte)0x18, (byte)0x00, // length of capability set: 24 bytes (LE)
+                (byte)0x01, (byte)0x00, // TS_OSMAJORTYPE_WINDOWS (1) (LE)
+                (byte)0x03, (byte)0x00, // TS_OSMINORTYPE_WINDOWS_NT (3) (LE)
+                (byte)0x00, (byte)0x02, // TS_CAPS_PROTOCOLVERSION (0x0200) (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+                (byte)0x00, (byte)0x00, // generalCompressionTypes: 0 (LE)
+
+                // Extra flags: 0x040d (LE)
+                // FastPathOutput: (...............1) Advertiser supports fast-path
+                // output
+                // ShadowCompression: (..............0.) Advertiser NOT supports shadow
+                // compression
+                // LongLengthCredentials: (.............1..) Advertiser supports
+                // long-length credentials for the user name, password, or domain name
+                // SessionAutoreconnection: (............1...) Advertiser supports
+                // session auto-reconnection
+                // ImprovedEncryptionChecksum: (...........0....) Client and server NOT
+                // support improved encryption checksum
+                // Reserved1: (......00000.....)
+                // CompressedBitMapDataFlag: (.....1..........) No 8-UINT8 header is
+                // present for compressed bitmap data
+                // Reserved2: (00000...........)
+                (byte)0x0d, (byte)0x04,
+
+                (byte)0x00, (byte)0x00, // updateCapabilityFlag: 0 (LE)
+                (byte)0x00, (byte)0x00, // remoteUnshareFlag: 0 (LE)
+                (byte)0x00, (byte)0x00, // generalCompressionLevel: 0 (LE)
+                (byte)0x00, // refreshRectSupport: FALSE (0)
+                (byte)0x00, // suppressOutputSupport: FALSE (0)
+
+        });
+    }
+
+    private void writeBitmapCS(ByteBuffer buf) {
+        // Bitmap capability set (28 bytes), see
+        // http://msdn.microsoft.com/en-us/library/cc240554.aspx
+
+        numberCapabilities++;
+
+        // Capability set type: CAPSTYPE_BITMAP (2) (LE)
+        buf.writeShortLE(CAPSTYPE_BITMAP);
+
+        // Length of capability set: 28 bytes (LE)
+        buf.writeShortLE(28);
+
+        // preferredBitsPerPixel: 16 bpp (LE)
+        buf.writeShortLE(prefferedBitsPerPixel);
+
+        // receive1BitPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
+        buf.writeShortLE(1);
+
+        // receive4BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
+        buf.writeShortLE(1);
+
+        // receive8BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
+        buf.writeShortLE(1);
+
+        // Desktop width and height (LE)
+        buf.writeShortLE(screen.getFramebufferWidth());
+        buf.writeShortLE(screen.getFramebufferHeight());
+
+        // Padding 2 bytes
+        buf.writeShortLE(0);
+
+        // desktopResizeFlag (LE)
+        buf.writeShortLE((desktopResize) ? 1 : 0);
+
+        buf.writeBytes(new byte[] {
+                (byte)0x01, (byte)0x00, // bitmapCompressionFlag (must be set to TRUE
+                                        // (0x1)): TRUE (0x1) (LE)
+                (byte)0x00, // highColorFlags (field is ignored and SHOULD be set to
+                            // zero): 0
+                (byte)0x01, // drawingFlags: 0x1 TODO: padding, why 0x1 ???
+                (byte)0x01, (byte)0x00, // multipleRectangleSupport: TRUE (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+
+        });
+    }
+
+    private void writeOrderCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Order Capability Set (88 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240556.aspx
+                (byte)0x03,
+                (byte)0x00, // capability set type: CAPSTYPE_ORDER (3) (LE)
+                (byte)0x58,
+                (byte)0x00, // length of capability set: 88 bytes (LE)
+                // terminalDescriptor = "" (16 bytes, UCS2)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // pad4octetsA
+                (byte)0x01, (byte)0x00, // desktopSaveXGranularity (ignored): 1 (LE)
+                (byte)0x14, (byte)0x00, // desktopSaveYGranularity (ignored): 20 (LE)
+                (byte)0x00, (byte)0x00, // pad2octetsA (ignored)
+                (byte)0x01, (byte)0x00, // maximumOrderLevel: ORD_LEVEL_1_ORDERS (1)
+                (byte)0x00, (byte)0x00, // number of fonts (ignored): 0
+                (byte)0x4a, (byte)0x00, // orderFlags = 0x004a (LE),
+                                        // SOLIDPATTERNBRUSHONLY (0x40),
+                                        // ZEROBOUNDSDELTASSUPPORT (0x8, MUST),
+                                        // NEGOTIATEORDERSUPPORT (0x2, MUST)
+                // Order support: 32 bytes (no primary drawing orders are supported, so
+                // this array MUST be initialized to all zeros, use 0x01 for TRUE).
+                (byte)0x00, // TS_NEG_DSTBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_PATBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_SCRBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MEMBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MEM3BLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_ATEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_AEXTTEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_DRAWNINEGRID_INDEX: FALSE
+                (byte)0x00, // TS_NEG_LINETO_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTI_DRAWNINEGRID_INDEX: FALSE
+                (byte)0x00, // TS_NEG_OPAQUERECT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_SAVEBITMAP_INDEX: FALSE
+                (byte)0x00, // TS_NEG_WTEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MEMBLT_R2_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MEM3BLT_R2_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTIDSTBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTIPATBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTISCRBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTIOPAQUERECT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_FAST_INDEX_INDEX: FALSE
+                (byte)0x00, // TS_NEG_POLYGON_SC_INDEX: FALSE
+                (byte)0x00, // TS_NEG_POLYGON_CB_INDEX: FALSE
+                (byte)0x00, // TS_NEG_POLYLINE_INDEX: TRUE
+                (byte)0x00, // Unused: 0
+                (byte)0x00, // TS_NEG_FAST_GLYPH_INDEX: FALSE
+                (byte)0x00, // TS_NEG_ELLIPSE_SC_INDEX: FALSE
+                (byte)0x00, // TS_NEG_ELLIPSE_CB_INDEX: FALSE
+                (byte)0x00, // TS_NEG_INDEX_INDEX: FALSE
+                (byte)0x00, // TS_NEG_WEXTTEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_WLONGTEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_WLONGEXTTEXTOUT_INDEX: FALSE
+                (byte)0x00, // Unused: 0
+                (byte)0x00, (byte)0x00, // Text flags (ignored): 0 (LE)
+                (byte)0x00, (byte)0x00, // Order support extra flags: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 4 bytes
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Desktop save size
+                                                                // (ignored): 0
+                                                                // (assumed to be
+                                                                // 230400 bytes
+                                                                // (480*480,
+                                                                // 0x38400, LE))
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+                (byte)0xe4, (byte)0x04, // Text ANSI Code Page: 1252, ANSI - Latin I
+                                        // (0x04e4, LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+
+        });
+    }
+
+    private void writeSoundCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Sound Capability Set (8 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240552.aspx
+                (byte)0x0c, (byte)0x00, // capability set type: CAPSTYPE_SOUND (12,
+                                        // LE)
+                (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // soundFlags:
+                                                                // 0x0000 (LE) //
+                                                                // SOUND_FLAG_BEEPS
+                                                                // (0x1)
+
+        });
+    }
+
+    private void writeFontCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Font Capability Set (8 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240571.aspx
+                (byte)0x0e, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
+
+        });
+    }
+
+    private void writeOffscreenBitmapCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Offscreen Bitmap Cache Capability Set (12 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240550.aspx
+                (byte)0x11, (byte)0x00, // capability set type:
+                                        // CAPSTYPE_OFFSCREENCACHE (17, LE)
+                (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // offscreenSupportLevel:
+                                                                // FALSE (LE)
+                (byte)0x00, (byte)0x00, // offscreenCacheSize: 0 (LE)
+                (byte)0x00, (byte)0x00, // offscreenCacheEntries: 0 (LE)
+
+        });
+    }
+
+    private void writeGlyphCacheCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Glyph Cache Capability Set (52 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240565.aspx
+                (byte)0x10, (byte)0x00, // capability set type:
+                                        // CAPSTYPE_OFFSCREENCACHE (16, LE)
+                (byte)0x34, (byte)0x00, // length of capability set: 52 bytes (LE)
+                // Glyph Cache (40 bytes)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x10, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x20, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x40, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x80, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 4 (LE)
+                (byte)0x40, (byte)0x00, // CacheEntries: 64 (LE)
+                (byte)0x00, (byte)0x08, // CacheMaximumCellSize: 2048 (LE)
+                // FragCache
+                (byte)0x00, (byte)0x01, // CacheEntries: 256 (LE)
+                (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 256 (LE)
+                //
+                (byte)0x00, (byte)0x00, // GlyphSupportLevel: GLYPH_SUPPORT_NONE (0x0,
+                                        // LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+        });
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        // MCS Send Data Request
+        (byte)0x64,  
+        
+        // Initiator: 1004 (1001+3)
+        (byte)0x00, (byte)0x03, 
+        
+        // Channel ID: 1003 (I/O channel)
+        (byte)0x03, (byte)0xeb,
+        
+        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+        (byte)0x70,
+        
+        // User data length: 432 bytes (0x1b0, variable length field)
+        (byte)0x81, (byte)0xb0, 
+        
+        // Total length: 432 bytes (0x1b0, LE)
+        (byte)0xb0, (byte)0x01, 
+        
+        // PDU type: Confirm Active PDU (0x3), TS_PROTOCOL_VERSION (0x10) (LE)
+        (byte)0x13, (byte)0x00, 
+        
+        // PDU source: 1004 (LE)
+        (byte)0xec, (byte)0x03, 
+        
+        // Share ID: 0x000103ea (LE)
+        (byte)0xea, (byte)0x03, (byte)0x01, (byte)0x00,
+        
+        // Originator ID: 1002 (LE)
+        (byte)0xea, (byte)0x03,
+        
+        // Length of source descriptor: 6 bytes (including NULL character) (LE) 
+        (byte)0x06, (byte)0x00, 
+        
+        // Length of combined capabilities: 410 bytes (LE)
+        (byte)0x9a, (byte)0x01,
+        
+        // Source descriptor: "MSTSC" ???
+        (byte)0x4d, (byte)0x53, (byte)0x54, (byte)0x53, (byte)0x43, (byte)0x00,
+        
+        // Number of capabilities: 15 (LE)
+        (byte)0x0f, (byte)0x00,
+        
+        // Padding 2 bytes
+        (byte)0x00, (byte)0x00,
+        
+        // Capabilities, see http://msdn.microsoft.com/en-us/library/cc240486.aspx
+        
+        //
+        // General capability set (24 bytes), see http://msdn.microsoft.com/en-us/library/cc240549.aspx
+        (byte)0x01, (byte)0x00, // capability set type: CAPSTYPE_GENERAL (1) (LE) 
+        (byte)0x18, (byte)0x00, // length of capability set: 24 bytes (LE)
+        (byte)0x01, (byte)0x00, // TS_OSMAJORTYPE_WINDOWS (1) (LE)
+        (byte)0x03, (byte)0x00, // TS_OSMINORTYPE_WINDOWS_NT (3) (LE)
+        (byte)0x00, (byte)0x02, // TS_CAPS_PROTOCOLVERSION (0x0200) (LE)
+        (byte)0x00, (byte)0x00, // Padding 2 bytes
+        (byte)0x00, (byte)0x00, // generalCompressionTypes: 0 (LE)
+        
+        // Extra flags: 0x040d (LE)
+//        FastPathOutput:             (...............1) Advertiser supports fast-path output
+//        ShadowCompression:          (..............0.) Advertiser NOT supports shadow compression
+//        LongLengthCredentials:      (.............1..) Advertiser supports long-length credentials for the user name, password, or domain name
+//        SessionAutoreconnection:    (............1...) Advertiser supports session auto-reconnection
+//        ImprovedEncryptionChecksum: (...........0....) Client and server NOT support improved encryption checksum
+//        Reserved1:                  (......00000.....)
+//        CompressedBitMapDataFlag:   (.....1..........) No 8-UINT8 header is present for compressed bitmap data
+//        Reserved2:                  (00000...........)
+        (byte)0x0d, (byte)0x04,
+        
+        (byte)0x00, (byte)0x00, // updateCapabilityFlag: 0 (LE)
+        (byte)0x00, (byte)0x00, // remoteUnshareFlag: 0 (LE)
+        (byte)0x00, (byte)0x00, // generalCompressionLevel: 0 (LE)
+        (byte)0x00, // refreshRectSupport: FALSE (0)
+        (byte)0x00, // suppressOutputSupport: FALSE (0)
+        
+        //
+        // Bitmap capability set (28 bytes), see http://msdn.microsoft.com/en-us/library/cc240554.aspx
+        (byte)0x02, (byte)0x00, // capability set type: CAPSTYPE_BITMAP (2) (LE)
+        (byte)0x1c, (byte)0x00, // length of capability set: 28 bytes (LE)
+        (byte)0x10, (byte)0x00, // preferredBitsPerPixel: 16 bpp (LE)
+        (byte)0x01, (byte)0x00, // receive1BitPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
+        (byte)0x01, (byte)0x00, // receive4BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
+        (byte)0x01, (byte)0x00, // receive8BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
+        (byte)0x00, (byte)0x04, // desktopWidth = 1024 pixels (LE)
+        (byte)0x00, (byte)0x03, // desktopHeight = 768 pixels (LE)
+        (byte)0x00, (byte)0x00, // Padding 2 bytes
+        (byte)0x00, (byte)0x00, // desktopResizeFlag: FALSE (0x0) (LE)
+        (byte)0x01, (byte)0x00, // bitmapCompressionFlag (must be set to TRUE (0x1)): TRUE (0x1) (LE)
+        (byte)0x00, // highColorFlags (field is ignored and SHOULD be set to zero): 0 
+        (byte)0x01, // drawingFlags: 0x1 TODO: padding, why 0x1 ???
+        (byte)0x01, (byte)0x00, // multipleRectangleSupport: TRUE (LE) 
+        (byte)0x00, (byte)0x00, // Padding 2 bytes
+        
+        //
+        // Order Capability Set (88 bytes), see http://msdn.microsoft.com/en-us/library/cc240556.aspx
+        (byte)0x03, (byte)0x00, // capability set type: CAPSTYPE_ORDER (3) (LE)
+        (byte)0x58, (byte)0x00, // length of capability set: 88 bytes (LE)
+        // terminalDescriptor = "" (16 bytes, UCS2)
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // pad4octetsA 
+        (byte)0x01, (byte)0x00, // desktopSaveXGranularity (ignored): 1 (LE)
+        (byte)0x14, (byte)0x00, // desktopSaveYGranularity (ignored): 20 (LE)
+        (byte)0x00, (byte)0x00, // pad2octetsA (ignored)
+        (byte)0x01, (byte)0x00, // maximumOrderLevel: ORD_LEVEL_1_ORDERS (1) 
+        (byte)0x00, (byte)0x00, // number of fonts (ignored): 0 
+        (byte)0x4a, (byte)0x00, // orderFlags = 0x004a (LE), SOLIDPATTERNBRUSHONLY (0x40), ZEROBOUNDSDELTASSUPPORT (0x8, MUST), NEGOTIATEORDERSUPPORT (0x2, MUST)
+        // Order support: 32 bytes (no primary drawing orders are supported, so this array MUST be initialized to all zeros, use 0x01 for TRUE).
+        (byte)0x00, // TS_NEG_DSTBLT_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_PATBLT_INDEX: FALSE  
+        (byte)0x00, // TS_NEG_SCRBLT_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_MEMBLT_INDEX: FALSE  
+        (byte)0x00, // TS_NEG_MEM3BLT_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_ATEXTOUT_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_AEXTTEXTOUT_INDEX: FALSE
+        (byte)0x00, // TS_NEG_DRAWNINEGRID_INDEX: FALSE
+        (byte)0x00, // TS_NEG_LINETO_INDEX: FALSE
+        (byte)0x00, // TS_NEG_MULTI_DRAWNINEGRID_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_OPAQUERECT_INDEX: FALSE
+        (byte)0x00, // TS_NEG_SAVEBITMAP_INDEX: FALSE
+        (byte)0x00, // TS_NEG_WTEXTOUT_INDEX: FALSE
+        (byte)0x00, // TS_NEG_MEMBLT_R2_INDEX: FALSE
+        (byte)0x00, // TS_NEG_MEM3BLT_R2_INDEX: FALSE
+        (byte)0x00, // TS_NEG_MULTIDSTBLT_INDEX: FALSE
+        (byte)0x00, // TS_NEG_MULTIPATBLT_INDEX: FALSE
+        (byte)0x00, // TS_NEG_MULTISCRBLT_INDEX: FALSE
+        (byte)0x00, // TS_NEG_MULTIOPAQUERECT_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_FAST_INDEX_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_POLYGON_SC_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_POLYGON_CB_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_POLYLINE_INDEX: TRUE 
+        (byte)0x00, // Unused: 0 
+        (byte)0x00, // TS_NEG_FAST_GLYPH_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_ELLIPSE_SC_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_ELLIPSE_CB_INDEX: FALSE
+        (byte)0x00, // TS_NEG_INDEX_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_WEXTTEXTOUT_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_WLONGTEXTOUT_INDEX: FALSE 
+        (byte)0x00, // TS_NEG_WLONGEXTTEXTOUT_INDEX: FALSE
+        (byte)0x00, // Unused: 0 
+        (byte)0x00, (byte)0x00, // Text flags (ignored): 0  (LE)
+        (byte)0x00, (byte)0x00, // Order support extra flags: 0 (LE)
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 4 bytes
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Desktop save size (ignored): 0 (assumed to be 230400 bytes (480*480, 0x38400, LE))  
+        (byte)0x00, (byte)0x00, // Padding 2 bytes 
+        (byte)0x00, (byte)0x00, // Padding 2 bytes
+        (byte)0xe4, (byte)0x04, // Text ANSI Code Page: 1252,  ANSI - Latin I (0x04e4, LE) 
+        (byte)0x00, (byte)0x00, // Padding 2 bytes
+        
+        //
+        // Bitmap Cache Rev. 2 Capability Set (40 bytes), see http://msdn.microsoft.com/en-us/library/cc240560.aspx
+        (byte)0x13, (byte)0x00, // capability set type: CAPSTYPE_BITMAPCACHE_REV2 (19) (LE) 
+        (byte)0x28, (byte)0x00, // length of capability set: 40 bytes (LE)
+        (byte)0x00, (byte)0x00, // Cache flags: 0 (LE) 
+        (byte)0x00, // Padding 1 byte 
+        (byte)0x00, // Number of cell caches: 0 
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache0 cell info: 0 (LE) 
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache1 cell info: 0 (LE)
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache2 cell info: 0 (LE)
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache3 cell info: 0 (LE)
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache4 cell info: 0 (LE)
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 12 bytes 
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
+        
+        //
+        // Color Table Cache Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc241564.aspx
+        (byte)0x0a, (byte)0x00, // capability set type: CAPSTYPE_COLORCACHE (10) (LE)
+        (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+        (byte)0x06, (byte)0x00, // Color table cache size (must be ignored during capability exchange and is assumed to be 0x0006): 6 (LE)
+        (byte)0x00, (byte)0x00, // Padding 2 bytes
+        
+        //
+        // Window Activation Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240569.aspx
+        (byte)0x07, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION (7) (LE) 
+        (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
+        (byte)0x00, (byte)0x00, // helpKeyFlag (should be set to FALSE (0)): FALSE (0, LE)
+        (byte)0x00, (byte)0x00, // helpKeyIndexFlag (should be set to FALSE (0)): FALSE (0, LE)
+        (byte)0x00, (byte)0x00, // helpExtendedKeyFlag (should be set to FALSE (0)): FALSE (0, LE)
+        (byte)0x00, (byte)0x00, // windowManagerKeyFlag (should be set to FALSE (0)): FALSE (0, LE)
+        
+        //
+        // Control Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240568.aspx
+        (byte)0x05, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION (7)
+        (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
+        (byte)0x00, (byte)0x00, // controlFlags (should be set to 0): 0 (LE)
+        (byte)0x00, (byte)0x00, // remoteDetachFlag (should be set to 0): 0 (LE)
+        (byte)0x02, (byte)0x00, // controlInterest (should be set to CONTROLPRIORITY_NEVER): CONTROLPRIORITY_NEVER (2) (LE)
+        (byte)0x02, (byte)0x00, // detachInterest (should be set to CONTROLPRIORITY_NEVER): CONTROLPRIORITY_NEVER (2) (LE)
+        
+        //
+        // Pointer Capability Set (10 bytes), see http://msdn.microsoft.com/en-us/library/cc240562.aspx
+        (byte)0x08, (byte)0x00, // capability set type: CAPSTYPE_POINTER (8, LE)
+        (byte)0x0a, (byte)0x00, // length of capability set: 10 bytes (LE)
+        (byte)0x00, (byte)0x00, // colorPointerFlag: FALSE (LE)
+        (byte)0x00, (byte)0x00, // colorPointerCacheSize: 0 (LE)
+        (byte)0x14, (byte)0x00, // pointerCacheSize: 20 (LE)
+        
+        //
+        // Share Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240570.aspx
+        (byte)0x09, (byte)0x00, // capability set type: CAPSTYPE_SHARE (9, LE)
+        (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+        (byte)0x00, (byte)0x00, // nodeID (must be set to 0 by client): 0 (LE)
+        (byte)0x00, (byte)0x00, // Padding 2 bytes (LE)
+        
+        //
+        // Input Capability Set (88 bytes), see http://msdn.microsoft.com/en-us/library/cc240563.aspx
+        (byte)0x0d, (byte)0x00, // capability set type:  CAPSTYPE_INPUT (13, LE)
+        (byte)0x58, (byte)0x00, // length of capability set: 88 bytes (LE)
+        (byte)0x35, (byte)0x00, // inputFlags: 0x0035  (LE),  INPUT_FLAG_FASTPATH_INPUT2 (0x20), INPUT_FLAG_VKPACKET (0x10), INPUT_FLAG_MOUSEX (0x4), INPUT_FLAG_SCANCODES (0x1)
+        (byte)0x00, (byte)0x00, // Padding 2 bytes 
+        (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, // keyboardLayout: "US" keyboard layout (0x000409, LE) 
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardType: unknown (LE) 
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardSubType: unknown (LE) 
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardFunctionKey: unknown (LE)
+        // imeFileName: "", (64 bytes, including trailing NULL characters, UCS2) 
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        
+        //
+        // Brush Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240564.aspx
+        (byte)0x0f, (byte)0x00, // capability set type: CAPSTYPE_BRUSH (15, LE)
+        (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // brushSupportLevel: BRUSH_DEFAULT (0x0, LE)
+        
+        //
+        // Sound Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240552.aspx
+        (byte)0x0c, (byte)0x00, // capability set type: CAPSTYPE_SOUND (12, LE)
+        (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // soundFlags: 0x0000 (LE) // SOUND_FLAG_BEEPS (0x1)   
+        
+        //
+        // Font Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240571.aspx
+        (byte)0x0e, (byte)0x00, 
+        (byte)0x08, (byte)0x00, 
+        (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 
+        
+        //
+        // Offscreen Bitmap Cache Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240550.aspx
+        (byte)0x11, (byte)0x00, // capability set type: CAPSTYPE_OFFSCREENCACHE (17, LE)
+        (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // offscreenSupportLevel: FALSE (LE) 
+        (byte)0x00, (byte)0x00, // offscreenCacheSize: 0 (LE)
+        (byte)0x00, (byte)0x00, // offscreenCacheEntries: 0 (LE)
+        
+        //
+        // Glyph Cache Capability Set (52 bytes), see http://msdn.microsoft.com/en-us/library/cc240565.aspx
+        (byte)0x10, (byte)0x00, // capability set type: CAPSTYPE_OFFSCREENCACHE (16, LE)
+        (byte)0x34, (byte)0x00, // length of capability set: 52 bytes (LE)
+        // Glyph Cache (40 bytes)
+        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) 
+        (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+        (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+        (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+        (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+        (byte)0x10, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+        (byte)0x20, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+        (byte)0x40, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+        (byte)0x80, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+        (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 4 (LE)
+        (byte)0x40, (byte)0x00, // CacheEntries: 64 (LE)
+        (byte)0x00, (byte)0x08, // CacheMaximumCellSize: 2048 (LE)
+        // FragCache
+        (byte)0x00, (byte)0x01, // CacheEntries: 256 (LE)
+        (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 256 (LE)
+        // 
+        (byte)0x00, (byte)0x00, // GlyphSupportLevel: GLYPH_SUPPORT_NONE (0x0, LE)  
+        (byte)0x00, (byte)0x00, // Padding 2 bytes   
+    };
+    /* @formatter:on */
+
+        RdpState rdpState = new RdpState();
+        ScreenDescription screenDescription = new ScreenDescription();
+        screenDescription.setFramebufferSize(1024, 768);
+
+        rdpState.serverShareId = 0x000103ea;
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {}));
+        Element confirm_active = new ClientConfirmActivePDU("confirm_active", screenDescription, rdpState);
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, confirm_active, sink);
+        pipeline.link("source", "confirm_active", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientFastPathPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientFastPathPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientFastPathPDU.java
new file mode 100755
index 0000000..108429c
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientFastPathPDU.java
@@ -0,0 +1,55 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240589.aspx
+ */
+public class ClientFastPathPDU extends BaseElement {
+
+    public ClientFastPathPDU(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        if (buf.length > 32767 - 3)
+            throw new RuntimeException("Packet is too long: " + buf + ".");
+
+        ByteBuffer data = new ByteBuffer(6);
+
+        // FastPath, 1 event, no checksum, not encrypted
+        data.writeByte(0x4);
+
+        // Length of full packet, including length field, in network order.
+        // Topmost bit of first byte indicates that field has 2 bytes
+        data.writeShort((1 + 2 + buf.length) | 0x8000);
+        data.trimAtCursor();
+
+        buf.prepend(data);
+
+        pushDataToAllOuts(buf);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientInfoPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientInfoPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientInfoPDU.java
new file mode 100755
index 0000000..7334d7f
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientInfoPDU.java
@@ -0,0 +1,456 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240475.aspx
+ */
+public class ClientInfoPDU extends OneTimeSwitch {
+
+    public static final int INFO_MOUSE = 0x1;
+    public static final int INFO_DISABLECTRLALTDEL = 0x2;
+    public static final int INFO_UNICODE = 0x10;
+
+    public static final int INFO_MAXIMIZESHELL = 0x20;
+    public static final int INFO_LOGONNOTIFY = 0x40;
+    public static final int INFO_ENABLEWINDOWSKEY = 0x100;
+    public static final int INFO_MOUSE_HAS_WHEEL = 0x00020000;
+    public static final int INFO_NOAUDIOPLAYBACK = 0x00080000;
+
+    public static final int PERF_DISABLE_WALLPAPER = 0x1;
+    public static final int PERF_DISABLE_FULLWINDOWDRAG = 0x2;
+    public static final int PERF_DISABLE_MENUANIMATIONS = 0x4;
+
+    protected byte[] userName = "".getBytes(RdpConstants.CHARSET_16);
+    protected byte[] password = "".getBytes(RdpConstants.CHARSET_16); // No effect
+    protected byte[] alternateShell = "".getBytes(RdpConstants.CHARSET_16);
+    protected byte[] domain = "".getBytes(RdpConstants.CHARSET_16);
+    protected byte[] workingDir = "".getBytes(RdpConstants.CHARSET_16);
+    protected byte[] clientAddress = "192.168.0.100".getBytes(RdpConstants.CHARSET_16);
+    protected byte[] clientDir = "C:\\Windows\\System32\\mstscax.dll".getBytes(RdpConstants.CHARSET_16);
+
+    protected String standardTimeZoneName = "EET, Standard Time";
+    protected String daylightTimeZoneName = "EET, Summer Time";
+    protected int standardTimeZoneBias = 0; /* in minutes */
+    protected int daylightTimeZoneBias = 60; /* in minutes */
+
+    public ClientInfoPDU(String id, String userName) {
+        super(id);
+        this.userName = userName.getBytes(RdpConstants.CHARSET_16);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        // Length of packet
+        ByteBuffer buf = new ByteBuffer(1024, true);
+
+        // MCS Send Data Request PDU 
+        buf.writeByte(0x64);
+
+        // Initiator: 0x03 + 1001 = 1004
+        buf.writeShort(3);
+
+        // Channel ID: 1003
+        buf.writeShort(1003);
+
+        // Data priority: high, segmentation: begin | end (0x40 | 0x20 | 0x10 = 0x70)
+        buf.writeByte(0x70);
+
+        // User data length: (variable length field)
+        int length = 224 + userName.length + password.length + alternateShell.length + domain.length + workingDir.length + clientAddress.length + clientDir.length;
+        buf.writeShort(length | 0x8000);
+
+        // Flags: SEC_INFO_PKT (0x4000)
+        buf.writeShort(0x4000);
+
+        // TS_SECURITY_HEADER::flagsHi - ignored
+        buf.writeShort(0x0000);
+
+        // Codepage: 0 (UNKNOWN, LE) (use  0x04090409  (1033,1033) for EN_US)  
+        buf.writeIntLE(0x0000);
+
+        // Flags
+        buf.writeIntLE(INFO_MOUSE | INFO_DISABLECTRLALTDEL | INFO_UNICODE |
+                INFO_MAXIMIZESHELL | INFO_LOGONNOTIFY | INFO_ENABLEWINDOWSKEY |
+                INFO_MOUSE_HAS_WHEEL | INFO_NOAUDIOPLAYBACK);
+
+        //
+        // Lengths
+        //
+
+        // cbDomain length: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
+        buf.writeShortLE(domain.length);
+
+        // cbUserName length: 16 bytes (0x10, LE) (NOT including size of mandatory NULL terminator)
+        buf.writeShortLE(userName.length);
+
+        // cbPassword length: (LE) (NOT including size of mandatory NULL terminator)
+        buf.writeShortLE(password.length);
+
+        // cbAlternateShell:  (LE) (NOT including size of mandatory NULL terminator)
+        buf.writeShortLE(alternateShell.length);
+
+        // cbWorkingDir: (LE) (NOT including size of mandatory NULL terminator)
+        buf.writeShortLE(workingDir.length);
+
+        //
+        // Values
+        //
+
+        // Domain: (UCS2), see cbDomain
+        buf.writeBytes(domain);
+        buf.writeShort(0);
+
+        // User name: (UCS2), see cbUserName
+        buf.writeBytes(userName);
+        buf.writeShort(0);
+
+        // Password: (UCS2), see cbPassword
+        buf.writeBytes(password);
+        buf.writeShort(0);
+
+        // Alternate shell: (UCS2), see cbAlternateShell
+        buf.writeBytes(alternateShell);
+        buf.writeShort(0);
+
+        // Working directory: (UCS2), see cbWorkingDir
+        buf.writeBytes(workingDir);
+        buf.writeShort(0);
+
+        // Client address family: 2 (AF_INET, LE)
+        buf.writeShortLE(2);
+
+        // cbClientAddress: ( LE) (including the size of the mandatory NULL terminator)
+        buf.writeShortLE(clientAddress.length + 2);
+
+        // Client address: (UCS2) 
+        buf.writeBytes(clientAddress);
+        buf.writeShort(0);
+
+        // cbClientDir: 64 bytes (0x40, LE) (including the size of the mandatory NULL terminator)
+        buf.writeShortLE(clientDir.length + 2);
+
+        // Client directory: (UCS2)
+        buf.writeBytes(clientDir);
+        buf.writeShort(0);
+
+        //
+        // Client time zone:
+        //
+
+        // Bias: 0 minutes (LE)
+        buf.writeIntLE(0);
+
+        // Standard name: "EET, Standard Time" (fixed string: 64 bytes, UCS2)
+        buf.writeFixedString(62, standardTimeZoneName, RdpConstants.CHARSET_16);
+        buf.writeShort(0);
+
+        // Standard date
+        buf.writeBytes(new byte[] {
+                // wYear: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wMonth: unknown (LE)
+                (byte)0x00, (byte)0x00,
+                // wDayOfWeek: Sunday (LE)
+                (byte)0x00, (byte)0x00,
+                // wDay: unknown (LE)
+                (byte)0x00, (byte)0x00,
+                // wHour: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wMinute: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wSecond: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wMilliseconds: 0
+                (byte)0x00, (byte)0x00,
+
+        });
+
+        // StandardBias: 0 minutes (LE)
+        buf.writeIntLE(standardTimeZoneBias);
+
+        // Daylight name: "EET, Summer Time" (fixed string: 64 bytes, UCS2)
+        buf.writeFixedString(62, daylightTimeZoneName, RdpConstants.CHARSET_16);
+        buf.writeShort(0);
+
+        // Daylight date
+        buf.writeBytes(new byte[] {
+                // wYear: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wMonth: unknown (LE)
+                (byte)0x00, (byte)0x00,
+                // wDayOfWeek: Sunday (LE)
+                (byte)0x00, (byte)0x00,
+                // wDay: unknown (LE)
+                (byte)0x00, (byte)0x00,
+                // wHour: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wMinute: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wSecond: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wMilliseconds: 0
+                (byte)0x00, (byte)0x00,
+
+        });
+
+        // Daylight bias: 60 minutes (LE)
+        buf.writeIntLE(daylightTimeZoneBias);
+
+        // Client session ID: 0x00000000 (LE)
+        buf.writeIntLE(0);
+
+        // Performance flags: 0x7 (LE) = PERF_DISABLE_WALLPAPER (0x1), PERF_DISABLE_FULLWINDOWDRAG (0x2), PERF_DISABLE_MENUANIMATIONS (0x4)
+        buf.writeIntLE(PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS);
+
+        // cbAutoReconnectCookie: 0 bytes (LE)
+        buf.writeShortLE(0);
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        
+        // TPKT
+        (byte) 0x03, (byte) 0x00,
+
+        // TPKT length: 343 bytes
+        (byte) 0x01, (byte) 0x57,
+        
+        // X224 Data PDU
+        (byte) 0x02, (byte) 0xf0, (byte) 0x80,
+        
+        
+        // MCS Send Data Request PDU 
+        (byte) 0x64, 
+        
+        // Initiator: 0x03 + 1001 = 1004
+        (byte) 0x00, (byte) 0x03,
+        
+        // Channel ID: 1003 (IO Channel)
+        (byte) 0x03, (byte) 0xeb,
+        
+        // Data priority: high, segmentation: begin | end (0x40 | 0x20 | 0x10 = 0x70)
+        (byte) 0x70, 
+        
+        // User data length: 328  (0x148) bytes, variable length field 
+        (byte) 0x81, (byte) 0x48, 
+        
+        // Flags: SEC_INFO_PKT (0x4000)
+        (byte) 0x40, (byte) 0x00, 
+
+        // TS_SECURITY_HEADER::flagsHi - ignored
+        (byte) 0x00, (byte) 0x00,
+        
+        // Codepage: 0 (UNKNOWN, LE) (use  0x04090409  (1033,1033) for EN_US)  
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+        
+        // Flags: 0xa0173 (LE), INFO_MOUSE (0x1), INFO_DISABLECTRLALTDEL (0x2), INFO_UNICODE (0x10), 
+        // INFO_MAXIMIZESHELL (0x20), INFO_LOGONNOTIFY (0x40), INFO_ENABLEWINDOWSKEY (0x100),
+        // INFO_MOUSE_HAS_WHEEL (0x00020000), INFO_NOAUDIOPLAYBACK (0x00080000), 
+        (byte) 0x73, (byte) 0x01, (byte) 0x0a, (byte) 0x00, 
+        
+        // Lengths
+        
+        // cbDomain length: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
+        (byte) 0x00, (byte) 0x00, 
+        
+        // cbUserName length: 16 bytes (0x10, LE) (NOT including size of mandatory NULL terminator)
+        (byte) 0x10, (byte) 0x00,
+        
+        // cbPassword length: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
+        (byte) 0x00, (byte) 0x00,
+        
+        // cbAlternateShell:  0 bytes (LE) (NOT including size of mandatory NULL terminator)
+        (byte) 0x00, (byte) 0x00, 
+        
+        // cbWorkingDir: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
+        (byte) 0x00, (byte) 0x00,
+        
+        // Values
+        
+        // Domain: "" (UCS2), see cbDomain
+        (byte) 0x00, (byte) 0x00, 
+        
+        // User name: "vlisivka" (UCS2), see cbUserName
+        (byte) 0x76, (byte) 0x00, (byte) 0x6c, (byte) 0x00, (byte) 0x69, (byte) 0x00, (byte) 0x73, (byte) 0x00, 
+        (byte) 0x69, (byte) 0x00, (byte) 0x76, (byte) 0x00, (byte) 0x6b, (byte) 0x00, (byte) 0x61, (byte) 0x00, 
+        (byte) 0x00, (byte) 0x00, 
+        
+        // Password: "" (UCS2), see cbPassword
+        (byte) 0x00, (byte) 0x00, 
+        
+        // Alternate shell: "" (UCS2), see cbAlternateShell
+        (byte) 0x00, (byte) 0x00, 
+        
+        // Working directory: "" (UCS2), see cbWorkingDir
+        (byte) 0x00, (byte) 0x00, 
+        
+        // Client address family: 2 (AF_INET, LE)
+        (byte) 0x02, (byte) 0x00, 
+        
+        // cbClientAddress = 28 bytes (0x1c, LE) (including the size of the mandatory NULL terminator)
+        (byte) 0x1c, (byte) 0x00, 
+        
+        // Client address: "192.168.0.100" (UCS2) 
+        (byte) 0x31, (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x32, (byte) 0x00, (byte) 0x2e, (byte) 0x00,
+        (byte) 0x31, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x38, (byte) 0x00, (byte) 0x2e, (byte) 0x00,
+        (byte) 0x30, (byte) 0x00, (byte) 0x2e, (byte) 0x00, (byte) 0x31, (byte) 0x00, (byte) 0x30, (byte) 0x00, 
+        (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        
+        // cbClientDir: 64 bytes (0x40, LE) (including the size of the mandatory NULL terminator)
+        (byte) 0x40, (byte) 0x00,
+        
+        // Client directory: "C:\Windows\System32\mstscax.dll" (UCS2)
+        (byte) 0x43, (byte) 0x00, (byte) 0x3a, (byte) 0x00, (byte) 0x5c, (byte) 0x00, (byte) 0x57, (byte) 0x00, 
+        (byte) 0x69, (byte) 0x00, (byte) 0x6e, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x6f, (byte) 0x00, 
+        (byte) 0x77, (byte) 0x00, (byte) 0x73, (byte) 0x00, (byte) 0x5c, (byte) 0x00, (byte) 0x53, (byte) 0x00, 
+        (byte) 0x79, (byte) 0x00, (byte) 0x73, (byte) 0x00, (byte) 0x74, (byte) 0x00, (byte) 0x65, (byte) 0x00, 
+        (byte) 0x6d, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x32, (byte) 0x00, (byte) 0x5c, (byte) 0x00, 
+        (byte) 0x6d, (byte) 0x00, (byte) 0x73, (byte) 0x00, (byte) 0x74, (byte) 0x00, (byte) 0x73, (byte) 0x00, 
+        (byte) 0x63, (byte) 0x00, (byte) 0x61, (byte) 0x00, (byte) 0x78, (byte) 0x00, (byte) 0x2e, (byte) 0x00, 
+        (byte) 0x64, (byte) 0x00, (byte) 0x6c, (byte) 0x00, (byte) 0x6c, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        
+        //
+        // Client time zone:
+        
+        // Bias: 0 minutes (LE)
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        
+        // Standard name: "EET, Standard Time" (fixed string: 64 bytes, UCS2)
+        (byte) 0x45, (byte) 0x00, (byte) 0x45, (byte) 0x00, (byte) 0x54, (byte) 0x00, (byte) 0x2c, (byte) 0x00, 
+        (byte) 0x20, (byte) 0x00, (byte) 0x53, (byte) 0x00, (byte) 0x74, (byte) 0x00, (byte) 0x61, (byte) 0x00, 
+        (byte) 0x6e, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x61, (byte) 0x00, (byte) 0x72, (byte) 0x00, 
+        (byte) 0x64, (byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x54, (byte) 0x00, (byte) 0x69, (byte) 0x00, 
+        (byte) 0x6d, (byte) 0x00, (byte) 0x65, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        
+        //
+        // Standard date
+        // wYear: 0 (LE)
+        (byte) 0x00, (byte) 0x00, 
+        // wMonth: unknown (LE)
+        (byte) 0x00, (byte) 0x00, 
+        // wDayOfWeek: Sunday (LE)
+        (byte) 0x00, (byte) 0x00, 
+        // wDay: unknown (LE)
+        (byte) 0x00, (byte) 0x00, 
+        // wHour: 0 (LE)
+        (byte) 0x00, (byte) 0x00, 
+        // wMinute: 0 (LE)
+        (byte) 0x00, (byte) 0x00, 
+        // wSecond: 0 (LE)
+        (byte) 0x00, (byte) 0x00, 
+        // wMilliseconds: 0
+        (byte) 0x00, (byte) 0x00,
+        
+        // StandardBias: 0 minutes (LE)
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+        
+        // Daylight name: "EET, Summer Time" (fixed string: 64 bytes, UCS2)
+        (byte) 0x45, (byte) 0x00, (byte) 0x45, (byte) 0x00, (byte) 0x54, (byte) 0x00, (byte) 0x2c, (byte) 0x00, 
+        (byte) 0x20, (byte) 0x00, (byte) 0x53, (byte) 0x00, (byte) 0x75, (byte) 0x00, (byte) 0x6d, (byte) 0x00, 
+        (byte) 0x6d, (byte) 0x00, (byte) 0x65, (byte) 0x00, (byte) 0x72, (byte) 0x00, (byte) 0x20, (byte) 0x00, 
+        (byte) 0x54, (byte) 0x00, (byte) 0x69, (byte) 0x00, (byte) 0x6d, (byte) 0x00, (byte) 0x65, (byte) 0x00, 
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+        
+        // Daylight date
+        // wYear: 0 (LE)
+        (byte) 0x00, (byte) 0x00, 
+        // wMonth: unknown (LE)
+        (byte) 0x00, (byte) 0x00,
+        // wDayOfWeek: Sunday (LE)
+        (byte) 0x00, (byte) 0x00,
+        // wDay: unknown (LE)
+        (byte) 0x00, (byte) 0x00,
+        // wHour: 0 (LE)
+        (byte) 0x00, (byte) 0x00,
+        // wMinute: 0 (LE)
+        (byte) 0x00, (byte) 0x00,
+        // wSecond: 0 (LE)
+        (byte) 0x00, (byte) 0x00,
+        // wMilliseconds: 0
+        (byte) 0x00, (byte) 0x00,
+        
+        // Daylight bias: 60 minutes (LE)
+        (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        
+        
+        // Client session ID: 0x00000000 (LE)
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+        
+        // Performance flags: 0x7 (LE) = PERF_DISABLE_WALLPAPER (0x1), PERF_DISABLE_FULLWINDOWDRAG (0x2), PERF_DISABLE_MENUANIMATIONS (0x4)
+        (byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+        
+        // cbAutoReconnectCookie: 0 bytes (LE)
+        (byte) 0x00, (byte) 0x00, 
+    };
+    /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element client_info = new ClientInfoPDU("client_info", "vlisivka");
+        Element x224 = new ClientX224DataPDU("x224");
+        Element tpkt = new ClientTpkt("tpkt");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, client_info, x224, tpkt, sink, mainSink);
+        pipeline.link("source", "client_info", "mainSink");
+        pipeline.link("client_info >" + OTOUT, "x224", "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSAttachUserRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSAttachUserRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSAttachUserRequest.java
new file mode 100755
index 0000000..dbe8bd1
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSAttachUserRequest.java
@@ -0,0 +1,103 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240684.aspx
+ */
+public class ClientMCSAttachUserRequest extends OneTimeSwitch {
+
+    public ClientMCSAttachUserRequest(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        int length = 1;
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        buf.writeByte(0x28); // AttachUserRequest
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+
+        0x03, 0x00, 0x00, 0x08,  //  TPKT Header (length = 8 bytes)
+        0x02, (byte) 0xf0, (byte) 0x80,  //  X.224 Data TPDU
+        
+        // PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
+        0x28, 
+        
+        // 0x28:
+        // 0 - --\
+        // 0 -   |
+        // 1 -   | CHOICE: From DomainMCSPDU select attachUserRequest (10) 
+        // 0 -   | of type AttachUserRequest
+        // 1 -   |
+        // 0 - --/
+        // 0 - padding
+        // 0 - padding
+
+    };
+    /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element todo = new ClientMCSAttachUserRequest("TODO");
+        Element x224 = new ClientX224DataPDU("x224");
+        Element tpkt = new ClientTpkt("tpkt");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
+        pipeline.link("source", "TODO", "mainSink");
+        pipeline.link("TODO >" + OTOUT, "x224", "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs.java
new file mode 100755
index 0000000..59dd233
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs.java
@@ -0,0 +1,223 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * The MCS Channel Join Request PDUs are sent sequentially. The first PDU is
+ * sent after receiving the MCS Attach User Confirm PDU and subsequent PDUs are
+ * sent after receiving the MCS Channel Join Confirm PDU for the previous
+ * request. Sending of the MCS Channel Join Request PDUs MUST continue until all
+ * channels have been successfully joined.
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc240686.aspx
+ */
+public class ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs extends OneTimeSwitch {
+
+    private static final int MCS_CHANNEL_CONFIRM_PDU = 15;
+
+    protected int[] channels;
+    protected int channelRequestsSent = 0;
+
+    protected RdpState state;
+
+    public ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs(String id, int[] channels, RdpState state) {
+        super(id);
+        this.channels = channels;
+        this.state = state;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        // Parse channel confirm response
+        int typeAndFlags = buf.readUnsignedByte();
+        int type = typeAndFlags >> 2;
+        // int flags = typeAndFlags & 0x3;
+
+        if (type != MCS_CHANNEL_CONFIRM_PDU)
+            throw new RuntimeException("[" + this + "] ERROR: Incorrect type of MCS AttachUserConfirm PDU. Expected value: 15, actual value: " + type + ", data: " + buf + ".");
+
+        int rtSuccess = buf.readUnsignedByte() >> 4;
+        if (rtSuccess != 0)
+            throw new RuntimeException("[" + this + "] ERROR: Cannot connect to channel: request failed. Error code: " + rtSuccess + ", channel ID: "
+                    + channels[channelRequestsSent - 1]
+                    + ", data: " + buf + ".");
+
+        // Initiator and requested fields MAY be ignored, however, the channelId
+        // field MUST be examined. If the value of the channelId field does not
+        // correspond with the value of the channelId field sent in the previous MCS
+        // Channel Join Request PDU the connection SHOULD be dropped.
+
+        // Initiator: 1007 (6+1001)
+        // int initator=buf.readUnsignedShort();
+        buf.skipBytes(2);
+
+        // Requested channel
+        // int requestedChannel=buf.readUnsignedShort();
+        buf.skipBytes(2);
+
+        // Actual channel
+        int actualChannel = buf.readUnsignedShort();
+        if (actualChannel != channels[channelRequestsSent - 1])
+            throw new RuntimeException("Unexpeceted channeld ID returned. Expected channeld ID: " + channels[channelRequestsSent - 1] + ", actual channel ID: "
+                    + actualChannel + ", data: " + buf + ".");
+
+        state.channelJoined(actualChannel);
+
+        buf.unref();
+
+        if (channelRequestsSent < channels.length)
+            sendChannelRequest(channels[channelRequestsSent++]);
+        else
+            switchOff();
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        sendChannelRequest(channels[channelRequestsSent++]);
+
+        // Switch off after receiving response(s)
+    }
+
+    private void sendChannelRequest(int channel) {
+        ByteBuffer buf = new ByteBuffer(5, true);
+
+        buf.writeByte(0x38); // Channel Join request
+
+        buf.writeShort(state.serverUserChannelId - 1001); // ChannelJoinRequest::initiator: 1004
+        buf.writeShort(channel);
+
+        pushDataToOTOut(buf);
+    }
+
+    /**
+     * Example.
+     * 
+     * @see http://msdn.microsoft.com/en-us/library/cc240834.aspx
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] clientRequestPacket = new byte[] {
+        0x03, 0x00, 0x00, 0x0c,  //  TPKT Header (length = 12 bytes)
+        0x02, (byte) 0xf0, (byte) 0x80,  //  X.224 Data TPDU
+        
+        // PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
+        0x38, 0x00, 0x03, 0x03, (byte) 0xef, 
+
+         // 0x38:
+         // 0 - --\
+         // 0 -   |
+         // 1 -   | CHOICE: From DomainMCSPDU select channelJoinRequest (14) 
+         // 1 -   | of type ChannelJoinRequest
+         // 1 -   |
+         // 0 - --/
+         // 0 - padding
+         // 0 - padding
+
+         // 0x00:
+         // 0 - --\
+         // 0 -   | 
+         // 0 -   | 
+         // 0 -   | 
+         // 0 -   | 
+         // 0 -   | 
+         // 0 -   | 
+         // 0 -   | 
+         //       | ChannelJoinRequest::initiator = 0x03 + 1001 = 1004
+         // 0x03: |
+         // 0 -   | 
+         // 0 -   | 
+         // 0 -   | 
+         // 0 -   | 
+         // 0 -   | 
+         // 1 -   | 
+         // 1 -   | 
+         // 0 - --/
+
+         // 0x03:
+         // 0 - --\
+         // 0 -   |
+         // 0 -   |
+         // 0 -   |
+         // 0 -   |
+         // 0 -   |
+         // 1 -   |
+         // 1 -   |
+         //       | ChannelJoinRequest::channelId = 0x03ef = 1007
+         // 0xef: |
+         // 1 -   |
+         // 1 -   |
+         // 1 -   |
+         // 0 -   |
+         // 1 -   |
+         // 1 -   |
+         // 1 -   |
+         // 1 - --/
+    };
+    
+    byte[] serverResponsePacket = new byte[] {
+        // MCS Channel Confirm
+    (byte)0x3e, 
+    
+    // result: rt-successful (0)
+    (byte)0x00, 
+    
+    // Initiator: 1007 (6+1001)
+    (byte)0x00, (byte)0x06, 
+    
+    // Requested channel
+    (byte)0x03, (byte)0xef,
+    
+    // Actual channel
+    (byte)0x03, (byte)0xef,
+    };
+    /* @formatter:on */
+
+        RdpState rdpState = new RdpState();
+        rdpState.serverUserChannelId = 1004;
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(serverResponsePacket, new byte[] {1, 2, 3}));
+        Element todo = new ClientMCSChannelJoinRequest_ServerMCSChannelConfirmPDUs("channels", new int[] {1007}, rdpState);
+        Element x224 = new ClientX224DataPDU("x224");
+        Element tpkt = new ClientTpkt("tpkt");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(clientRequestPacket));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
+        pipeline.link("source", "channels", "mainSink");
+        pipeline.link("channels >" + OTOUT, "x224", "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}


[21/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/SizeChangeListener.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/SizeChangeListener.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/SizeChangeListener.java
old mode 100644
new mode 100755
index d658d1b..0be8761
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/SizeChangeListener.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/SizeChangeListener.java
@@ -18,5 +18,5 @@ package common;
 
 public interface SizeChangeListener {
 
-  public void sizeChanged(int width, int height);
+    public void sizeChanged(int width, int height);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtBellAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtBellAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtBellAdapter.java
new file mode 100755
index 0000000..7a1feb1
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtBellAdapter.java
@@ -0,0 +1,76 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.adapter;
+
+import java.awt.Toolkit;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.FakeSource;
+
+public class AwtBellAdapter extends BaseElement {
+
+    public AwtBellAdapter(String id) {
+        super(id);
+        declarePads();
+    }
+
+    private void declarePads() {
+        inputPads.put(STDIN, null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        if (buf == null)
+            return;
+
+        Toolkit.getDefaultToolkit().beep();
+    }
+
+    public String toString() {
+        return "Bell(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        System.setProperty("streamer.Element.debug", "true");
+
+        Element source = new FakeSource("source") {
+            {
+                this.incommingBufLength = 0;
+                this.delay = 1000;
+                this.numBuffers = 3;
+            }
+        };
+
+        Element sink = new AwtBellAdapter("sink");
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.addAndLink(source, sink);
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java
new file mode 100755
index 0000000..788d370
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java
@@ -0,0 +1,171 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.adapter;
+
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+
+import common.BitmapOrder;
+import common.BitmapRectangle;
+import common.BufferedImageCanvas;
+import common.CopyRectOrder;
+import common.OrderType;
+import common.ScreenDescription;
+
+import rdpclient.rdp.ServerBitmapUpdate;
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Order;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+
+public class AwtCanvasAdapter extends BaseElement {
+
+    protected ScreenDescription screen;
+
+    public AwtCanvasAdapter(String id, BufferedImageCanvas canvas, ScreenDescription screen) {
+        super(id);
+        this.canvas = canvas;
+        this.screen = screen;
+    }
+
+    protected BufferedImageCanvas canvas;
+
+    public String toString() {
+        return "AwtRdpAdapter(" + id + ")";
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        Order order = (Order)buf.getOrder();
+        switch ((OrderType)order.type) {
+
+        case BITMAP_UPDATE:
+            handleBitmap((BitmapOrder)order, buf);
+            break;
+
+        case COPY_RECT:
+            handleCopyRect((CopyRectOrder)order, buf);
+            break;
+
+        default:
+            throw new RuntimeException("Order is not implemented: " + buf + ".");
+            // break;
+        }
+
+        buf.unref();
+    }
+
+    private void handleCopyRect(CopyRectOrder order, ByteBuffer buf) {
+        // TODO Auto-generated method stub
+        // Copy image
+        canvas.getOfflineGraphics().copyArea(order.srcX, order.srcY, order.width, order.height, order.x - order.srcX, order.y - order.srcY);
+
+        // Request update of repainted area
+        canvas.repaint(order.x, order.y, order.width, order.height);
+
+    }
+
+    private void handleBitmap(BitmapOrder order, ByteBuffer buf) {
+        // Draw rectangle on offline buffer
+        BufferedImage image = canvas.getOfflineImage();
+        Graphics2D g = (Graphics2D)image.getGraphics();
+
+        for (BitmapRectangle rectangle : order.rectangles) {
+            // *DEBUG*/System.out.println("["+this+"] DEBUG: Rectangle: " +
+            // rectangle.toString());
+
+            int x = rectangle.x;
+            int y = rectangle.y;
+            int width = rectangle.width;
+            int height = rectangle.height;
+            int bufferWidth = rectangle.bufferWidth;
+            int bufferHeight = rectangle.bufferHeight;
+
+            BufferedImage rectImage;
+            switch (rectangle.colorDepth) {
+            case 8: {
+                rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_BYTE_INDEXED, screen.colorMap);
+                WritableRaster raster = rectImage.getRaster();
+                raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toByteArray());
+                break;
+            }
+            case 15: {
+                rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_USHORT_555_RGB);
+                WritableRaster raster = rectImage.getRaster();
+                raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toShortArray());
+                break;
+            }
+            case 16: {
+                rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_USHORT_565_RGB);
+                WritableRaster raster = rectImage.getRaster();
+                raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toShortArray());
+                break;
+            }
+            case 24:
+            case 32: {
+                rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_INT_RGB);
+                WritableRaster raster = rectImage.getRaster();
+                raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toIntLEArray());
+                break;
+            }
+            default:
+                throw new RuntimeException("Unsupported color depth: " + rectangle.colorDepth + ".");
+            }
+
+            g.setClip(x, y, width, height);
+            g.drawImage(rectImage, x, y, null);
+
+            // Request update of repainted area
+            canvas.repaint(x, y, width, height);
+        }
+
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        // System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+        ByteBuffer packet = new ByteBuffer(new byte[] {0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x00,
+                0x01, 0x04, 0x0a, 0x00, 0x0c, (byte)0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
+
+        Pipeline pipeline = new PipelineImpl("test");
+
+        Element bitmap = new ServerBitmapUpdate("bitmap");
+
+        BufferedImageCanvas canvas = new BufferedImageCanvas(1024, 768);
+        Element adapter = new AwtCanvasAdapter("test", canvas, null) {
+            {
+                verbose = true;
+            }
+        };
+        pipeline.addAndLink(bitmap, adapter);
+
+        bitmap.handleData(packet, null);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtClipboardAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtClipboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtClipboardAdapter.java
new file mode 100755
index 0000000..ccdabf8
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtClipboardAdapter.java
@@ -0,0 +1,56 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.adapter;
+
+import java.awt.Toolkit;
+import java.awt.datatransfer.StringSelection;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class AwtClipboardAdapter extends BaseElement {
+
+    public static final String CLIPBOARD_CONTENT = "content";
+
+    public AwtClipboardAdapter(String id) {
+        super(id);
+        declarePads();
+    }
+
+    private void declarePads() {
+        inputPads.put(STDIN, null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        if (buf == null)
+            return;
+
+        String content = (String)buf.getMetadata(CLIPBOARD_CONTENT);
+        StringSelection contents = new StringSelection(content);
+        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(contents, null);
+    }
+
+    public String toString() {
+        return "ClipboardAdapter(" + id + ")";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Any.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Any.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Any.java
new file mode 100755
index 0000000..dd73560
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Any.java
@@ -0,0 +1,78 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.asn1;
+
+import streamer.ByteBuffer;
+
+/**
+ * Any type. Don't forget to set type.
+ */
+public class Any extends Tag {
+
+    /**
+     * Raw bytes of any value.
+     */
+    public ByteBuffer value;
+
+    public Any(String name) {
+        super(name);
+    }
+
+    @Override
+    public boolean isValueSet() {
+        return value != null;
+    }
+
+    @Override
+    public long calculateLengthOfValuePayload() {
+        return value.length;
+    }
+
+    @Override
+    public void writeTagValuePayload(ByteBuffer buf) {
+        buf.writeBytes(value);
+    }
+
+    @Override
+    public void readTagValue(ByteBuffer buf, BerType typeAndFlags) {
+        long length = buf.readBerLength();
+
+        value = buf.readBytes((int)length);
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new Any(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+        this.tagType = tag.tagType;
+        this.value = new ByteBuffer(((Any)tag).value.toByteArray());
+        return this;
+    }
+
+    @Override
+    public boolean isTypeValid(BerType typeAndFlags, boolean explicit) {
+        if (explicit)
+            return typeAndFlags.tagClass == tagClass && typeAndFlags.constructed && typeAndFlags.typeOrTagNumber == tagNumber;
+        else
+            return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Constants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Constants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Constants.java
new file mode 100755
index 0000000..6dacd60
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Constants.java
@@ -0,0 +1,83 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.asn1;
+
+public interface Asn1Constants {
+
+    /**
+     * Universal class type.
+     */
+    public static final int UNIVERSAL_CLASS = 0x00;
+
+    /**
+     * Application class type.
+     */
+    public static final int APPLICATION_CLASS = 0x40;
+
+    public static final int CONTEXT_CLASS = 0x80;
+
+    public static final int PRIVATE_CLASS = 0xC0;
+
+    /**
+     * Constructed type.
+     */
+    public static final int CONSTRUCTED = 0x20;
+
+    /**
+     * Mask to extract class.
+     */
+    public static final int CLASS_MASK = 0xC0;
+
+    /**
+     * Mask to extract type.
+     */
+    public static final int TYPE_MASK = 0x1F;
+
+    public static final int EOF = 0x00;
+    public static final int BOOLEAN = 0x01;
+    /**
+     * Integer primitive.
+     */
+    public static final int INTEGER = 0x02;
+    public static final int BIT_STRING = 0x03;
+    /**
+     * Octet string primitive.
+     */
+    public static final int OCTET_STRING = 0x04;
+    public static final int NULL = 0x05;
+    public static final int OBJECT_ID = 0x06;
+    public static final int REAL = 0x09;
+    public static final int ENUMERATED = 0x0A;
+    /**
+     * Sequence primitive.
+     */
+    public static final int SEQUENCE = 0x10;
+    public static final int SET = 0x11;
+    public static final int NUMERIC_STRING = 0x12;
+    public static final int PRINTABLE_STRING = 0x13;
+    public static final int TELETEX_STRING = 0x14;
+    public static final int VIDEOTEXT_STRING = 0x15;
+    public static final int IA5_STRING = 0x16;
+    public static final int UTCTIME = 0x17;
+    public static final int GENERAL_TIME = 0x18;
+    public static final int GRAPHIC_STRING = 0x19;
+    public static final int VISIBLE_STRING = 0x1A;
+    public static final int GENERAL_STRING = 0x1B;
+
+    public static final int EXTENDED_TYPE = 0x1F;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Integer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Integer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Integer.java
new file mode 100755
index 0000000..fb8715f
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Integer.java
@@ -0,0 +1,116 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.asn1;
+
+import streamer.ByteBuffer;
+
+/**
+ * Variable length integer.
+ */
+public class Asn1Integer extends Tag {
+
+    public Long value = null;
+
+    public Asn1Integer(String name) {
+        super(name);
+        this.tagType = INTEGER;
+    }
+
+    @Override
+    public void readTagValue(ByteBuffer buf, BerType typeAndFlags) {
+        // Type is already read by parent parser
+
+        long length = buf.readBerLength();
+        if (length > 8)
+            throw new RuntimeException("[" + this + "] ERROR: Integer value is too long: " + length + " bytes. Cannot handle integers more than 8 bytes long. Data: "
+                    + buf + ".");
+
+        value = buf.readSignedVarInt((int)length);
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new Asn1Integer(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+        this.value = ((Asn1Integer)tag).value;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "= " + value;
+    }
+
+    @Override
+    public long calculateLengthOfValuePayload() {
+        if (value <= 0xff)
+            return 1;
+        if (value <= 0xffFF)
+            return 2;
+        if (value <= 0xffFFff)
+            return 3;
+        if (value <= 0xffFFffFFL)
+            return 4;
+        if (value <= 0xffFFffFFffL)
+            return 5;
+        if (value <= 0xffFFffFFffFFL)
+            return 6;
+        if (value <= 0xffFFffFFffFFffL)
+            return 7;
+
+        return 8;
+    }
+
+    @Override
+    public void writeTagValuePayload(ByteBuffer buf) {
+        long value = this.value.longValue();
+
+        if (value < 0xff) {
+            buf.writeByte((int)value);
+        } else if (value <= 0xffFF) {
+            buf.writeShort((int)value);
+        } else if (value <= 0xffFFff) {
+            buf.writeByte((int)(value >> 16));
+            buf.writeShort((int)value);
+        } else if (value <= 0xffFFffFFL) {
+            buf.writeInt((int)value);
+        } else if (value <= 0xffFFffFFffL) {
+            buf.writeByte((int)(value >> 32));
+            buf.writeInt((int)value);
+        } else if (value <= 0xffFFffFFffFFL) {
+            buf.writeShort((int)(value >> 32));
+            buf.writeInt((int)value);
+        } else if (value <= 0xffFFffFFffFFffL) {
+            buf.writeByte((int)(value >> (32 + 16)));
+            buf.writeShort((int)(value >> 32));
+            buf.writeInt((int)value);
+        } else {
+            buf.writeInt((int)(value >> 32));
+            buf.writeInt((int)value);
+        }
+    }
+
+    @Override
+    public boolean isValueSet() {
+        return value != null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BerType.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BerType.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BerType.java
new file mode 100755
index 0000000..8e53f24
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BerType.java
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.asn1;
+
+public class BerType {
+
+    public int tagClass;
+    public boolean constructed;
+    public int typeOrTagNumber;
+
+    public BerType() {
+    }
+
+    public BerType(int tagClass, boolean constructed, int typeOrTagNumber) {
+        this.tagClass = tagClass;
+        this.constructed = constructed;
+        this.typeOrTagNumber = typeOrTagNumber;
+    }
+
+    @Override
+    public String toString() {
+        return "BerType [tagClass=" + Tag.tagClassToString(tagClass) + ", constructed=" + constructed + ", type or tag number="
+                + Tag.tagTypeOrNumberToString(tagClass, typeOrTagNumber) + "]";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BitString.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BitString.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BitString.java
new file mode 100755
index 0000000..3aba5d4
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BitString.java
@@ -0,0 +1,67 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.asn1;
+
+import streamer.ByteBuffer;
+
+public class BitString extends Tag {
+
+    /**
+     * Bit string value.
+     */
+    public ByteBuffer value;
+
+    public BitString(String name) {
+        super(name);
+        this.tagType = BIT_STRING;
+    }
+
+    @Override
+    public boolean isValueSet() {
+        return value != null;
+    }
+
+    @Override
+    public long calculateLengthOfValuePayload() {
+        return value.length;
+    }
+
+    @Override
+    public void writeTagValuePayload(ByteBuffer buf) {
+        buf.writeBytes(value);
+    }
+
+    @Override
+    public void readTagValue(ByteBuffer buf, BerType typeAndFlags) {
+        long length = buf.readBerLength();
+
+        value = buf.readBytes((int)length);
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new BitString(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+        this.value = new ByteBuffer(((BitString)tag).value.toByteArray());
+        return this;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/ObjectID.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/ObjectID.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/ObjectID.java
new file mode 100755
index 0000000..47fdb42
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/ObjectID.java
@@ -0,0 +1,67 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.asn1;
+
+import streamer.ByteBuffer;
+
+public class ObjectID extends Tag {
+
+    /**
+     * Raw bytes of encoded OID.
+     */
+    public ByteBuffer value;
+
+    public ObjectID(String name) {
+        super(name);
+        this.tagType = OBJECT_ID;
+    }
+
+    @Override
+    public boolean isValueSet() {
+        return value != null;
+    }
+
+    @Override
+    public long calculateLengthOfValuePayload() {
+        return value.length;
+    }
+
+    @Override
+    public void writeTagValuePayload(ByteBuffer buf) {
+        buf.writeBytes(value);
+    }
+
+    @Override
+    public void readTagValue(ByteBuffer buf, BerType typeAndFlags) {
+        long length = buf.readBerLength();
+
+        value = buf.readBytes((int)length);
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new ObjectID(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+        this.value = new ByteBuffer(((ObjectID)tag).value.toByteArray());
+        return this;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/OctetString.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/OctetString.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/OctetString.java
new file mode 100755
index 0000000..edad843
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/OctetString.java
@@ -0,0 +1,80 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.asn1;
+
+import streamer.ByteBuffer;
+
+public class OctetString extends Tag {
+
+    public ByteBuffer value = null;
+
+    public OctetString(String name) {
+        super(name);
+        this.tagType = OCTET_STRING;
+    }
+
+    @Override
+    public void readTagValue(ByteBuffer buf, BerType typeAndFlags) {
+        // Type is already read by parent parser
+
+        long length = buf.readBerLength();
+
+        if (length > buf.length)
+            throw new RuntimeException("BER octet string is too long: " + length + " bytes. Data: " + buf + ".");
+
+        value = buf.readBytes((int)length);
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new OctetString(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+        this.value = ((OctetString)tag).value;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "= " + value;
+    }
+
+    @Override
+    public long calculateLengthOfValuePayload() {
+        if (value != null)
+            return value.length;
+        else
+            return 0;
+    }
+
+    @Override
+    public void writeTagValuePayload(ByteBuffer buf) {
+        if (value != null)
+            buf.writeBytes(value);
+        else
+            return;
+    }
+
+    @Override
+    public boolean isValueSet() {
+        return value != null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Sequence.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Sequence.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Sequence.java
new file mode 100755
index 0000000..1676f69
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Sequence.java
@@ -0,0 +1,143 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.asn1;
+
+import java.util.Arrays;
+
+import streamer.ByteBuffer;
+
+/**
+ * One or more elements of different types.
+ * 
+ * Only prefixed tags are supported.
+ */
+public class Sequence extends Tag {
+
+    public Tag[] tags;
+
+    public Sequence(String name) {
+        super(name);
+        this.tagType = SEQUENCE;
+        // Sequence and SequenceOf are always encoded as constructed
+        this.constructed = true;
+    }
+
+    @Override
+    public long calculateLengthOfValuePayload() {
+        long sum = 0;
+
+        for (Tag tag : tags) {
+            long tagLength = tag.calculateFullLength();
+            sum += tagLength;
+        }
+
+        return sum;
+    }
+
+    @Override
+    public void writeTagValuePayload(ByteBuffer buf) {
+        // Write tags
+        for (Tag tag : tags) {
+            tag.writeTag(buf);
+        }
+    }
+
+    @Override
+    public void readTagValue(ByteBuffer buf, BerType typeAndFlags) {
+        // Type is already read by parent parser
+
+        long length = buf.readBerLength();
+        if (length > buf.remainderLength())
+            throw new RuntimeException("BER sequence is too long: " + length + " bytes, while buffer remainder length is " + buf.remainderLength() + ". Data: " + buf
+                    + ".");
+
+        ByteBuffer value = buf.readBytes((int)length);
+        parseContent(value);
+
+        value.unref();
+    }
+
+    protected void parseContent(ByteBuffer buf) {
+        for (int i = 0; buf.remainderLength() > 0 && i < tags.length; i++) {
+            BerType typeAndFlags = readBerType(buf);
+
+            // If current tag does not match data in buffer
+            if (!tags[i].isTypeValid(typeAndFlags)) {
+
+                // If tag is required, then throw exception
+                if (!tags[i].optional) {
+                    throw new RuntimeException("[" + this + "] ERROR: Required tag is missed: " + tags[i] + ". Unexected tag type: " + typeAndFlags + ". Data: " + buf
+                            + ".");
+                } else {
+                    // One or more tags are omitted, so skip them
+                    for (; i < tags.length; i++) {
+                        if (tags[i].isTypeValid(typeAndFlags)) {
+                            break;
+                        }
+                    }
+
+                    if (i >= tags.length || !tags[i].isTypeValid(typeAndFlags)) {
+                        throw new RuntimeException("[" + this + "] ERROR: No more tags to read or skip, but some data still left in buffer. Unexected tag type: "
+                                + typeAndFlags + ". Data: " + buf + ".");
+                    }
+                }
+            }
+
+            tags[i].readTag(buf, typeAndFlags);
+        }
+
+    }
+
+    @Override
+    public boolean isTypeValid(BerType typeAndFlags, boolean explicit) {
+        if (explicit)
+            return typeAndFlags.tagClass == tagClass && typeAndFlags.constructed && typeAndFlags.typeOrTagNumber == tagNumber;
+        else
+            // Sequences are always encoded as "constructed" in BER.
+            return typeAndFlags.tagClass == UNIVERSAL_CLASS && typeAndFlags.constructed && typeAndFlags.typeOrTagNumber == SEQUENCE;
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new Sequence(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+
+        if (this.tags.length != ((Sequence)tag).tags.length)
+            throw new RuntimeException("Incompatible sequences. This: " + this + ", another: " + tag + ".");
+
+        for (int i = 0; i < tags.length; i++) {
+            this.tags[i].copyFrom(((Sequence)tag).tags[i]);
+        }
+
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "{" + Arrays.toString(tags) + " }";
+    }
+
+    @Override
+    public boolean isValueSet() {
+        return tags != null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/SequenceOf.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/SequenceOf.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/SequenceOf.java
new file mode 100755
index 0000000..aa4543c
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/SequenceOf.java
@@ -0,0 +1,81 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.asn1;
+
+import java.util.ArrayList;
+
+import streamer.ByteBuffer;
+
+/**
+ * Zero or more elements of same type (array).
+ */
+public class SequenceOf extends Sequence {
+
+    /**
+     * Type of this array.
+     */
+    public Tag type;
+
+    /* Values are stored in tags[] variable inherited from Sequence. */
+
+    public SequenceOf(String name) {
+        super(name);
+    }
+
+    protected void parseContent(ByteBuffer buf) {
+        ArrayList<Tag> tagList = new ArrayList<Tag>();
+
+        for (int index = 0; buf.remainderLength() > 0; index++) {
+            // End of array is marked with two zero bytes (0x00 0x00)
+            if (buf.peekUnsignedByte(0) == 0x00 && buf.peekUnsignedByte(1) == 0x00) {
+                break;
+            }
+
+            Tag tag = (Tag)type.deepCopy(index);
+
+            tag.readTag(buf);
+            tagList.add(tag);
+        }
+
+        tags = tagList.toArray(new Tag[tagList.size()]);
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new SequenceOf(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+        // We can create shallow copy of type, because it will not be modified
+        this.type = ((SequenceOf)tag).type;
+
+        this.tags = new Tag[((Sequence)tag).tags.length];
+        for (int i = 0; i < tags.length; i++) {
+            this.tags[i] = ((Sequence)tag).tags[i].deepCopy("");
+        }
+
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + ": " + type;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Tag.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Tag.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Tag.java
new file mode 100755
index 0000000..8fb8c82
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Tag.java
@@ -0,0 +1,462 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.asn1;
+
+import streamer.ByteBuffer;
+
+public abstract class Tag implements Asn1Constants {
+
+    /**
+     * Name of this tag, for debugging purposes.
+     */
+    public String name = "";
+
+    /**
+     * Is this tag required or optional, for explicit tags only.
+     */
+    public boolean optional = false;
+
+    /**
+     * Tag primitive (e.g. implicit boolean), or constructed (e.g. sequence, or
+     * explicit boolean).
+     */
+    public boolean constructed = false;
+
+    /**
+     * Class of tag, when it is explicit.
+     */
+    public int tagClass = UNIVERSAL_CLASS;
+
+    /**
+     * Tag number (e.g. index in sequence), when tag is explicit.
+     */
+    public int tagNumber = -1;
+
+    /**
+     * Tag type (e.g. INDER), when tag is implicit.
+     */
+    public int tagType = -1;
+
+    /**
+     * If tag is explicit, then it is prefixed with tag number, so it can be
+     * optional or used in unordered set.
+     */
+    public boolean explicit = false;
+
+    public Tag(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Write tag value, with or without prefix.
+     */
+    public void writeTag(ByteBuffer buf) {
+
+        if (!isMustBeWritten())
+            return;
+
+        // Write prefix, when necessary
+        if (explicit) {
+
+            // Write tag prefix, always constructed
+            BerType berTagPrefix = new BerType(tagClass, true, tagNumber);
+            writeBerType(buf, berTagPrefix);
+
+            // Write tag prefix length
+            buf.writeBerLength(calculateLength());
+
+            // Write tag value
+            writeTagValue(buf);
+        } else {
+            // If implicit, just write tag value
+            writeTagValue(buf);
+        }
+    }
+
+    /**
+     * Must return true when value of this tag is set or tag is required, so it
+     * can be written, false otherwise.
+     */
+    public boolean isMustBeWritten() {
+        return !optional || isValueSet();
+    }
+
+    /**
+     * Must return true when value of this tag is set or tag is required, so it
+     * can be written, false otherwise.
+     */
+    public abstract boolean isValueSet();
+
+    /**
+     * Calculate full length of tag, including type (or prefix, when explicit).
+     */
+    public long calculateFullLength() {
+        if (!isMustBeWritten())
+            return 0;
+
+        // Length of value, including type
+        long length = calculateLength();
+
+        if (!explicit) {
+            // Length of tag type and it length
+            length += calculateLengthOfTagTypeOrTagNumber(tagType) + calculateLengthOfLength(length);
+        } else {
+            // Length of tag prefix and it length
+            length += calculateLengthOfTagTypeOrTagNumber(tagNumber) + calculateLengthOfLength(length);
+        }
+
+        return length;
+    }
+
+    /**
+     * Calculate length of tag, including type when explicit, but without length
+     * of prefix (or type, when implicit).
+     */
+    public long calculateLength() {
+        if (!isMustBeWritten())
+            return 0;
+
+        // Length of value
+        long length = calculateLengthOfValuePayload();
+
+        if (explicit) {
+            // Length of tag type and it length
+            length += calculateLengthOfTagTypeOrTagNumber(tagType) + calculateLengthOfLength(length);
+        }
+
+        return length;
+    }
+
+    /**
+     * Calculate length of BER length.
+     */
+    public int calculateLengthOfLength(long length) {
+        if (length < 0)
+            throw new RuntimeException("[" + this + "] ERROR: Length of tag cannot be less than zero: " + length + ".");
+
+        if (length <= 0x7f)
+            return 1;
+        if (length <= 0xff)
+            return 2;
+        if (length <= 0xffFF)
+            return 3;
+        if (length <= 0xffFFff)
+            return 4;
+        if (length <= 0xffFFffFFL)
+            return 5;
+        if (length <= 0xffFFffFFffL)
+            return 6;
+        if (length <= 0xffFFffFFffFFL)
+            return 7;
+        if (length <= 0xffFFffFFffFFffL)
+            return 8;
+
+        return 9;
+    }
+
+    /**
+     * Calculate length of type to tag number. Values less than 31 are encoded
+     * using lower 5 bits of first byte of tag. Values larger than 31 are
+     * indicated by lower 5 bits set to 1 (0x1F, 31), and next bytes are contain
+     * value in network order, where topmost bit of byte (0x80) indicates is value
+     * contains more bytes, i.e. last byte of sequence has this bit set to 0.
+     */
+    public int calculateLengthOfTagTypeOrTagNumber(int tagType) {
+        if (tagType >= EXTENDED_TYPE)
+            throw new RuntimeException("Multibyte tag types are not supported yet.");
+
+        return 1;
+    }
+
+    /**
+     * Calculate length of payload only, without tag prefix, tag type, and
+     * lengths.
+     * 
+     * @return
+     */
+    public abstract long calculateLengthOfValuePayload();
+
+    /**
+     * Write tag value only, without prefix.
+     */
+    public void writeTagValue(ByteBuffer buf) {
+
+        // Write type
+        BerType valueType = new BerType(UNIVERSAL_CLASS, constructed, tagType);
+        writeBerType(buf, valueType);
+
+        // Write length
+        long lengthOfPayload = calculateLengthOfValuePayload();
+        buf.writeBerLength(lengthOfPayload);
+
+        // Store cursor to check is calculated length matches length of actual bytes
+        // written
+        int storedCursor = buf.cursor;
+
+        // Write value
+        writeTagValuePayload(buf);
+
+        // Check is calculated length matches length of actual bytes written, to catch errors early
+        int actualLength = buf.cursor - storedCursor;
+        if (actualLength != lengthOfPayload)
+            throw new RuntimeException("[" + this + "] ERROR: Unexpected length of data in buffer. Expected " + lengthOfPayload + " of bytes of payload, but "
+                    + actualLength + " bytes are written instead. Data: " + buf + ".");
+    }
+
+    /**
+     * Write tag value only, without prefix, tag type, and length.
+     */
+    public abstract void writeTagValuePayload(ByteBuffer buf);
+
+    /**
+     * Read required tag, i.e. we are 100% sure that byte buffer will contain this
+     * tag, or exception will be thrown otherwise.
+     * 
+     * @param buf
+     *          buffer with tag data
+     */
+    public void readTag(ByteBuffer buf) {
+        BerType typeAndFlags = readBerType(buf);
+
+        // * DEBUG */System.out.println("Tag, read " + typeAndFlags);
+
+        if (!isTypeValid(typeAndFlags))
+            throw new RuntimeException("[" + this + "] Unexpected type: " + typeAndFlags + ".");
+
+        readTag(buf, typeAndFlags);
+    }
+
+    /**
+     * Read tag when it type is already read.
+     */
+    public void readTag(ByteBuffer buf, BerType typeAndFlags) {
+
+        if (explicit) {
+            long length = buf.readBerLength();
+
+            if (length > buf.length)
+                throw new RuntimeException("BER value is too long: " + length + " bytes. Data: " + buf + ".");
+
+            ByteBuffer value = buf.readBytes((int)length);
+
+            readTagValue(value);
+
+            value.unref();
+        } else {
+
+            readTagValue(buf, typeAndFlags);
+        }
+    }
+
+    /**
+     * Read tag value only, i.e. it prefix is already read.
+     */
+    public void readTagValue(ByteBuffer value) {
+        BerType typeAndFlags = readBerType(value);
+
+        // * DEBUG */System.out.println("Tag, read value " + typeAndFlags);
+
+        if (!isTypeValid(typeAndFlags, false))
+            throw new RuntimeException("[" + this + "] Unexpected type: " + typeAndFlags + ".");
+
+        readTagValue(value, typeAndFlags);
+    }
+
+    /**
+     * Check are tag type and flags valid for this tag.
+     */
+    public final boolean isTypeValid(BerType typeAndFlags) {
+        return isTypeValid(typeAndFlags, explicit);
+    }
+
+    /**
+     * Check are tag type and flags valid for this tag with or without tag prefix.
+     * 
+     * @param explicit
+     *          if true, then value is wrapped in tag prefix
+     */
+    public boolean isTypeValid(BerType typeAndFlags, boolean explicit) {
+        if (explicit)
+            return typeAndFlags.tagClass == tagClass && typeAndFlags.constructed && typeAndFlags.typeOrTagNumber == tagNumber;
+        else
+            return typeAndFlags.tagClass == UNIVERSAL_CLASS && !typeAndFlags.constructed && typeAndFlags.typeOrTagNumber == this.tagType;
+    }
+
+    @Override
+    public String toString() {
+        return "  \nTag [name="
+                + name
+
+                + ((constructed) ? ", constructed=" + constructed : "")
+
+                + (", tagType=" + tagTypeOrNumberToString(UNIVERSAL_CLASS, tagType))
+
+                + ((explicit) ? ", explicit=" + explicit + ", optional=" + optional + ", tagClass=" + tagClassToString(tagClass) + ", tagNumber="
+                        + tagTypeOrNumberToString(tagClass, tagNumber) : "") + "]";
+    }
+
+    public static final String tagTypeOrNumberToString(int tagClass, int tagTypeOrNumber) {
+        switch (tagClass) {
+        case UNIVERSAL_CLASS:
+            switch (tagTypeOrNumber) {
+            case EOF:
+                return "EOF";
+            case BOOLEAN:
+                return "BOOLEAN";
+            case INTEGER:
+                return "INTEGER";
+            case BIT_STRING:
+                return "BIT_STRING";
+            case OCTET_STRING:
+                return "OCTET_STRING";
+            case NULL:
+                return "NULL";
+            case OBJECT_ID:
+                return "OBJECT_ID";
+            case REAL:
+                return "REAL";
+            case ENUMERATED:
+                return "ENUMERATED";
+            case SEQUENCE:
+                return "SEQUENCE";
+            case SET:
+                return "SET";
+            case NUMERIC_STRING:
+                return "NUMERIC_STRING";
+            case PRINTABLE_STRING:
+                return "PRINTABLE_STRING";
+            case TELETEX_STRING:
+                return "TELETEX_STRING";
+            case VIDEOTEXT_STRING:
+                return "VIDEOTEXT_STRING";
+            case IA5_STRING:
+                return "IA5_STRING";
+            case UTCTIME:
+                return "UTCTIME";
+            case GENERAL_TIME:
+                return "GENERAL_TIME";
+            case GRAPHIC_STRING:
+                return "GRAPHIC_STRING";
+            case VISIBLE_STRING:
+                return "VISIBLE_STRING";
+            case GENERAL_STRING:
+                return "GENERAL_STRING";
+            case EXTENDED_TYPE:
+                return "EXTENDED_TYPE (multibyte)";
+            default:
+                return "UNKNOWN(" + tagTypeOrNumber + ")";
+
+            }
+
+        default:
+            return "[" + tagTypeOrNumber + "]";
+        }
+    }
+
+    public static final String tagClassToString(int tagClass) {
+        switch (tagClass) {
+        case UNIVERSAL_CLASS:
+            return "UNIVERSAL";
+        case CONTEXT_CLASS:
+            return "CONTEXT";
+        case APPLICATION_CLASS:
+            return "APPLICATION";
+        case PRIVATE_CLASS:
+            return "PRIVATE";
+        default:
+            return "UNKNOWN";
+        }
+    }
+
+    /**
+     * Read BER tag type.
+     */
+    public BerType readBerType(ByteBuffer buf) {
+        int typeAndFlags = buf.readUnsignedByte();
+
+        int tagClass = typeAndFlags & CLASS_MASK;
+
+        boolean constructed = (typeAndFlags & CONSTRUCTED) != 0;
+
+        int type = typeAndFlags & TYPE_MASK;
+        if (type == EXTENDED_TYPE)
+            throw new RuntimeException("Extended tag types/numbers (31+) are not supported yet.");
+
+        return new BerType(tagClass, constructed, type);
+    }
+
+    /**
+     * Write BER tag type.
+     */
+    public void writeBerType(ByteBuffer buf, BerType berType) {
+
+        if (berType.typeOrTagNumber >= EXTENDED_TYPE || berType.typeOrTagNumber < 0)
+            throw new RuntimeException("Extended tag types/numbers (31+) are not supported yet: " + berType + ".");
+
+        if ((berType.tagClass & CLASS_MASK) != berType.tagClass)
+            throw new RuntimeException("Value of BER tag class is out of range: " + berType.tagClass + ". Expected values: " + UNIVERSAL_CLASS + ", " + CONTEXT_CLASS
+                    + ", " + APPLICATION_CLASS + ", " + PRIVATE_CLASS + ".");
+
+        int typeAndFlags = berType.tagClass | ((berType.constructed) ? CONSTRUCTED : 0) | berType.typeOrTagNumber;
+
+        buf.writeByte(typeAndFlags);
+    }
+
+    /**
+     * Read tag value only, i.e. it prefix is already read, when value type is
+     * already read.
+     * 
+     * @param buf
+     *          buffer with tag data
+     */
+    public abstract void readTagValue(ByteBuffer buf, BerType typeAndFlags);
+
+    /**
+     * Create deep copy of this tag with given suffix appended to name.
+     * 
+     * @param suffix
+     *          suffix to add to tag name, or empty string
+     * @return deep copy of this tag
+     */
+    public abstract Tag deepCopy(String suffix);
+
+    /**
+     * Create deep copy of this tag for array or set.
+     * 
+     * @param index
+     *          index of element in array or set
+     * @return deep copy of this tag
+     */
+    public Tag deepCopy(int index) {
+        return deepCopy("[" + index + "]");
+    }
+
+    /**
+     * Copy tag values from an other tag, except name.
+     * 
+     * @return this
+     */
+    public Tag copyFrom(Tag tag) {
+        this.constructed = tag.constructed;
+        this.explicit = tag.explicit;
+        this.optional = tag.optional;
+        this.tagClass = tag.tagClass;
+        this.tagNumber = tag.tagNumber;
+        return this;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IncrementalOption.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IncrementalOption.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IncrementalOption.java
new file mode 100755
index 0000000..eb24d11
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IncrementalOption.java
@@ -0,0 +1,28 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.opt;
+
+public class IncrementalOption extends Option {
+    int value = 0;
+
+    @Override
+    public int parse(int position, String[] args) {
+        value++;
+        return super.parse(position, args);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IntOption.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IntOption.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IntOption.java
new file mode 100755
index 0000000..87e732a
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IntOption.java
@@ -0,0 +1,41 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.opt;
+
+public class IntOption extends Option {
+    public int value = 0;
+
+    @Override
+    public int parse(int position, String[] args) {
+        if (position + 1 >= args.length)
+            throw new NoArgumentForOptionException("Cannot find required argument for option \"" + args[position] + "\".");
+
+        value = Integer.parseInt(args[position + 1]);
+        return super.parse(position, args) + 1;
+    }
+
+    @Override
+    public String help() {
+        StringBuilder help = new StringBuilder();
+        help.append(join("|", name, alias, aliases)).append(" VALUE\t").append(description);
+        if (required)
+            help.append(" Required.");
+        else if (value != 0)
+            help.append(" Default value is \"").append("" + value).append("\".");
+        return help.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/NoArgumentForOptionException.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/NoArgumentForOptionException.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/NoArgumentForOptionException.java
new file mode 100755
index 0000000..a074672
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/NoArgumentForOptionException.java
@@ -0,0 +1,26 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.opt;
+
+public class NoArgumentForOptionException extends RuntimeException {
+    public NoArgumentForOptionException(String message) {
+        super(message);
+    }
+
+    private static final long serialVersionUID = 1L;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/Option.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/Option.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/Option.java
new file mode 100755
index 0000000..e038075
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/Option.java
@@ -0,0 +1,102 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.opt;
+
+public class Option {
+
+    public String name = "";
+    public String alias = null;
+    public String aliases[] = null;
+
+    public String description = "";
+    public boolean used = false;
+    public boolean required = false;
+
+    /**
+     * Parse option value, if any.
+     * 
+     * @param position
+     *          position of this option in list of arguments
+     * @param args
+     *          command line arguments
+     * @return how many arguments are consumed, at least 1
+     */
+    public int parse(int position, String args[]) {
+        used = true;
+        return 1;
+    }
+
+    @Override
+    public String toString() {
+        return help();
+    }
+
+    /**
+     * Return help string for this option. Example:
+     * 
+     * <pre>
+     *   --foo|-f    Foo option.
+     * </pre>
+     */
+    public String help() {
+        return join("|", name, alias, aliases) + "\t" + description + ((required) ? " Required." : "");
+    }
+
+    /**
+     * Return string like "--foo|-f|--another-foo-alias".
+     */
+    protected String join(String delim, String name, String alias, String aliases[]) {
+
+        // Option name is mandatory
+        StringBuilder sb = new StringBuilder(name.length());
+        sb.append(name);
+
+        // Alias is optional
+        if (alias != null && alias.length() > 0) {
+            sb.append(delim).append(alias);
+        }
+
+        // Other aliases are optional too
+        if (aliases != null) {
+            for (String s : aliases) {
+                if (s != null && s.length() > 0) {
+                    sb.append(delim).append(s);
+                }
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Return description of options in format suitable for help and usage text.
+     * 
+     * @param header
+     *          header string to print before list of options
+     * @param options
+     *          list of options to print
+     */
+    public static String toHelp(String header, Option[] options) {
+        StringBuffer sb = new StringBuffer();
+        sb.append(header).append(":\n");
+        for (Option option : options) {
+            sb.append("  ").append(option.help()).append('\n');
+        }
+        return sb.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionParser.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionParser.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionParser.java
new file mode 100755
index 0000000..5c45e9e
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionParser.java
@@ -0,0 +1,147 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.opt;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Simple parser of GNU-like options.
+ */
+public class OptionParser {
+
+    public static Option helpOption() {
+        return new Option() {
+            {
+                name = "--help";
+                alias = "-h";
+            }
+        };
+    }
+
+    /**
+     * Parse options, capture values and return rest of arguments.
+     * 
+     * @param args
+     *          command line arguments to parse
+     * @param startFrom
+     *          number of first argument to start parsing from
+     * @param options
+     *          options to fill with values
+     * @return rest of command line after first non-option or "--" separator
+     */
+    public static String[] parseOptions(String args[], int startFrom, Option options[]) {
+        // Convert array of options into map, where key is option name or alias
+        Map<String, Option> optionMap = new HashMap<String, Option>(options.length);
+        for (Option option : options) {
+            optionMap.put(option.name, option);
+
+            if (option.alias != null)
+                optionMap.put(option.alias, option);
+
+            if (option.aliases != null) {
+                for (String alias : option.aliases)
+                    optionMap.put(alias, option);
+            }
+        }
+
+        // Parse arguments
+        int position = startFrom;
+        while (position < args.length) {
+            // Double dash means end of options
+            String optionName = args[position];
+            if (optionName.equals("--")) {
+                position++;
+                break;
+            }
+
+            Option option = optionMap.get(optionName);
+
+            // If option is not found, then this is argument, unless is starts with
+            // dash
+            if (option == null)
+                if (!optionName.startsWith("-"))
+                    break;
+                else
+                    throw new UnknownOptionException("Option \"" + optionName
+                            + "\" is unknown. If this is not an option, then use \"--\" to separate options and arguments. Known options: " + optionMap.keySet().toString());
+
+            position += option.parse(position, args);
+        }
+
+        // Check is required options are used on command line
+        for (Option option : options) {
+            if (option.required && !option.used)
+                throw new OptionRequiredException("Option \"" + option.name + "\" is required.");
+        }
+
+        // Return rest of arguments, which are left after options
+        return (position < args.length) ? Arrays.copyOfRange(args, position, args.length) : new String[] {};
+    }
+
+    /* Example. */
+    public static void main(String args[]) {
+        if (args.length == 0)
+            args = new String[] {"--help", "--foo", "fooval", "--bar", "123", "-v", "--verbose", "-v", "-a", "a1", "-aa", "a2", "-aaa", "a3", "rest", "of",
+                    "arguments"};
+
+        StringOption foo = new StringOption() {
+            {
+                name = "--foo";
+                alias = "-f";
+                value = "fooDefault";
+            }
+        };
+
+        IntOption bar = new IntOption() {
+            {
+                name = "--bar";
+                alias = "-b";
+                value = 123;
+            }
+        };
+
+        IncrementalOption verbose = new IncrementalOption() {
+            {
+                name = "--verbose";
+                alias = "-v";
+            }
+        };
+
+        StringArrayOption array = new StringArrayOption() {
+            {
+                name = "--array";
+                alias = "-a";
+                aliases = new String[] {"-aa", "-aaa"};
+            }
+        };
+
+        String arguments[] = OptionParser.parseOptions(args, 0, new Option[] {helpOption(), foo, bar, verbose, array});
+
+        assertTrue(foo.value.equals("fooval"));
+        assertTrue(bar.value == 123);
+        assertTrue(verbose.value == 3);
+        assertTrue(Arrays.equals(array.value, new String[] {"a1", "a2", "a3"}));
+        assertTrue(Arrays.equals(arguments, new String[] {"rest", "of", "arguments"}));
+    }
+
+    public static void assertTrue(boolean result) {
+        if (!result)
+            throw new AssertionError();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionRequiredException.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionRequiredException.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionRequiredException.java
new file mode 100755
index 0000000..b397627
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionRequiredException.java
@@ -0,0 +1,26 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.opt;
+
+public class OptionRequiredException extends RuntimeException {
+    public OptionRequiredException(String message) {
+        super(message);
+    }
+
+    private static final long serialVersionUID = 1L;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringArrayOption.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringArrayOption.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringArrayOption.java
new file mode 100755
index 0000000..b2f3c30
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringArrayOption.java
@@ -0,0 +1,38 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.opt;
+
+import java.util.Arrays;
+
+public class StringArrayOption extends Option {
+    public String value[] = null;
+
+    @Override
+    public int parse(int position, String[] args) {
+        if (position + 1 >= args.length)
+            throw new NoArgumentForOptionException("Cannot find required argument for option \"" + args[position] + "\".");
+
+        // Append value to end of array of values
+        if (value == null) {
+            value = new String[] {args[position + 1]};
+        } else {
+            value = Arrays.copyOf(value, value.length + 1);
+            value[value.length - 1] = args[position + 1];
+        }
+        return super.parse(position, args) + 1;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringEnumerationOption.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringEnumerationOption.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringEnumerationOption.java
new file mode 100755
index 0000000..f59952e
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringEnumerationOption.java
@@ -0,0 +1,72 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.opt;
+
+public class StringEnumerationOption extends Option {
+    public String value = "";
+    public String choices[] = new String[] {};
+
+    @Override
+    public int parse(int position, String[] args) {
+        if (position + 1 >= args.length)
+            throw new NoArgumentForOptionException("Cannot find required argument for option \"" + args[position] + "\".");
+
+        value = args[position + 1];
+
+        for (String s : choices) {
+            if (value.equals(s))
+                return super.parse(position, args) + 1;
+        }
+
+        throw new NoArgumentForOptionException("Unexpected argument for option \"" + args[position] + "\": \"" + value + "\". Expected argument: "
+                + join("|", choices) + ".");
+    }
+
+    @Override
+    public String help() {
+        StringBuilder help = new StringBuilder();
+        help.append(join("|", name, alias, aliases)).append(" ").append(join("|", choices)).append("\t").append(description);
+        if (required)
+            help.append(" Required.");
+        else if (value != null && value.length() > 0)
+            help.append(" Default value is \"").append(value).append("\".");
+        return help.toString();
+    }
+
+    /**
+     * Join strings in array into one large string.
+     */
+    protected String join(String delim, String values[]) {
+        StringBuilder sb = new StringBuilder();
+        if (values != null) {
+            boolean first = true;
+            for (String s : values) {
+                if (s != null && s.length() > 0) {
+                    if (first)
+                        first = false;
+                    else
+                        sb.append(delim);
+
+                    sb.append(s);
+                }
+            }
+        }
+
+        return sb.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringOption.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringOption.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringOption.java
new file mode 100755
index 0000000..ec9c82c
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringOption.java
@@ -0,0 +1,41 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.opt;
+
+public class StringOption extends Option {
+    public String value = "";
+
+    @Override
+    public int parse(int position, String[] args) {
+        if (position + 1 >= args.length)
+            throw new NoArgumentForOptionException("Cannot find required argument for option \"" + args[position] + "\".");
+
+        value = args[position + 1];
+        return super.parse(position, args) + 1;
+    }
+
+    @Override
+    public String help() {
+        StringBuilder help = new StringBuilder();
+        help.append(join("|", name, alias, aliases)).append(" VALUE\t").append(description);
+        if (required)
+            help.append(" Required.");
+        else if (value != null && value.length() > 0)
+            help.append(" Default value is \"").append(value).append("\".");
+        return help.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/UnknownOptionException.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/UnknownOptionException.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/UnknownOptionException.java
new file mode 100755
index 0000000..58cce73
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/UnknownOptionException.java
@@ -0,0 +1,27 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 common.opt;
+
+public class UnknownOptionException extends RuntimeException {
+
+    public UnknownOptionException(String message) {
+        super(message);
+    }
+
+    private static final long serialVersionUID = 1L;
+
+}


[15/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224ConnectionConfirmPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224ConnectionConfirmPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224ConnectionConfirmPDU.java
deleted file mode 100644
index a335277..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224ConnectionConfirmPDU.java
+++ /dev/null
@@ -1,237 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * Once the External Security Protocol handshake has run to completion, the
- * client MUST continue with the connection sequence by sending the MCS Connect
- * Initial PDU to the server over the newly established secure channel.
- * 
- * 
- * @see http://msdn.microsoft.com/en-us/library/cc240663.aspx
- */
-public class ServerX224ConnectionConfirmPDU extends OneTimeSwitch {
-
-  public static final int X224_TPDU_CONNECTION_REQUEST = 0xe0;
-  public static final int X224_TPDU_CONNECTION_CONFIRM = 0xd0;
-  public static final int X224_TPDU_DISCONNECTION_REQUEST = 0x80;
-  public static final int X224_TPDU_DISCONNECTION_CONFIRM = 0xc0;
-  public static final int X224_TPDU_EXPEDITED_DATA = 0x10;
-  public static final int X224_TPDU_DATA_ACKNOWLEDGE = 0x61;
-  public static final int X224_TPDU_EXPEDITET_ACKNOWLEDGE = 0x40;
-  public static final int X224_TPDU_REJECT = 0x51;
-  public static final int X224_TPDU_ERROR = 0x70;
-  public static final int X224_TPDU_PROTOCOL_IDENTIFIER = 0x01;
-
-  /**
-   * The server requires that the client support Enhanced RDP Security with
-   * either TLS 1.0, 1.1 or 1.2 or CredSSP. If only CredSSP was requested then
-   * the server only supports TLS.
-   */
-  public static final int SSL_REQUIRED_BY_SERVER = 0x00000001;
-
-  /**
-   * The server is configured to only use Standard RDP Security mechanisms and
-   * does not support any External Security Protocols.
-   */
-  public static final int SSL_NOT_ALLOWED_BY_SERVER = 0x00000002;
-
-  /**
-   * The server does not possess a valid authentication certificate and cannot
-   * initialize the External Security Protocol Provider.
-   */
-  public static final int SSL_CERT_NOT_ON_SERVER = 0x00000003;
-
-  /**
-   * The list of requested security protocols is not consistent with the current
-   * security protocol in effect. This error is only possible when the Direct
-   * Approach is used and an External Security Protocolis already being used.
-   */
-  public static final int INCONSISTENT_FLAGS = 0x00000004;
-
-  /**
-   * The server requires that the client support Enhanced RDP Security with
-   * CredSSP.
-   */
-  public static final int HYBRID_REQUIRED_BY_SERVER = 0x00000005;
-
-  /**
-   * The server requires that the client support Enhanced RDP Security with TLS
-   * 1.0, 1.1 or 1.2 and certificate-based client authentication.
-   */
-  public static final int SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER = 0x00000006;
-
-  public ServerX224ConnectionConfirmPDU(String id) {
-    super(id);
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    int x224Length = buf.readVariableSignedIntLE();
-
-    int x224Type = buf.readUnsignedByte();
-    if (x224Type != X224_TPDU_CONNECTION_CONFIRM)
-      throw new RuntimeException("Unexpected type of packet. Expected type: " + X224_TPDU_CONNECTION_CONFIRM + " (CONNECTION CONFIRM), actual type: "
-          + x224Type + ", length: " + x224Length + ", buf: " + buf + ".");
-
-    // Ignore destination reference, because client side has only one node
-    buf.skipBytes(2);
-
-    // Source reference
-    // int srcRef = buf.readUnsignedShort();
-    buf.skipBytes(2);
-
-    // Ignore class and options
-    buf.skipBytes(1);
-
-    // RDP_NEG_RSP::type (TYPE_RDP_NEG_RSP)
-    int negType = buf.readUnsignedByte();
-
-    // RDP_NEG_RSP::flags (0)
-    buf.skipBytes(1); // Ignore: always 0
-
-    // RDP_NEG_RSP::length (always 8 bytes)
-    int length = buf.readUnsignedShortLE();
-
-    if (length != 8)
-      throw new RuntimeException("Unexpected length of buffer. Expected value: 8, actual value: " + length + ", RDP NEG buf: " + buf + ".");
-
-    // RDP_NEG_RSP: Selected protocols (PROTOCOL_SSL)
-    int protocol = buf.readSignedIntLE();
-
-    if (negType != RdpConstants.RDP_NEG_REQ_TYPE_NEG_RSP) {
-      // Parse error code, see
-      // http://msdn.microsoft.com/en-us/library/cc240507.aspx
-      int errorCode = protocol;
-      String message = "Unknown error.";
-      switch (errorCode) {
-      case SSL_REQUIRED_BY_SERVER:
-        message = "The server requires that the client support Enhanced RDP Security with either TLS 1.0, 1.1 or 1.2 or CredSSP. If only CredSSP was requested then the server only supports TLS.";
-        break;
-
-      case SSL_NOT_ALLOWED_BY_SERVER:
-        message = "The server is configured to only use Standard RDP Security mechanisms and does not support any External Security Protocols.";
-        break;
-
-      case SSL_CERT_NOT_ON_SERVER:
-        message = "The server does not possess a valid authentication certificate and cannot initialize the External Security Protocol Provider.";
-        break;
-
-      case INCONSISTENT_FLAGS:
-        message = "The list of requested security protocols is not consistent with the current security protocol in effect. This error is only possible when the Direct Approach is used and an External Security Protocolis already being used.";
-        break;
-
-      case HYBRID_REQUIRED_BY_SERVER:
-        message = "The server requires that the client support Enhanced RDP Security with CredSSP.";
-        break;
-
-      case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
-        message = "The server requires that the client support Enhanced RDP Security  with TLS 1.0, 1.1 or 1.2 and certificate-based client authentication.";
-        break;
-
-      }
-      throw new RuntimeException("Connection failure: " + message );
-    }
-
-
-    
-    if (protocol != RdpConstants.RDP_NEG_REQ_PROTOCOL_SSL)
-      throw new RuntimeException("Unexpected protocol type. Expected protocol type: " + RdpConstants.RDP_NEG_REQ_PROTOCOL_SSL
-          + " (SSL), actual response type: " + protocol + ", RDP NEG buf: " + buf + ".");
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: RDP Negotiation response. Type: " + negType + ", protocol: " + protocol + ".");
-
-    // Next: upgrade socket to SSL, send ConnectInitial packet
-    switchOff();
-  }
-
-  /**
-   * Example.
-   * 
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-//    byte[] packet = new byte[] { 
-//    
-//        0x03, // -> TPKT Header: TPKT version = 3
-//        0x00, // TPKT Header: Reserved = 0
-//        0x00, 0x13, // TPKT Header: Packet length - (total = 19 bytes)
-//        0x0e, // X.224: Length indicator (14 bytes)
-//        (byte) 0xd0, // X.224: Type (high nibble) = 0xd = CC TPDU; credit
-//                     // (low nibble) = 0
-//        0x00, 0x00, // X.224: Destination reference = 0
-//        0x12, 0x34, // X.224: Source reference = 0x1234 (bogus value)
-//        0x00, // X.224: Class and options = 0
-//
-//        0x02, // RDP_NEG_RSP::type (TYPE_RDP_NEG_RSP)
-//        0x00, // RDP_NEG_RSP::flags (0)
-//        0x08, 0x00, // RDP_NEG_RSP::length (8 bytes)
-//        0x01, 0x00, 0x00, 0x00 // RDP_NEG_RSP: Selected protocols (PROTOCOL_SSL)
-//    };
-
-    // Connection failure
-    // 03 00 00 13 0e d0 00 00 12 34 00 03 00 08 00 05 00 00 00
-    byte[] packet = new byte[] {
-        
-        0x03, // -> TPKT Header: TPKT version = 3
-        0x00, // TPKT Header: Reserved = 0
-        0x00, 0x13, // TPKT Header: Packet length - (total = 19 bytes)
-        0x0e, // X.224: Length indicator (14 bytes)
-        (byte) 0xd0, // X.224: Type (high nibble) = 0xd = CC TPDU; credit
-                     // (low nibble) = 0
-        0x00, 0x00, // X.224: Destination reference = 0
-        0x12, 0x34, // X.224: Source reference = 0x1234 (bogus value)
-        0x00, // X.224: Class and options = 0
-        (byte) 0x03, // Failure 
-        (byte) 0x00, // RDP_NEG_RSP::flags (0)
-        (byte) 0x08, (byte) 0x00, // RDP_NEG_RSP::length (8 bytes) 
-        (byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Code:  HYBRID_REQUIRED_BY_SERVER
-        
-    };
-
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
-    Element cc = new ServerX224ConnectionConfirmPDU("cc");
-    Element tpkt = new ServerTpkt("tpkt");
-    Element sink = new MockSink("sink", new ByteBuffer[] {});
-    Element mainSink = new MockSink("mainSink", new ByteBuffer[] {});
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, tpkt, cc, sink, mainSink);
-    pipeline.link("source", "tpkt", "cc", "mainSink");
-    pipeline.link("cc >" + OTOUT, "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224DataPdu.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224DataPdu.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224DataPdu.java
deleted file mode 100644
index 1548904..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224DataPdu.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-public class ServerX224DataPdu extends BaseElement {
-
-  public static final int X224_TPDU_LAST_DATA_UNIT = 0x80;
-  public static final int X224_TPDU_DATA = 0xF0;
-
-  public ServerX224DataPdu(String id) {
-    super(id);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    int headerLength = buf.readVariableSignedIntLE();
-
-    if (headerLength != 2)
-      throw new RuntimeException("Unexpected X224 Data PDU header length. Expected header length: 2 , actual header length: " + headerLength + ".");
-
-    // Read X224 type and options
-    int type = buf.readUnsignedByte(); // High nibble: type, low nibble:
-
-    if ((type & 0xf0) != X224_TPDU_DATA)
-      throw new RuntimeException("[" + this + "] ERROR: Unexepcted X224 packet type. Expected packet type: " + X224_TPDU_DATA
-          + " (X224_TPDU_DATA), actual packet type: " + type + ", buf: " + buf + ".");
-
-    int options = buf.readUnsignedByte();
-
-    if ((options & X224_TPDU_LAST_DATA_UNIT) != X224_TPDU_LAST_DATA_UNIT)
-      throw new RuntimeException("Unexepcted X224 packet options. Expected options: " + X224_TPDU_LAST_DATA_UNIT
-          + " (X224_TPDU_LAST_DATA_UNIT), actual packet options: " + options + ", buf: " + buf + ".");
-
-    ByteBuffer payload = buf.readBytes(buf.length - buf.cursor);
-
-    buf.unref();
-
-    pushDataToAllOuts(payload);
-  }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/TrustAllX509TrustManager.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/TrustAllX509TrustManager.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/TrustAllX509TrustManager.java
deleted file mode 100644
index aaf93b0..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/TrustAllX509TrustManager.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import java.security.cert.X509Certificate;
-
-import javax.net.ssl.X509TrustManager;
-
-public class TrustAllX509TrustManager implements X509TrustManager {
-  @Override
-  public void checkClientTrusted(final X509Certificate[] chain, final String authType) {
-    // TODO: ask user to confirm self-signed certificates
-  }
-
-  @Override
-  public void checkServerTrusted(final X509Certificate[] chain, final String authType) {
-    // TODO: ask user to confirm self-signed certificates
-  }
-
-  @Override
-  public X509Certificate[] getAcceptedIssuers() {
-    // TODO: use system CA certificates here
-    return null;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/UpgradeSocketToSSL.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/UpgradeSocketToSSL.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/UpgradeSocketToSSL.java
deleted file mode 100644
index d4c08f1..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/UpgradeSocketToSSL.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Direction;
-import streamer.Event;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-public class UpgradeSocketToSSL extends OneTimeSwitch {
-
-  public UpgradeSocketToSSL(String id) {
-    super(id);
-  }
-
-  @Override
-  protected void onStart() {
-
-    sendEventToAllPads(Event.SOCKET_UPGRADE_TO_SSL, Direction.IN);
-    switchOff();
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    throw new RuntimeException("Unexpected data: " + buf + ".");
-
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java
new file mode 100755
index 0000000..36da0a3
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java
@@ -0,0 +1,351 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.adapter;
+
+import java.awt.event.KeyEvent;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+import common.KeyOrder;
+
+public class AwtRdpKeyboardAdapter extends BaseElement {
+
+    /**
+     * Absence of this flag indicates a key-down event, while its presence
+     * indicates a key-release event.
+     */
+    public static final int FASTPATH_INPUT_KBDFLAGS_RELEASE = 0x01;
+
+    /**
+     * Keystroke message contains an extended scancode. For enhanced 101-key and
+     * 102-key keyboards, extended keys include the right ALT and right CTRL keys
+     * on the main section of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE
+     * DOWN and ARROW keys in the clusters to the left of the numeric keypad; and
+     * the Divide ("/") and ENTER keys in the numeric keypad.
+     */
+    public static final int FASTPATH_INPUT_KBDFLAGS_EXTENDED = 0x02;
+
+    public static final int FASTPATH_INPUT_EVENT_SCANCODE = 0;
+
+    public AwtRdpKeyboardAdapter(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        KeyOrder order = (KeyOrder)buf.getOrder();
+        buf.unref();
+
+        ByteBuffer outBuf = new ByteBuffer(2, true);
+
+        int scanCode = map_en_us(order.event);
+
+        // eventHeader (1 byte): An 8-bit, unsigned integer. The format of this
+        // field is the same as the eventHeader byte field described in section
+        // 2.2.8.1.2.2. The eventCode bitfield (3 bits in size) MUST be set to
+        // FASTPATH_INPUT_EVENT_SCANCODE (0). The eventFlags bitfield (5 bits in
+        // size) contains flags describing the keyboard event.
+        outBuf.writeByte((scanCode >> 8) | (FASTPATH_INPUT_EVENT_SCANCODE << 5) | ((order.pressed) ? 0 : FASTPATH_INPUT_KBDFLAGS_RELEASE));
+
+        // keyCode (1 byte): An 8-bit, unsigned integer. The scancode of the key
+        // which triggered the event.
+        outBuf.writeByte(scanCode);
+
+        // Push buffer to one pad only, so it can be modified without copying of
+        // data
+        pushDataToPad(STDOUT, outBuf);
+    }
+
+    /**
+     * Return key scan code (in lower byte) and extended flags (in second byte).
+     */
+    private int map_en_us(KeyEvent event) {
+        // Also set extended key flag when necessary.
+        // For enhanced 101-key and 102-key keyboards, extended keys include the
+        // right ALT and right CTRL keys on the main section of the keyboard; the
+        // INS, DEL, HOME, END, PAGE UP, PAGE DOWN and ARROW keys in the clusters to
+        // the left of the numeric keypad; and the Divide ("/") and ENTER keys in
+        // the numeric keypad.
+
+        switch (event.getKeyCode()) {
+        // Functional keys
+        case KeyEvent.VK_ESCAPE:
+            return 1;
+        case KeyEvent.VK_F1:
+            return 59;
+        case KeyEvent.VK_F2:
+            return 60;
+        case KeyEvent.VK_F3:
+            return 61;
+        case KeyEvent.VK_F4:
+            return 62;
+        case KeyEvent.VK_F5:
+            return 63;
+        case KeyEvent.VK_F6:
+            return 64;
+        case KeyEvent.VK_F7:
+            return 65;
+        case KeyEvent.VK_F8:
+            return 66;
+        case KeyEvent.VK_F9:
+            return 67;
+        case KeyEvent.VK_F10:
+            return 68;
+        case KeyEvent.VK_F11:
+            return 87;
+        case KeyEvent.VK_F12:
+            return 88;
+
+            // Row #1
+        case KeyEvent.VK_BACK_QUOTE:
+            return 41;
+        case KeyEvent.VK_1:
+            return 2;
+        case KeyEvent.VK_2:
+            return 3;
+        case KeyEvent.VK_3:
+            return 4;
+        case KeyEvent.VK_4:
+            return 5;
+        case KeyEvent.VK_5:
+            return 6;
+        case KeyEvent.VK_6:
+            return 7;
+        case KeyEvent.VK_7:
+            return 8;
+        case KeyEvent.VK_8:
+            return 9;
+        case KeyEvent.VK_9:
+            return 10;
+        case KeyEvent.VK_0:
+            return 11;
+        case KeyEvent.VK_MINUS:
+            return 12;
+        case KeyEvent.VK_EQUALS:
+            return 13;
+        case KeyEvent.VK_BACK_SPACE:
+            return 14;
+
+            // Row #2
+        case KeyEvent.VK_TAB:
+            return 15;
+        case KeyEvent.VK_Q:
+            return 16;
+        case KeyEvent.VK_W:
+            return 17;
+        case KeyEvent.VK_E:
+            return 18;
+        case KeyEvent.VK_R:
+            return 19;
+        case KeyEvent.VK_T:
+            return 20;
+        case KeyEvent.VK_Y:
+            return 21;
+        case KeyEvent.VK_U:
+            return 22;
+        case KeyEvent.VK_I:
+            return 23;
+        case KeyEvent.VK_O:
+            return 24;
+        case KeyEvent.VK_P:
+            return 25;
+        case KeyEvent.VK_OPEN_BRACKET:
+            return 26;
+        case KeyEvent.VK_CLOSE_BRACKET:
+            return 27;
+        case KeyEvent.VK_ENTER:
+            switch (event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_STANDARD:
+                return 28;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 28;
+            }
+
+            // Row #3
+        case KeyEvent.VK_CAPS_LOCK:
+            return 58;
+        case KeyEvent.VK_A:
+            return 30;
+        case KeyEvent.VK_S:
+            return 31;
+        case KeyEvent.VK_D:
+            return 32;
+        case KeyEvent.VK_F:
+            return 33;
+        case KeyEvent.VK_G:
+            return 34;
+        case KeyEvent.VK_H:
+            return 35;
+        case KeyEvent.VK_J:
+            return 36;
+        case KeyEvent.VK_K:
+            return 37;
+        case KeyEvent.VK_L:
+            return 38;
+        case KeyEvent.VK_SEMICOLON:
+            return 39;
+        case KeyEvent.VK_QUOTE:
+            return 40;
+
+            // Row #4
+        case KeyEvent.VK_SHIFT:
+            switch (event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 42;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 54;
+            }
+        case KeyEvent.VK_BACK_SLASH:
+            return 43;
+        case KeyEvent.VK_Z:
+            return 44;
+        case KeyEvent.VK_X:
+            return 45;
+        case KeyEvent.VK_C:
+            return 46;
+        case KeyEvent.VK_V:
+            return 47;
+        case KeyEvent.VK_B:
+            return 48;
+        case KeyEvent.VK_N:
+            return 49;
+        case KeyEvent.VK_M:
+            return 50;
+        case KeyEvent.VK_COMMA:
+            return 51;
+        case KeyEvent.VK_PERIOD:
+            return 52;
+        case KeyEvent.VK_SLASH:
+            return 53;
+
+            //
+            // Bottom row
+        case KeyEvent.VK_CONTROL:
+            switch (event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 29;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 29;
+            }
+        case KeyEvent.VK_WINDOWS:
+            switch (event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 91;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 92;
+            }
+        case KeyEvent.VK_ALT:
+            switch (event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 56;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 56;
+            }
+        case KeyEvent.VK_ALT_GRAPH:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 56;
+
+        case KeyEvent.VK_SPACE:
+            return 57;
+
+        case KeyEvent.VK_CONTEXT_MENU:
+            return 93;
+
+            //
+            // Special keys
+        case KeyEvent.VK_PRINTSCREEN:
+            return 55;
+        case KeyEvent.VK_SCROLL_LOCK:
+            return 70;
+        case KeyEvent.VK_PAUSE:
+            return 29;
+
+            // Text navigation keys
+        case KeyEvent.VK_INSERT:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 82;
+        case KeyEvent.VK_HOME:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 71;
+        case KeyEvent.VK_PAGE_UP:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 73;
+        case KeyEvent.VK_DELETE:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 83;
+        case KeyEvent.VK_END:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 79;
+        case KeyEvent.VK_PAGE_DOWN:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 81;
+
+            // Cursor keys
+        case KeyEvent.VK_UP:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 72;
+        case KeyEvent.VK_LEFT:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 75;
+        case KeyEvent.VK_DOWN:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 80;
+        case KeyEvent.VK_RIGHT:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 77;
+
+            // Keypad
+        case KeyEvent.VK_NUM_LOCK:
+            return 69;
+        case KeyEvent.VK_DIVIDE:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 53;
+        case KeyEvent.VK_MULTIPLY:
+            return 55;
+        case KeyEvent.VK_SUBTRACT:
+            return 74;
+        case KeyEvent.VK_ADD:
+            return 78;
+
+        case KeyEvent.VK_NUMPAD7:
+            return 71;
+        case KeyEvent.VK_NUMPAD8:
+            return 72;
+        case KeyEvent.VK_NUMPAD9:
+            return 73;
+        case KeyEvent.VK_NUMPAD4:
+            return 75;
+        case KeyEvent.VK_NUMPAD5:
+            return 76;
+        case KeyEvent.VK_NUMPAD6:
+            return 77;
+        case KeyEvent.VK_NUMPAD1:
+            return 79;
+        case KeyEvent.VK_NUMPAD2:
+            return 80;
+        case KeyEvent.VK_NUMPAD3:
+            return 81;
+        case KeyEvent.VK_NUMPAD0:
+            return 82;
+        case KeyEvent.VK_DECIMAL:
+            return 83;
+
+        default:
+            System.err.println("Key is not mapped: " + event + ".");
+            return 57; // Space
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpMouseAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpMouseAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpMouseAdapter.java
new file mode 100755
index 0000000..9e2ad99
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpMouseAdapter.java
@@ -0,0 +1,180 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.adapter;
+
+import java.awt.event.MouseEvent;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+import common.MouseOrder;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240594.aspx
+ */
+public class AwtRdpMouseAdapter extends BaseElement {
+    public static int FASTPATH_INPUT_EVENT_MOUSE = 0x01;
+
+    /**
+     * Event is a mouse wheel rotation. The only valid flags in a wheel rotation
+     * event are PTRFLAGS_WHEEL_NEGATIVE and the WheelRotationMask; all other
+     * pointer flags are ignored.
+     */
+    public static int PTRFLAGS_WHEEL = 0x0200;
+
+    /**
+     * Wheel rotation value (contained in the WheelRotationMask bit field) is
+     * negative and MUST be sign-extended before injection at the server.
+     */
+    public static int PTRFLAGS_WHEEL_NEGATIVE = 0x0100;
+
+    /**
+     * Bit field describing the number of rotation units the mouse wheel was
+     * rotated. The value is negative if the PTRFLAGS_WHEEL_NEGATIVE flag is set.
+     */
+    public static int WHEEL_ROTATION_MASK = 0x01FF;
+
+    /**
+     * Indicates that the mouse position MUST be updated to the location specified
+     * by the xPos and yPos fields.
+     */
+    public static int PTRFLAGS_MOVE = 0x0800;
+
+    /**
+     * Indicates that a click event has occurred at the position specified by the
+     * xPos and yPos fields. The button flags indicate which button has been
+     * clicked and at least one of these flags MUST be set.
+     */
+    public static int PTRFLAGS_DOWN = 0x8000;
+
+    /**
+     * Mouse button 1 (left button) was clicked or released. If the PTRFLAGS_DOWN
+     * flag is set, then the button was clicked, otherwise it was released.
+     */
+    public static int PTRFLAGS_BUTTON1 = 0x1000;
+
+    /**
+     * Mouse button 2 (right button) was clicked or released. If the PTRFLAGS_DOWN
+     * flag is set, then the button was clicked, otherwise it was released.
+     */
+    public static int PTRFLAGS_BUTTON2 = 0x2000;
+
+    /**
+     * Mouse button 3 (middle button or wheel) was clicked or released. If the
+     * PTRFLAGS_DOWN flag is set, then the button was clicked, otherwise it was
+     * released.
+     */
+    public static int PTRFLAGS_BUTTON3 = 0x4000;
+
+    public AwtRdpMouseAdapter(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Get mouse event
+        MouseOrder order = (MouseOrder)buf.getOrder();
+
+        ByteBuffer outBuf = new ByteBuffer(7, true);
+
+        // eventHeader (1 byte): An 8-bit, unsigned integer. EventCode bitfield (top
+        // 3 bits) MUST be set to FASTPATH_INPUT_EVENT_MOUSE (1). The
+        // eventFlags bitfield (low 5 bits) MUST be zeroed out.
+        outBuf.writeByte(FASTPATH_INPUT_EVENT_MOUSE << 5);
+
+        // pointerFlags (2 bytes): A 16-bit, unsigned integer.
+        outBuf.writeShortLE(getPointerFlags(order));
+
+        // xPos (2 bytes): A 16-bit, unsigned integer. The x-coordinate of the
+        // pointer.
+        outBuf.writeShortLE(order.event.getX());
+
+        // yPos (2 bytes): A 16-bit, unsigned integer. The y-coordinate of the
+        // pointer.
+        outBuf.writeShortLE(order.event.getY());
+
+        // Push buffer to one pad only, so it can be modified without copying of
+        // data
+        pushDataToPad(STDOUT, outBuf);
+    }
+
+    // Remember mouse buttons
+    protected boolean button1, button2, button3;
+
+    protected int getPointerFlags(MouseOrder order) {
+        int flags = 0;
+
+        int modifiers = order.event.getModifiersEx();
+
+        if (order.pressed) {
+            // Mouse pressed
+            flags |= PTRFLAGS_DOWN;
+
+            // Check, which one of buttons is released
+            boolean b1 = ((modifiers & MouseEvent.BUTTON1_DOWN_MASK) > 0) && !button1;
+            boolean b2 = ((modifiers & MouseEvent.BUTTON2_DOWN_MASK) > 0) && !button2;
+            boolean b3 = ((modifiers & MouseEvent.BUTTON3_DOWN_MASK) > 0) && !button3;
+
+            if (b1) {
+                flags |= PTRFLAGS_BUTTON1;
+                button1 = true;
+            }
+
+            if (b2) {
+                flags |= PTRFLAGS_BUTTON3;
+                button2 = true;
+            }
+
+            if (b3) {
+                flags |= PTRFLAGS_BUTTON2;
+                button3 = true;
+            }
+        } else if (order.released) {
+            // Mouse released
+
+            // Check, which one of buttons is released
+            boolean b1 = !((modifiers & MouseEvent.BUTTON1_DOWN_MASK) > 0) && button1;
+            boolean b2 = !((modifiers & MouseEvent.BUTTON2_DOWN_MASK) > 0) && button2;
+            boolean b3 = !((modifiers & MouseEvent.BUTTON3_DOWN_MASK) > 0) && button3;
+
+            if (b1) {
+                flags |= PTRFLAGS_BUTTON1;
+                button1 = false;
+            }
+
+            if (b2) {
+                flags |= PTRFLAGS_BUTTON3;
+                button2 = false;
+            }
+
+            if (b3) {
+                flags |= PTRFLAGS_BUTTON2;
+                button3 = false;
+            }
+        } else {
+            // Mouse moved
+            flags |= PTRFLAGS_MOVE;
+        }
+
+        return flags;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardDataFormat.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardDataFormat.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardDataFormat.java
new file mode 100755
index 0000000..83ecfe5
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardDataFormat.java
@@ -0,0 +1,143 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.clip;
+
+import java.util.Map;
+
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+
+public class ClipboardDataFormat {
+
+    public static final String HTML_FORMAT = "HTML Format";
+    public static final String RTF_AS_TEXT = "RTF As Text";
+    public static final String RICH_TEXT_FORMAT_WITHOUT_OBJECTS = "Rich Text Format Without Objects";
+    public static final String RICH_TEXT_FORMAT = "Rich Text Format";
+
+    public static final int CB_FORMAT_TEXT = 0x0001;
+    public static final int CB_FORMAT_UNICODETEXT = 0x000D;
+
+    /**
+     * Supported clipboard data formats in order of preference.
+     */
+    public static final Object[] supportedTextBasedFormats = new Object[] {
+            // ID's
+            CB_FORMAT_UNICODETEXT, CB_FORMAT_TEXT,
+
+            // Names
+            HTML_FORMAT,
+
+            // RTF_AS_TEXT,
+            // RICH_TEXT_FORMAT_WITHOUT_OBJECTS,
+            // RICH_TEXT_FORMAT,
+
+    };
+
+    public final int id;
+    public final String name;
+
+    public ClipboardDataFormat(int id, String name) {
+        super();
+        this.id = id;
+        this.name = name;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + id;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ClipboardDataFormat other = (ClipboardDataFormat)obj;
+        if (id != other.id)
+            return false;
+        if (name == null) {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "ClipboardDataFormat [id=" + id + ", name=\"" + name + "\"" + ((id == CB_FORMAT_UNICODETEXT) ? " (Unicode text)" : "")
+                + ((id == CB_FORMAT_TEXT) ? " (text)" : "") + "]";
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Parse response of supported format and return it as string.
+     */
+    public String parseServerResponseAsString(ByteBuffer buf) {
+        switch (id) {
+        case CB_FORMAT_UNICODETEXT:
+            return buf.readVariableWideString(RdpConstants.CHARSET_16);
+        case CB_FORMAT_TEXT:
+            return buf.readVariableString(RdpConstants.CHARSET_8);
+        }
+
+        if (name == null || name.length() == 0)
+            return null;
+
+        if (HTML_FORMAT.equals(name))
+            return buf.readVariableString(RdpConstants.CHARSET_8); // TODO: verify
+
+        // if (RTF_AS_TEXT.equals(name))
+        // return buf.readVariableString(RdpConstants.CHARSET_8); // TODO: verify
+        //
+        // if (RICH_TEXT_FORMAT_WITHOUT_OBJECTS.equals(name))
+        // return buf.readVariableString(RdpConstants.CHARSET_8); // TODO: verify
+        //
+        // if (RICH_TEXT_FORMAT.equals(name))
+        // return buf.readVariableString(RdpConstants.CHARSET_8); // TODO: verify
+
+        return null;
+    }
+
+    /**
+     * Find first (richest) text-based data format.
+     * 
+     * @return text-based data format or null, when not found
+     */
+    public static ClipboardDataFormat findBestTextFormat(Map<Object, ClipboardDataFormat> serverClipboardDataFormats) {
+        for (Object formatKey : ClipboardDataFormat.supportedTextBasedFormats)
+            if (serverClipboardDataFormats.containsKey(formatKey))
+                return serverClipboardDataFormats.get(formatKey);
+
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardState.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardState.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardState.java
new file mode 100755
index 0000000..9c465b5
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardState.java
@@ -0,0 +1,70 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.clip;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ClipboardState {
+
+    /**
+     * The Long Format Name variant of the Format List PDU is supported for
+     * exchanging updated format names. If this flag is not set, the Short Format
+     * Name variant MUST be used. If this flag is set by both protocol endpoints,
+     * then the Long Format Name variant MUST be used.
+     */
+    public boolean serverUseLongFormatNames = false;
+    public final boolean clientUseLongFormatNames = false;
+
+    /**
+     * File copy and paste using stream-based operations are supported using the
+     * File Contents Request PDU and File Contents Response PDU.
+     */
+    public boolean serverStreamFileClipEnabled = false;
+    public final boolean clientStreamFileClipEnabled = false;
+
+    /**
+     * Indicates that any description of files to copy and paste MUST NOT include
+     * the source path of the files.
+     */
+    public boolean serverFileClipNoFilePaths = false;
+    public final boolean clientFileClipNoFilePaths = false;
+
+    /**
+     * Locking and unlocking of File Stream data on the clipboard is supported
+     * using the Lock Clipboard Data PDU and Unlock Clipboard Data PDU.
+     */
+    public boolean serverCanLockClipdata = false;
+    public final boolean clientCanLockClipdata = false;
+
+    /**
+     * The Monitor Ready PDU is sent from the server to the client to indicate
+     * that the server is initialized and ready.
+     */
+    public boolean serverReady = false;
+
+    /**
+     * Set of data formats, which are supported by server for paste operation.
+     */
+    public Map<Object, ClipboardDataFormat> serverClipboardDataFormats = new HashMap<Object, ClipboardDataFormat>(0);
+
+    /**
+     * Server sends clipboard data in requested format.
+     */
+    public ClipboardDataFormat serverRequestedFormat;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipRdrChannelRouter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipRdrChannelRouter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipRdrChannelRouter.java
new file mode 100755
index 0000000..3238124
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipRdrChannelRouter.java
@@ -0,0 +1,193 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.clip;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class ServerClipRdrChannelRouter extends BaseElement {
+
+    /**
+     * Key for ASCII names message flag in payload metadata.  Value is Boolean.
+     */
+    public static final String ASCII_NAMES = "ascii_names";
+
+    /**
+     * Key for success/fail message flag in payload metadata. Value is Boolean.
+     */
+    public static final String SUCCESS = "success";
+
+    /**
+     * Monitor Ready PDU
+     */
+    public static final int CB_MONITOR_READY = 0x0001;
+
+    /**
+     * Format List PDU
+     */
+    public static final int CB_FORMAT_LIST = 0x0002;
+
+    /**
+     * Format List Response PDU
+     */
+    public static final int CB_FORMAT_LIST_RESPONSE = 0x0003;
+
+    /**
+     * Format Data Request PDU
+     */
+    public static final int CB_FORMAT_DATA_REQUEST = 0x0004;
+
+    /**
+     * Format Data Response PDU
+     */
+    public static final int CB_FORMAT_DATA_RESPONSE = 0x0005;
+
+    /**
+     * Temporary Directory PDU
+     */
+    public static final int CB_TEMP_DIRECTORY = 0x0006;
+
+    /**
+     * Clipboard Capabilities PDU
+     */
+    public static final int CB_CLIP_CAPS = 0x0007;
+
+    /**
+     * File Contents Request PDU
+     */
+    public static final int CB_FILECONTENTS_REQUEST = 0x0008;
+
+    /**
+     * File Contents Response PDU
+     */
+    public static final int CB_FILECONTENTS_RESPONSE = 0x0009;
+
+    /**
+     * Lock Clipboard Data PDU
+     */
+    public static final int CB_LOCK_CLIPDATA = 0x000A;
+
+    /**
+     * Unlock Clipboard Data PDU
+     */
+    public static final int CB_UNLOCK_CLIPDATA = 0x000B;
+
+    /**
+     * Used by the Format List Response PDU, Format Data Response PDU, and File
+     * Contents Response PDU to indicate that the associated request Format List
+     * PDU, Format Data Request PDU, and File Contents Request PDU were processed
+     * successfully.
+     */
+    public static final int CB_RESPONSE_OK = 0x0001;
+
+    /**
+     * Used by the Format List Response PDU, Format Data Response PDU, and File
+     * Contents Response PDU to indicate that the associated Format List PDU,
+     * Format Data Request PDU, and File Contents Request PDU were not processed
+     * successfully.
+     */
+    public static final int CB_RESPONSE_FAIL = 0x0002;
+
+    /**
+     * Used by the Short Format Name variant of the Format List Response PDU to
+     * indicate the format names are in ASCII 8.
+     */
+    public static final int CB_ASCII_NAMES = 0x0004;
+
+    public ServerClipRdrChannelRouter(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Parse PDU header
+        // Example: 07 00 -> CLIPRDR_HEADER::msgType = CB_CLIP_CAPS (7)
+        int msgType = buf.readUnsignedShortLE();
+
+        // Example: 00 00 -> CLIPRDR_HEADER::msgFlags = 0
+        int msgFlags = buf.readUnsignedShortLE();
+
+        // Example: 10 00 00 00 -> CLIPRDR_HEADER::dataLen = 0x10 = 16 bytes
+        long dataLenLong = buf.readSignedIntLE();
+        if (dataLenLong > 4 * 1024 * 1024)
+            throw new RuntimeException("Clipboard packet is too long. Expected length: less than 4MiB. Actual length: " + dataLenLong + ".");
+        int dataLen = (int)dataLenLong;
+
+        ByteBuffer payload = buf.readBytes(dataLen);
+
+        // Parse message flags and store them in the payload metadata
+        if ((msgFlags & CB_RESPONSE_OK) == CB_RESPONSE_OK)
+            payload.putMetadata("success", true);
+        if ((msgFlags & CB_RESPONSE_FAIL) == CB_RESPONSE_FAIL)
+            payload.putMetadata(SUCCESS, false);
+        if ((msgFlags & CB_ASCII_NAMES) == CB_ASCII_NAMES)
+            payload.putMetadata(ASCII_NAMES, true);
+
+        // Push PDU to appropriate handler
+        switch (msgType) {
+        case CB_MONITOR_READY:
+            pushDataToPad("monitor_ready", payload);
+            break;
+        case CB_FORMAT_LIST:
+            pushDataToPad("format_list", payload);
+            break;
+        case CB_FORMAT_LIST_RESPONSE:
+            pushDataToPad("format_list_response", payload);
+            break;
+        case CB_FORMAT_DATA_REQUEST:
+            pushDataToPad("format_data_request", payload);
+            break;
+        case CB_FORMAT_DATA_RESPONSE:
+            pushDataToPad("format_data_response", payload);
+            break;
+        case CB_TEMP_DIRECTORY:
+            throw new RuntimeException("[" + this + "] ERROR: Unexpected clipboard temporary directory PDU received from server. Data: " + buf + ".");
+        case CB_CLIP_CAPS:
+            pushDataToPad("clipboard_capabilities", payload);
+            break;
+        case CB_FILECONTENTS_REQUEST:
+            pushDataToPad("filecontent_request", payload);
+            break;
+        case CB_FILECONTENTS_RESPONSE:
+            pushDataToPad("filecontent_response", payload);
+            break;
+        case CB_LOCK_CLIPDATA:
+            pushDataToPad("lock_clipdata", payload);
+            break;
+        case CB_UNLOCK_CLIPDATA:
+            pushDataToPad("unlock_clipdata", payload);
+            break;
+        default:
+            throw new RuntimeException("[" + this + "] ERROR: Unknown clipboard PDU message type: " + msgType + ".");
+        }
+
+        buf.unref();
+
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // TODO
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipboardCapabilitiesPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipboardCapabilitiesPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipboardCapabilitiesPDU.java
new file mode 100755
index 0000000..ab2d99a
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipboardCapabilitiesPDU.java
@@ -0,0 +1,180 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.clip;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class ServerClipboardCapabilitiesPDU extends BaseElement {
+
+    /**
+     * General capability set.
+     */
+    public static final int CB_CAPSTYPE_GENERAL = 0x1;
+
+    /**
+     * The Long Format Name variant of the Format List PDU is supported for
+     * exchanging updated format names. If this flag is not set, the Short Format
+     * Name variant MUST be used. If this flag is set by both protocol endpoints,
+     * then the Long Format Name variant MUST be used.
+     */
+    public static final int CB_USE_LONG_FORMAT_NAMES = 0x00000002;
+
+    /**
+     * File copy and paste using stream-based operations are supported using the
+     * File Contents Request PDU and File Contents Response PDU.
+     */
+    public static final int CB_STREAM_FILECLIP_ENABLED = 0x00000004;
+
+    /**
+     * Indicates that any description of files to copy and paste MUST NOT include
+     * the source path of the files.
+     */
+    public static final int CB_FILECLIP_NO_FILE_PATHS = 0x00000008;
+
+    /**
+     * Locking and unlocking of File Stream data on the clipboard is supported
+     * using the Lock Clipboard Data PDU and Unlock Clipboard Data PDU.
+     */
+    public static final int CB_CAN_LOCK_CLIPDATA = 0x00000010;
+
+    protected ClipboardState state;
+
+    public ServerClipboardCapabilitiesPDU(String id, ClipboardState state) {
+        super(id);
+        this.state = state;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // 0x01, 0x00, // CLIPRDR_CAPS::cCapabilitiesSets = 1
+        int cCapabilitiesSets = buf.readUnsignedShortLE();
+
+        // 0x00, 0x00, // CLIPRDR_CAPS::pad1
+        buf.skipBytes(2);
+
+        // Parse all capability sets
+        for (int capabilitySet = 0; capabilitySet < cCapabilitiesSets; capabilitySet++) {
+            // 0x01, 0x00, // CLIPRDR_CAPS_SET::capabilitySetType =
+            // CB_CAPSTYPE_GENERAL (1)
+            int capabilitySetType = buf.readUnsignedShortLE();
+
+            // 0x0c, 0x00, // CLIPRDR_CAPS_SET::lengthCapability = 0x0c = 12 bytes
+            int lengthCapability = buf.readUnsignedShortLE();
+
+            // parse capability set
+            switch (capabilitySetType) {
+            case CB_CAPSTYPE_GENERAL:
+                parseGeneralCapabilitySet(buf.readBytes(lengthCapability - 4));
+                break;
+            default:
+                // Ignore
+                // throw new RuntimeException("Unknown capability set type: " +
+                // capabilitySetType + ". Expected value: CB_CAPSTYPE_GENERAL (1).");
+            }
+        }
+
+        buf.unref();
+    }
+
+    protected void parseGeneralCapabilitySet(ByteBuffer buf) {
+        // 0x02, 0x00, 0x00, 0x00, // CLIPRDR_GENERAL_CAPABILITY::version =
+        // CB_CAPS_VERSION_2 (2)
+        // long version = buf.readUnsignedIntLE();
+        buf.skipBytes(4);
+
+        // 0x0e, 0x00, 0x00, 0x00, // CLIPRDR_GENERAL_CAPABILITY::capabilityFlags
+        // = 0x0000000e = 0x02 |0x04 |0x08 = CB_USE_LONG_FORMAT_NAMES |
+        // CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS
+        int flags = buf.readSignedIntLE();
+
+        if ((flags & CB_USE_LONG_FORMAT_NAMES) == CB_USE_LONG_FORMAT_NAMES) {
+            state.serverUseLongFormatNames = true;
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Server can use long format names for clipboard data.");
+        }
+
+        if ((flags & CB_STREAM_FILECLIP_ENABLED) == CB_STREAM_FILECLIP_ENABLED) {
+            state.serverStreamFileClipEnabled = true;
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Server supports stream based file clipboard operations.");
+        }
+
+        if ((flags & CB_FILECLIP_NO_FILE_PATHS) == CB_FILECLIP_NO_FILE_PATHS) {
+            state.serverFileClipNoFilePaths = true;
+            if (verbose)
+                System.out.println("[" + this
+                        + "] INFO: Server Indicates that any description of files to copy and paste MUST NOT include the source path of the files.");
+        }
+
+        if ((flags & CB_CAN_LOCK_CLIPDATA) == CB_CAN_LOCK_CLIPDATA) {
+            state.serverCanLockClipdata = true;
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Server can lock and unlock file streams on the clipboard.");
+        }
+
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String[] args) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        0x07, 0x00,  //  CLIPRDR_HEADER::msgType = CB_CLIP_CAPS (7)
+        0x00, 0x00,  //  CLIPRDR_HEADER::msgFlags = 0
+        0x10, 0x00, 0x00, 0x00,  //  CLIPRDR_HEADER::dataLen = 0x10 = 16 bytes
+        0x01, 0x00,  //  CLIPRDR_CAPS::cCapabilitiesSets = 1
+        0x00, 0x00,  //  CLIPRDR_CAPS::pad1
+        0x01, 0x00,  //  CLIPRDR_CAPS_SET::capabilitySetType = CB_CAPSTYPE_GENERAL (1)
+        0x0c, 0x00,  //  CLIPRDR_CAPS_SET::lengthCapability = 0x0c = 12 bytes
+        0x02, 0x00, 0x00, 0x00,  //  CLIPRDR_GENERAL_CAPABILITY::version = CB_CAPS_VERSION_2 (2)
+        0x0e, 0x00, 0x00, 0x00,  //  CLIPRDR_GENERAL_CAPABILITY::capabilityFlags = 0x0000000e = 0x02 |0x04 |0x08 = CB_USE_LONG_FORMAT_NAMES | CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS
+    };
+    /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element router = new ServerClipRdrChannelRouter("router");
+        ClipboardState state = new ClipboardState();
+        Element clip_cap = new ServerClipboardCapabilitiesPDU("clip_cap", state);
+        Element sink = new MockSink("sink", new ByteBuffer[] {});
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, router, clip_cap, sink);
+        pipeline.link("source", "router >clipboard_capabilities", "clip_cap", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        // Check state
+        if (!state.serverUseLongFormatNames || !state.serverStreamFileClipEnabled || !state.serverFileClipNoFilePaths || state.serverCanLockClipdata)
+            throw new RuntimeException("Server clipboard capabilities packet parsed incorrectly.");
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatDataResponsePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatDataResponsePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatDataResponsePDU.java
new file mode 100755
index 0000000..4e5acc1
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatDataResponsePDU.java
@@ -0,0 +1,98 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.clip;
+
+import common.adapter.AwtClipboardAdapter;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class ServerFormatDataResponsePDU extends BaseElement {
+
+    public static final String SERVER_CLIPBOARD_ADAPTER_PAD = "clipboard";
+
+    protected ClipboardState state;
+
+    public ServerFormatDataResponsePDU(String id, ClipboardState state) {
+        super(id);
+        this.state = state;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        parseData(buf);
+
+        buf.unref();
+    }
+
+    protected void parseData(ByteBuffer buf) {
+
+        String content = state.serverRequestedFormat.parseServerResponseAsString(buf);
+
+        // Send response to clipboard adapter
+        ByteBuffer outBuf = new ByteBuffer(0);
+        outBuf.putMetadata(AwtClipboardAdapter.CLIPBOARD_CONTENT, content);
+
+        pushDataToPad(SERVER_CLIPBOARD_ADAPTER_PAD, outBuf);
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String[] args) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        0x05, 0x00,  //  CLIPRDR_HEADER::msgType = CB_FORMAT_DATA_RESPONSE (5)
+        0x01, 0x00,  //  CLIPRDR_HEADER::msgFlags = 0x0001 = CB_RESPONSE_OK
+        0x18, 0x00, 0x00, 0x00,  //  CLIPRDR_HEADER::dataLen = 0x18 = 24 bytes
+        
+        0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x77, 0x00, 0x6f, 0x00,
+        0x72, 0x00, 0x6c, 0x00, 0x64, 0x00, 0x00, 0x00,  //  CLIPRDR_FORMAT_DATA_RESPONSE::requestedFormatData: "hello world"
+    };
+    /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element router = new ServerClipRdrChannelRouter("router");
+        ClipboardState state = new ClipboardState();
+        state.serverRequestedFormat = new ClipboardDataFormat(ClipboardDataFormat.CB_FORMAT_UNICODETEXT, "");
+        Element format_data_response = new ServerFormatDataResponsePDU("format_data_response", state);
+
+        ByteBuffer clipboardAdapterPacket = new ByteBuffer(0);
+        clipboardAdapterPacket.putMetadata(AwtClipboardAdapter.CLIPBOARD_CONTENT, "hello world");
+        Element sink = new MockSink("sink", new ByteBuffer[] {clipboardAdapterPacket});
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, router, format_data_response, sink);
+        pipeline.link("source", "router >format_data_response", "format_data_response >clipboard", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatListPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatListPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatListPDU.java
new file mode 100755
index 0000000..7d305c6
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatListPDU.java
@@ -0,0 +1,237 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.clip;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import rdpclient.rdp.RdpConstants;
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class ServerFormatListPDU extends BaseElement {
+
+    protected ClipboardState state;
+
+    public ServerFormatListPDU(String id, ClipboardState state) {
+        super(id);
+        this.state = state;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        parseFormatNames(buf);
+        buf.unref();
+
+        // Automatically send request for text-based data to insert it into local
+        // clipboard
+        ClipboardDataFormat textFormat = ClipboardDataFormat.findBestTextFormat(state.serverClipboardDataFormats);
+        if (textFormat != null) {
+            // Send response: OK
+            sendFormatListParseResponse(true);
+            // Request data
+            sendFormatDataRequest(textFormat);
+        } else {
+            // Send response: FAIL, we are not interested in this data
+            sendFormatListParseResponse(false);
+        }
+    }
+
+    /**
+     * The Format Data Request PDU is sent by the recipient of the Format List
+     * PDU. It is used to request the data for one of the formats that was listed
+     * in the Format List PDU.
+     */
+    protected void sendFormatDataRequest(ClipboardDataFormat textFormat) {
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Sending request for data in following format: " + textFormat + ".");
+
+        // Store data format to parse server response later 
+        state.serverRequestedFormat = textFormat;
+
+        ByteBuffer buf = new ByteBuffer(12, true);
+
+        // Type
+        buf.writeShortLE(ServerClipRdrChannelRouter.CB_FORMAT_DATA_REQUEST);
+        // Message flags
+        buf.writeShortLE(0);
+        // Length
+        buf.writeIntLE(4);
+
+        // ID of chosen format
+        buf.writeIntLE(textFormat.id);
+
+        buf.trimAtCursor();
+
+        pushDataToPad(STDOUT, buf);
+    }
+
+    /**
+     * The Format List Response PDU is sent as a reply to the Format List PDU. It
+     * is used to indicate whether processing of the Format List PDU was
+     * successful.
+     * 
+     * @param b
+     */
+    protected void sendFormatListParseResponse(boolean ok) {
+        ByteBuffer buf = new ByteBuffer(8, true);
+
+        // Type
+        buf.writeShortLE(ServerClipRdrChannelRouter.CB_FORMAT_LIST_RESPONSE);
+        // Message flags
+        buf.writeShortLE((ok) ? ServerClipRdrChannelRouter.CB_RESPONSE_OK : ServerClipRdrChannelRouter.CB_RESPONSE_FAIL);
+        // Length
+        buf.writeIntLE(0);
+
+        buf.trimAtCursor();
+
+        pushDataToPad(STDOUT, buf);
+    }
+
+    protected void parseFormatNames(ByteBuffer buf) {
+
+        // Set will not be modified after creation, so there is no need to make it
+        // synchronous.
+        Map<Object, ClipboardDataFormat> formats = new HashMap<Object, ClipboardDataFormat>();
+
+        while (buf.cursor < buf.length) {
+            int id = buf.readSignedIntLE();
+
+            String name;
+            if (state.serverUseLongFormatNames) {
+                // Long format names in Unicode
+                name = buf.readVariableWideString(RdpConstants.CHARSET_16);
+            } else {
+                Boolean asciiNames = (Boolean)buf.getMetadata(ServerClipRdrChannelRouter.ASCII_NAMES);
+
+                if (asciiNames != null && asciiNames) {
+                    // Short format names in ASCII
+                    name = buf.readString(32, RdpConstants.CHARSET_8);
+                } else {
+                    // Short format names in Unicode
+                    name = buf.readString(32, RdpConstants.CHARSET_16);
+                }
+
+            }
+
+            // Store format in map by both ID and name (if name is not empty)
+            formats.put(id, new ClipboardDataFormat(id, name));
+            if (name.length() > 0)
+                formats.put(name, new ClipboardDataFormat(id, name));
+        }
+
+        if (verbose)
+            System.out.println("Server supports following formats for clipboard data: " + formats.values().toString() + ".");
+
+        state.serverClipboardDataFormats = formats;
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String[] args) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        0x02, 0x00,  //  CLIPRDR_HEADER::msgType = CB_FORMAT_LIST (2)
+        0x00, 0x00,  //  CLIPRDR_HEADER::msgFlags = 0
+        (byte) 0xe0, 0x00, 0x00, 0x00,  //  CLIPRDR_HEADER::dataLen = 0xe0 = 224 bytes
+
+        (byte) 0x8a, (byte) 0xc0, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 0xc08a = 49290
+        0x52, 0x00, 0x69, 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65, 0x00, 0x78, 0x00, 0x74, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = "Rich Text Format"
+
+        0x45, (byte) 0xc1, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 0xc145 = 49477
+        0x52, 0x00, 0x69, 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65, 0x00, 0x78, 0x00,
+        0x74, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00,
+        0x20, 0x00, 0x57, 0x00, 0x69, 0x00, 0x74, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x74, 0x00,
+        0x20, 0x00, 0x4f, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x73, 0x00,
+        0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = "Rich Text Format Without Objects"
+
+        0x43, (byte) 0xc1, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 0xc143 = 49475
+        0x52, 0x00, 0x54, 0x00, 0x46, 0x00, 0x20, 0x00, 0x41, 0x00, 0x73, 0x00, 0x20, 0x00, 0x54, 0x00,
+        0x65, 0x00, 0x78, 0x00, 0x74, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = "RTF As Text"
+
+        0x01, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 1
+        0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = ""
+
+        0x0d, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 0x0d = 13
+        0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = ""
+
+        0x04, (byte) 0xc0, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 0xc004 = 49156
+        0x4e, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x00, 0x00,  //  "Native"
+
+        0x0e, (byte) 0xc0, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 0xc00e = 49166
+        0x4f, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x20, 0x00, 0x44, 0x00,
+        0x65, 0x00, 0x73, 0x00, 0x63, 0x00, 0x72, 0x00, 0x69, 0x00, 0x70, 0x00, 0x74, 0x00, 0x6f, 0x00, 
+        0x72, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = "Object Descriptor"
+
+        0x03, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 3
+        0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = ""
+
+        0x10, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 16
+        0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = ""
+
+        0x07, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 7
+        0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = ""
+    };
+    /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element router = new ServerClipRdrChannelRouter("router");
+        ClipboardState state = new ClipboardState();
+        state.serverUseLongFormatNames = true;
+        Element format_list = new ServerFormatListPDU("format_list", state);
+
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
+                // Format List Response PDU
+                0x03, 0x00, // CLIPRDR_HEADER::msgType = CB_FORMAT_LIST_RESPONSE (3)
+                0x01, 0x00, // CLIPRDR_HEADER::msgFlags = 0x0001 = CB_RESPONSE_OK
+                0x00, 0x00, 0x00, 0x00, // CLIPRDR_HEADER::dataLen = 0 bytes
+        }, new byte[] {
+                // Format Data Request PDU
+                0x04, 0x00, // CLIPRDR_HEADER::msgType = CB_FORMAT_DATA_REQUEST (4)
+                0x00, 0x00, // CLIPRDR_HEADER::msgFlags = 0
+                0x04, 0x00, 0x00, 0x00, // CLIPRDR_HEADER::dataLen = 4 bytes
+                0x0d, 0x00, 0x00, 0x00, // CLIPRDR_FORMAT_DATA_REQUEST::requestedFormatId
+                                        // = 0x0d
+        }));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, router, format_list, sink);
+        pipeline.link("source", "router >format_list", "format_list", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        // Check state
+        if (!(state.serverClipboardDataFormats.containsKey(49475) && state.serverClipboardDataFormats.containsKey("Rich Text Format")))
+            throw new RuntimeException("Server format list packet parsed incorrectly.");
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerMonitorReadyPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerMonitorReadyPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerMonitorReadyPDU.java
new file mode 100755
index 0000000..6e35dcd
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerMonitorReadyPDU.java
@@ -0,0 +1,85 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.clip;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class ServerMonitorReadyPDU extends BaseElement {
+
+    protected ClipboardState state;
+
+    public ServerMonitorReadyPDU(String id, ClipboardState state) {
+        super(id);
+        this.state = state;
+    }
+
+    // 0x01, 0x00, // CLIPRDR_HEADER::msgType = CB_MONITOR_READY (1)
+    // 0x00, 0x00, // CLIPRDR_HEADER::msgFlags = 0
+    // 0x00, 0x00, 0x00, 0x00, // CLIPRDR_HEADER::dataLen = 0 bytes
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        state.serverReady = true;
+
+        buf.unref();
+
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String[] args) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        0x01, 0x00,  //  CLIPRDR_HEADER::msgType = CB_MONITOR_READY (1)
+        0x00, 0x00,  //  CLIPRDR_HEADER::msgFlags = 0
+        0x00, 0x00, 0x00, 0x00,  //  CLIPRDR_HEADER::dataLen = 0 bytes
+    };
+    /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element router = new ServerClipRdrChannelRouter("router");
+        ClipboardState state = new ClipboardState();
+        Element monitor_ready = new ServerMonitorReadyPDU("monitor_ready", state);
+        Element sink = new MockSink("sink", new ByteBuffer[] {});
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, router, monitor_ready, sink);
+        pipeline.link("source", "router >monitor_ready", "monitor_ready", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        // Check state
+        if (!state.serverReady)
+            throw new RuntimeException("Server monitor ready packet parsed incorrectly.");
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ClientPacketSniffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ClientPacketSniffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ClientPacketSniffer.java
new file mode 100755
index 0000000..3a108ab
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ClientPacketSniffer.java
@@ -0,0 +1,50 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.debug;
+
+/**
+ * Try to determine packet content by it header fingerprint.
+ */
+public class ClientPacketSniffer extends PacketSniffer {
+
+    private static final Pair[] clientRegexps = new Pair[] {
+// @formatter:off
+    new Pair("Client FastPath input",           "04"),
+    new Pair("Client X224ConnectionRequest",    "03 00 XX XX 27 E0"),
+    new Pair("Client ConnectionRequest",        "03 00 XX XX XX E0"),
+    new Pair("Client MCConnectInitial",         "03 00 XX XX 02 F0 80 7F 65"),
+    new Pair("Client ErectDomainRequest",       "03 00 XX XX 02 F0 80 04"),
+    new Pair("Client AttachUserRequest",        "03 00 XX XX 02 F0 80 28"),
+    new Pair("Client ChannelJoinRequest",       "03 00 XX XX 02 F0 80 38"),
+    new Pair("Client Info",                     "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 00 00"),
+    new Pair("Client ConfirmActivePDU",         "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 13 00"),
+    new Pair("Client SynchronizePDU",           "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX 00 XX XX XX XX 1F"),
+    new Pair("Client ControlPDU",               "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX 00 XX XX XX XX 14"),
+    new Pair("Client FontListPDU",              "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX 00 XX XX XX XX 27"),
+    new Pair("Client BitmapCachePersistentList","03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX XX XX XX XX XX 2b"), 
+    new Pair("Client CredSSP",                  "30"),
+    new Pair("Client HyperV PreConnection Blob","5E"),
+    new Pair("Client a TPKT packet",            "03"),
+    new Pair("Client a Fast Path packet",       "00"),
+    // @formatter:on
+    };
+
+    public ClientPacketSniffer(String id) {
+        super(id, clientRegexps);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/PacketSniffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/PacketSniffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/PacketSniffer.java
new file mode 100755
index 0000000..efbe689
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/PacketSniffer.java
@@ -0,0 +1,75 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.debug;
+
+import java.util.regex.Pattern;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+/**
+ * Try to determine packet content by it header fingerprint.
+ */
+public class PacketSniffer extends BaseElement {
+
+    protected Pair regexps[] = null;
+
+    public PacketSniffer(String id, Pair[] regexps) {
+        super(id);
+        this.regexps = regexps;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+
+        matchPacket(buf);
+
+        super.handleData(buf, link);
+    }
+
+    private void matchPacket(ByteBuffer buf) {
+        String header = buf.toPlainHexString(100);
+        for (Pair pair : regexps) {
+            if (pair.regexp.matcher(header).find()) {
+                System.out.println("[" + this + "] INFO: Packet: " + pair.name + ".");
+                return;
+            }
+        }
+
+        System.out.println("[" + this + "] INFO: Unknown packet: " + header + ".");
+    }
+
+    protected static class Pair {
+        String name;
+        Pattern regexp;
+
+        protected Pair(String name, String regexp) {
+            this.name = name;
+            this.regexp = Pattern.compile("^" + replaceShortcuts(regexp), Pattern.CASE_INSENSITIVE);
+        }
+
+        private static String replaceShortcuts(String regexp) {
+            String result = regexp;
+            result = result.replaceAll("XX\\*", "([0-9a-fA-F]{2} )*?");
+            result = result.replaceAll("XX\\?", "([0-9a-fA-F]{2} )?");
+            result = result.replaceAll("XX", "[0-9a-fA-F]{2}");
+            return result;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ServerPacketSniffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ServerPacketSniffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ServerPacketSniffer.java
new file mode 100755
index 0000000..5422769
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ServerPacketSniffer.java
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.debug;
+
+/**
+ * Try to determine packet content by it header fingerprint.
+ */
+public class ServerPacketSniffer extends PacketSniffer {
+
+    private static final Pair[] serverRegexps = new Pair[] {
+// @formatter:off
+  new Pair("Server FastPath update",             "04"),
+  new Pair("Server X224ConnectionRequest",       "03 00 XX XX 0E D0"), 
+  new Pair("Server MCSConnectResponse",          "03 00 XX XX 02 F0 80 7F 66 5A"), 
+  new Pair("Server AttachUserConfirm",           "03 00 XX XX 02 F0 80 2E"),
+  new Pair("Server ChannelJoinConfirm",          "03 00 XX XX 02 F0 80 3E"),
+  new Pair("Server ErrorAlert",                  "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 14 80 00"),
+  new Pair("Server DemandActivePDU",             "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX XX 11"),
+  new Pair("Server ControlPDU",                  "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 17 00 EA 03 EA 03 XX 00 XX XX XX XX 14"),
+  new Pair("Server SynchronizePDU",              "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 17 00 EA 03 EA 03 XX 00 XX XX XX XX 1F"),
+  new Pair("Server FontMapPDU",                  "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 17 00 EA 03 EA 03 XX 00 XX XX XX XX 28"),
+  new Pair("Server SET_ERROR_INFO_PDU",          "03 00 XX XX 02 F0 80 68 00 01 03 EB 30 XX XX XX 17 00 00 00 EA 03 XX 00 XX XX XX XX 2F"),
+  new Pair("Server DeactivateAllPDU",            "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 16 00"),
+  new Pair("Server CloseConnection",             "03 00 00 09 02 F0 80 21 80"),
+  new Pair("Server CredSSP",                     "30"),
+  new Pair("Server a TPKT packet",               "03"),
+  new Pair("Server a FastPath packet",           "00"),
+  // @formatter:on
+    };
+
+    public ServerPacketSniffer(String id) {
+        super(id, serverRegexps);
+    }
+}


[16/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerDemandActivePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerDemandActivePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerDemandActivePDU.java
deleted file mode 100644
index 9ce87d3..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerDemandActivePDU.java
+++ /dev/null
@@ -1,661 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.FakeSink;
-import streamer.Link;
-import streamer.MockSource;
-import streamer.Order;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-import common.ScreenDescription;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240669.aspx
- * @see http://msdn.microsoft.com/en-us/library/cc240484.aspx
- */
-public class ServerDemandActivePDU extends BaseElement {
-
-  /**
-   * Demand Active PDU.
-   */
-  public static final int PDUTYPE_DEMANDACTIVEPDU = 0x1;
-
-  protected RdpState state;
-  protected ScreenDescription screen;
-
-  public ServerDemandActivePDU(String id, ScreenDescription screen, RdpState state) {
-    super(id);
-    this.state = state;
-    this.screen = screen;
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    // Total length of packet
-    int length = buf.readSignedShortLE(); // Ignore
-    if (buf.length != length)
-      throw new RuntimeException("Incorrect length of packet. Length: " + length + ", data: " + buf + ".");
-
-    int type = buf.readSignedShortLE() & 0xf;
-    if (type != PDUTYPE_DEMANDACTIVEPDU)
-      throw new RuntimeException("Unknown PDU type. Expected type: Demand Active PDU (0x1), actual tyoe: " + type + ", data: " + buf + ".");
-
-    // TS_SHARECONTROLHEADER::pduSource = 0x03ea (1002)
-    int pduSource = buf.readSignedShortLE();
-    if (pduSource != 1002)
-      throw new RuntimeException("Unexepcted source of demand active PDU. Expected source: 1002, actual source: " + pduSource + ".");
-
-    // (4 bytes): A 32-bit, unsigned integer. The share identifier for the
-    // packet (see [T128] section 8.4.2 for more information regarding share
-    // IDs).
-    long shareId = buf.readUnsignedIntLE();
-    state.serverShareId = shareId;
-
-    // Ignore rest of server data because it is not used by this client.
-    // (2 bytes): A 16-bit, unsigned integer. The size in bytes of the
-    // sourceDescriptor field.
-    int lengthSourceDescriptor = buf.readUnsignedShortLE();
-
-    // (2 bytes): A 16-bit, unsigned integer. The combined size in bytes of the
-    // numberCapabilities, pad2Octets, and capabilitySets fields.
-    int lengthCombinedCapabilities = buf.readUnsignedShortLE();
-
-    // (variable): A variable-length array of bytes containing a source
-    // descriptor,
-    // ByteBuffer sourceDescriptor = buf.readBytes(lengthSourceDescriptor);
-    buf.skipBytes(lengthSourceDescriptor);
-
-    // (variable): An array of Capability Set (section 2.2.1.13.1.1.1)
-    // structures. The number of capability sets is specified by the
-    // numberCapabilities field.
-    handleCapabiltySets(buf.readBytes(lengthCombinedCapabilities));
-
-    // (4 bytes): A 32-bit, unsigned integer. The session identifier. This field
-    // is ignored by the client.
-    buf.skipBytes(4);
-
-    /* DEBUG */buf.assertThatBufferIsFullyRead();
-
-    buf.unref();
-
-    sendHandshakePackets();
-  }
-
-  /**
-   * General Capability Set
-   */
-  public static final int CAPSTYPE_GENERAL = 0x0001;
-  /**
-   * Bitmap Capability Set
-   */
-  public static final int CAPSTYPE_BITMAP = 0x0002;
-  /**
-   * Order Capability Set
-   */
-  public static final int CAPSTYPE_ORDER = 0x0003;
-  /**
-   * Revision 1 Bitmap Cache Capability Set
-   */
-  public static final int CAPSTYPE_BITMAPCACHE = 0x0004;
-  /**
-   * Control Capability Set
-   */
-  public static final int CAPSTYPE_CONTROL = 0x0005;
-  /**
-   * Window Activation Capability Set
-   */
-  public static final int CAPSTYPE_ACTIVATION = 0x0007;
-  /**
-   * Pointer Capability Set
-   */
-  public static final int CAPSTYPE_POINTER = 0x0008;
-  /**
-   * Share Capability Set
-   */
-  public static final int CAPSTYPE_SHARE = 0x0009;
-  /**
-   * Color Table Cache Capability Set
-   */
-  public static final int CAPSTYPE_COLORCACHE = 0x000A;
-  /**
-   * Sound Capability Set
-   */
-  public static final int CAPSTYPE_SOUND = 0x000C;
-  /**
-   * Input Capability Set
-   */
-  public static final int CAPSTYPE_INPUT = 0x000D;
-  /**
-   * Font Capability Set
-   */
-  public static final int CAPSTYPE_FONT = 0x000E;
-  /**
-   * Brush Capability Set
-   */
-  public static final int CAPSTYPE_BRUSH = 0x000F;
-  /**
-   * Glyph Cache Capability Set
-   */
-  public static final int CAPSTYPE_GLYPHCACHE = 0x0010;
-  /**
-   * Offscreen Bitmap Cache Capability Set
-   */
-  public static final int CAPSTYPE_OFFSCREENCACHE = 0x0011;
-  /**
-   * Bitmap Cache Host Support Capability Set
-   */
-  public static final int CAPSTYPE_BITMAPCACHE_HOSTSUPPORT = 0x0012;
-  /**
-   * Revision 2 Bitmap Cache Capability Set
-   */
-  public static final int CAPSTYPE_BITMAPCACHE_REV2 = 0x0013;
-  /**
-   * Virtual Channel Capability Set
-   */
-  public static final int CAPSTYPE_VIRTUALCHANNEL = 0x0014;
-  /**
-   * DrawNineGrid Cache Capability Set
-   */
-  public static final int CAPSTYPE_DRAWNINEGRIDCACHE = 0x0015;
-  /**
-   * Draw GDI+ Cache Capability Set
-   */
-  public static final int CAPSTYPE_DRAWGDIPLUS = 0x0016;
-  /**
-   * Remote Programs Capability Set
-   */
-  public static final int CAPSTYPE_RAIL = 0x0017;
-  /**
-   * Window List Capability Set
-   */
-  public static final int CAPSTYPE_WINDOW = 0x0018;
-  /**
-   * Desktop Composition Extension Capability Set
-   */
-  public static final int CAPSETTYPE_COMPDESK = 0x0019;
-  /**
-   * Multifragment Update Capability Set
-   */
-  public static final int CAPSETTYPE_MULTIFRAGMENTUPDATE = 0x001A;
-  /**
-   * Large Pointer Capability Set
-   */
-  public static final int CAPSETTYPE_LARGE_POINTER = 0x001B;
-  /**
-   * Surface Commands Capability Set
-   */
-  public static final int CAPSETTYPE_SURFACE_COMMANDS = 0x001C;
-  /**
-   * Bitmap Codecs Capability Set
-   */
-  public static final int CAPSETTYPE_BITMAP_CODECS = 0x001D;
-  /**
-   * Frame Acknowledge Capability Set
-   */
-  public static final int CAPSSETTYPE_FRAME_ACKNOWLEDGE = 0x001E;
-
-  /**
-   * @see http://msdn.microsoft.com/en-us/library/cc240486.aspx
-   */
-  protected void handleCapabiltySets(ByteBuffer buf) {
-    // (2 bytes): A 16-bit, unsigned integer. The number of capability sets
-    // included in the Demand Active PDU.
-    int numberCapabilities = buf.readSignedShortLE();
-
-    // (2 bytes): Padding.
-    buf.skipBytes(2);
-
-    for (int i = 0; i < numberCapabilities; i++) {
-      // (2 bytes): A 16-bit, unsigned integer. The type identifier of the
-      // capability set.
-      int capabilitySetType = buf.readUnsignedShortLE();
-
-      // (2 bytes): A 16-bit, unsigned integer. The length in bytes of the
-      // capability data, including the size of the capabilitySetType and
-      // lengthCapability fields.
-      int lengthCapability = buf.readUnsignedShortLE();
-
-      // (variable): Capability set data which conforms to the structure of the
-      // type given by the capabilitySetType field.
-      ByteBuffer capabilityData = buf.readBytes(lengthCapability - 4);
-
-      switch (capabilitySetType) {
-      case CAPSTYPE_GENERAL:
-        break;
-      case CAPSTYPE_BITMAP:
-        handleBitmapCapabilities(capabilityData);
-        break;
-      case CAPSTYPE_ORDER:
-        break;
-      case CAPSTYPE_BITMAPCACHE:
-        break;
-      case CAPSTYPE_CONTROL:
-        break;
-      case CAPSTYPE_ACTIVATION:
-        break;
-      case CAPSTYPE_POINTER:
-        break;
-      case CAPSTYPE_SHARE:
-        break;
-      case CAPSTYPE_COLORCACHE:
-        break;
-      case CAPSTYPE_SOUND:
-        break;
-      case CAPSTYPE_INPUT:
-        break;
-      case CAPSTYPE_FONT:
-        break;
-      case CAPSTYPE_BRUSH:
-        break;
-      case CAPSTYPE_GLYPHCACHE:
-        break;
-      case CAPSTYPE_OFFSCREENCACHE:
-        break;
-      case CAPSTYPE_BITMAPCACHE_HOSTSUPPORT:
-        break;
-      case CAPSTYPE_BITMAPCACHE_REV2:
-        break;
-      case CAPSTYPE_VIRTUALCHANNEL:
-        break;
-      case CAPSTYPE_DRAWNINEGRIDCACHE:
-        break;
-      case CAPSTYPE_DRAWGDIPLUS:
-        break;
-      case CAPSTYPE_RAIL:
-        break;
-      case CAPSTYPE_WINDOW:
-        break;
-      case CAPSETTYPE_COMPDESK:
-        break;
-      case CAPSETTYPE_MULTIFRAGMENTUPDATE:
-        break;
-      case CAPSETTYPE_LARGE_POINTER:
-        break;
-      case CAPSETTYPE_SURFACE_COMMANDS:
-        break;
-      case CAPSETTYPE_BITMAP_CODECS:
-        break;
-      case CAPSSETTYPE_FRAME_ACKNOWLEDGE:
-        break;
-      default:
-        // Ignore
-        break;
-      }
-
-      capabilityData.unref();
-    }
-
-    // TODO
-
-    buf.unref();
-  }
-
-  /**
-   * @see http://msdn.microsoft.com/en-us/library/cc240554.aspx
-   */
-  protected void handleBitmapCapabilities(ByteBuffer buf) {
-
-    // (2 bytes): A 16-bit, unsigned integer. The server MUST set this field to
-    // the color depth of the session, while the client SHOULD set this field to
-    // the color depth requested in the Client Core Data (section 2.2.1.3.2).
-    int preferredBitsPerPixel = buf.readUnsignedShortLE();
-    screen.setPixelFormatRGBTrueColor(preferredBitsPerPixel);
-
-    // receive1BitPerPixel (2 bytes): A 16-bit, unsigned integer. Indicates
-    // whether the client can receive 1 bpp. This field is ignored and SHOULD be
-    // set to TRUE (0x0001).
-    buf.skipBytes(2);
-
-    // receive4BitsPerPixel(2 bytes): A 16-bit, unsigned integer. Indicates
-    // whether the client can receive 4 bpp. This field is ignored and SHOULD be
-    // set to TRUE (0x0001).
-    buf.skipBytes(2);
-
-    // receive8BitsPerPixel (2 bytes): A 16-bit, unsigned integer. Indicates
-    // whether the client can receive 8 bpp. This field is ignored and SHOULD be
-    // set to TRUE (0x0001).
-    buf.skipBytes(2);
-
-    // (2 bytes): A 16-bit, unsigned integer. The width of the desktop in the
-    // session.
-    int desktopWidth = buf.readUnsignedShortLE();
-
-    // (2 bytes): A 16-bit, unsigned integer. The height of the desktop in the
-    // session.
-    int desktopHeight = buf.readUnsignedShortLE();
-
-    screen.setFramebufferSize(desktopWidth, desktopHeight);
-
-    // pad2octets (2 bytes): A 16-bit, unsigned integer. Padding. Values in this
-    // field MUST be ignored.
-
-    // desktopResizeFlag (2 bytes): A 16-bit, unsigned integer. Indicates
-    // whether resizing the desktop by using a Deactivation-Reactivation
-    // Sequence is supported.
-
-    // bitmapCompressionFlag (2 bytes): A 16-bit, unsigned integer. Indicates
-    // whether bitmap compression is supported. This field MUST be set to TRUE
-    // (0x0001) because support for compressed bitmaps is required for a
-    // connection to proceed.
-
-    // highColorFlags (1 byte): An 8-bit, unsigned integer. Client support for
-    // 16 bpp color modes. This field is ignored and SHOULD be set to zero.
-
-    // drawingFlags (1 byte): An 8-bit, unsigned integer. Flags describing
-    // support for 32 bpp bitmaps.
-
-    // multipleRectangleSupport (2 bytes): A 16-bit, unsigned integer. Indicates
-    // whether the use of multiple bitmap rectangles is supported in the Bitmap
-    // Update (section 2.2.9.1.1.3.1.2). This field MUST be set to TRUE (0x0001)
-    // because multiple rectangle support is required for a connection to
-    // proceed.
-
-    // pad2octetsB (2 bytes): A 16-bit, unsigned integer. Padding. Values in
-    // this field MUST be ignored.
-  }
-
-  /**
-   * Send all client requests in one hop, to simplify logic.
-   */
-  protected void sendHandshakePackets() {
-    // Send reactivation sequence in bulk
-    pushDataToPad("confirm_active", new ByteBuffer((Order) null));
-  }
-
-  /**
-   * Example.
-   * 
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    /* @formatter:off */
-    byte[] packet = new byte[] {
-        0x67, 0x01,  //  TS_SHARECONTROLHEADER::totalLength = 0x0167 = 359 bytes
-        0x11, 0x00,  //  TS_SHARECONTROLHEADER::pduType = 0x0011 0x0011 = 0x0010 | 0x0001  = TS_PROTOCOL_VERSION | PDUTYPE_DEMANDACTIVEPDU
-
-        (byte) 0xea, 0x03,  //  TS_SHARECONTROLHEADER::pduSource = 0x03ea (1002)
-
-        (byte) 0xea, 0x03, 0x01, 0x00,  //  TS_DEMAND_ACTIVE_PDU::shareId
-        0x04, 0x00,  //  TS_DEMAND_ACTIVE_PDU::lengthSourceDescriptor = 4 bytes
-        0x51, 0x01,  //  TS_DEMAND_ACTIVE_PDU::lengthCombinedCapabilities = 0x151 = 337 bytes
-
-        0x52, 0x44, 0x50, 0x00,  //  TS_DEMAND_ACTIVE_PDU::sourceDescriptor = "RDP"
-
-        0x0d, 0x00,  //  TS_DEMAND_ACTIVE_PDU::numberCapabilities = 13
-        0x00, 0x00,  //  TS_DEMAND_ACTIVE_PDU::pad2octets
-
-        //  Share Capability Set (8 bytes)
-        // 0x09, 0x00, 0x08, 0x00, (byte) 0xea, 0x03, (byte) 0xdc, (byte) 0xe2,
-        // 
-        0x09, 0x00,  //  TS_SHARE_CAPABILITYSET::capabilitySetType = CAPSTYPE_SHARE (9)
-        0x08, 0x00,  //  TS_SHARE_CAPABILITYSET::lengthCapability = 8 bytes
-        (byte) 0xea, 0x03,  //  TS_SHARE_CAPABILITYSET::nodeID = 0x03ea (1002)
-        (byte) 0xdc, (byte) 0xe2,  //  TS_SHARE_CAPABILITYSET::pad2octets
-
-        //  General Capability Set (24 bytes)
-        // 0x01, 0x00, 0x18, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x04, 
-        // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 
-        // 
-        0x01, 0x00,  //  TS_GENERAL_CAPABILITYSET::capabilitySetType = CAPSTYPE_GENERAL (1)
-        0x18, 0x00,  //  TS_GENERAL_CAPABILITYSET::lengthCapability = 24 bytes
-
-        0x01, 0x00,  //  TS_GENERAL_CAPABILITYSET::osMajorType = TS_OSMAJORTYPE_WINDOWS (1)
-        0x03, 0x00,  //  TS_GENERAL_CAPABILITYSET::osMinorType = TS_OSMINORTYPE_WINDOWS_NT (3)
-        0x00, 0x02,  //  TS_GENERAL_CAPABILITYSET::protocolVersion = TS_CAPS_PROTOCOLVERSION (0x0200)
-        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::pad2octetsA
-        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::generalCompressionTypes = 0
-        0x1d, 0x04,  //  TS_GENERAL_CAPABILITYSET::extraFlags = 0x041d = 0x0400 | 0x0010 | 0x0008 | 0x0004 | 0x0001 = NO_BITMAP_COMPRESSION_HDR | ENC_SALTED_CHECKSUM | AUTORECONNECT_SUPPORTED | LONG_CREDENTIALS_SUPPORTED | FASTPATH_OUTPUT_SUPPORTED
-
-        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::updateCapabilityFlag = 0
-        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::remoteUnshareFlag = 0
-        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::generalCompressionLevel = 0
-        0x01,  //  TS_GENERAL_CAPABILITYSET::refreshRectSupport = TRUE
-        0x01,  //  TS_GENERAL_CAPABILITYSET::suppressOutputSupport = TRUE
-
-        // Virtual Channel Capability Set (8 bytes)
-        // 0x14, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 
-        // 
-        0x14, 0x00,  //  TS_VIRTUALCHANNEL_CAPABILITYSET::capabilitySetType = CAPSTYPE_VIRTUALCHANNEL (20)
-        0x08, 0x00,  //  TS_VIRTUALCHANNEL_CAPABILITYSET::lengthCapability = 8 bytes
-
-        0x02, 0x00, 0x00, 0x00,  //  TS_VIRTUALCHANNEL_CAPABILITYSET::vccaps1 = 0x00000002 = VCCAPS_COMPR_CS_8K
-
-        //  DrawGdiPlus Capability Set (40 bytes)
-        // 0x16, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, (byte) 0xf6, 0x13, (byte) 0xf3, 0x01, 0x00, 0x00, 0x00, 
-        // 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, (byte) 0x9c, (byte) 0xf6, 0x13, (byte) 0xf3, 0x61, (byte) 0xa6, (byte) 0x82, (byte) 0x80, 
-        // 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, (byte) 0x91, (byte) 0xbf, 
-        // 
-        0x16, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::capabilitySetType = CAPSTYPE_DRAWGDIPLUS (22)
-        0x28, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::lengthCapability = 40 bytes
-
-        0x00, 0x00, 0x00, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::drawGdiplusSupportLevel = TS_DRAW_GDIPLUS_DEFAULT (0)
-        0x70, (byte) 0xf6, 0x13, (byte) 0xf3,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::GdipVersion (not initialized by server)
-        0x01, 0x00, 0x00, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::drawGdiplusCacheLevel  = TS_DRAW_GDIPLUS_CACHE_LEVEL_ONE (1)
-
-        0x01, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipGraphicsCacheEntries  (not initialized by server)
-        0x00, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectBrushCacheEntries (not initialized by server)
-        0x18, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectPenCacheEntries (not initialized by server)
-        0x00, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectImageCacheEntries (not initialized by server)
-        (byte) 0x9c, (byte) 0xf6,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectImageAttributesCacheEntries (not initialized by server)
-
-        0x13, (byte) 0xf3,  //  TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipGraphicsCacheChunkSize  (not initialized by server)
-        0x61, (byte) 0xa6,  //  TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipObjectBrushCacheChunkSize (not initialized by server)
-        (byte) 0x82, (byte) 0x80,  //  TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipObjectPenCacheChunkSize (not initialized by server)
-        0x00, 0x00,  //   TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipObjectImageAttributesCacheChunkSize (not initialized by server)
-
-        0x00, 0x00,  //  TS_GDIPLUS_IMAGE_CACHE_PROPERTIES::GdipObjectImageCacheChunkSize  (not initialized by server)
-        0x00, 0x50,  //  TS_GDIPLUS_IMAGE_CACHE_PROPERTIES::GdipObjectImageCacheTotalSize  (not initialized by server)
-        (byte) 0x91, (byte) 0xbf,  //  TS_GDIPLUS_IMAGE_CACHE_PROPERTIES::GdipObjectImageCacheMaxSize (not initialized by server)
-
-        //  Font Capability Set (4 bytes)
-        // 0x0e, 0x00, 0x04, 0x00,
-        //
-        // Due to a bug, the TS_FONT_CAPABILITYSET capability set size is incorrectly set to 4 bytes (it must be 8 bytes). As a result of this bug, the fontSupportFlags and pad2octets fields are missing.
-        0x0e, 0x00,  //  TS_FONT_CAPABILITYSET::capabilitySetType = CAPSTYPE_FONT (14)
-        0x04, 0x00,  //  TS_FONT_CAPABILITYSET::lengthCapability = 4 bytes
-
-
-        //  Bitmap Capability Set (28 bytes)
-        // 0x02, 0x00, 0x1c, 0x00, 0x18, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 
-        // 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
-        // 
-        0x02, 0x00,  //  TS_BITMAP_CAPABILITYSET::capabilitySetType = CAPSTYPE_BITMAP (2)
-        0x1c, 0x00,  //  TS_BITMAP_CAPABILITYSET::lengthCapability = 28 bytes
-
-        0x18, 0x00,  //  TS_BITMAP_CAPABILITYSET::preferredBitsPerPixel = 24 bpp
-        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::receive1BitPerPixel = TRUE
-        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::receive4BitsPerPixel = TRUE
-        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::receive8BitsPerPixel = TRUE
-        0x00, 0x05,  //  TS_BITMAP_CAPABILITYSET::desktopWidth = 1280 pixels
-        0x00, 0x04,  //  TS_BITMAP_CAPABILITYSET::desktopHeight = 1024 pixels
-        0x00, 0x00,  //  TS_BITMAP_CAPABILITYSET::pad2octets
-        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::desktopResizeFlag = TRUE
-        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::bitmapCompressionFlag = TRUE
-        0x00,  //  TS_BITMAP_CAPABILITYSET::highColorFlags = 0
-        0x00,  //  TS_BITMAP_CAPABILITYSET::pad1octet
-        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::multipleRectangleSupport = TRUE
-        0x00, 0x00,  //  TS_BITMAP_CAPABILITYSET::pad2octetsB
-
-        //  Order Capability Set (88 bytes)
-        // 0x03, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-        // 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 
-        // 0x00, 0x00, 0x22, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 
-        // 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 
-        // 0x00, 0x00, 0x00, 0x00, (byte) 0xa1, 0x06, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x40, 0x42, 0x0f, 0x00, 
-        // 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-        // 
-        0x03, 0x00,  //  TS_ORDER_CAPABILITYSET::capabilitySetType = CAPSTYPE_ORDER (3)
-        0x58, 0x00,  //  TS_ORDER_CAPABILITYSET::lengthCapability = 88 bytes
-
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // TS_ORDER_CAPABILITYSET::terminalDescriptor = ""
-        0x40, 0x42, 0x0f, 0x00,  //  TS_ORDER_CAPABILITYSET::pad4octetsA
-
-        0x01, 0x00,  //  TS_ORDER_CAPABILITYSET::desktopSaveXGranularity = 1
-        0x14, 0x00,  //  TS_ORDER_CAPABILITYSET::desktopSaveYGranularity = 20
-        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsA
-        0x01, 0x00,  //  TS_ORDER_CAPABILITYSET::maximumOrderLevel = ORD_LEVEL_1_ORDERS (1)
-        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::numberFonts = 0
-
-        0x22, 0x00,  //  TS_ORDER_CAPABILITYSET::orderFlags = 0x0022 = 0x0020 | 0x0002 = COLORINDEXSUPPORT | NEGOTIATEORDERSUPPORT   
-
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_DSTBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_PATBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_SCRBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEMBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEM3BLT_INDEX] = TRUE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_ATEXTOUT_INDEX] = FALSE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_AEXTTEXTOUT_INDEX] = FALSE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_DRAWNINEGRID_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_LINETO_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTI_DRAWNINEGRID_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_OPAQUERECT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_SAVEBITMAP_INDEX] = TRUE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WTEXTOUT_INDEX] = FALSE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEMBLT_R2_INDEX] = FALSE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEM3BLT_R2_INDEX] = FALSE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTIDSTBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTIPATBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTISCRBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTIOPAQUERECT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_FAST_INDEX_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_POLYGON_SC_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_POLYGON_CB_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_POLYLINE_INDEX] = TRUE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[23] = 0
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_FAST_GLYPH_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_ELLIPSE_SC_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_ELLIPSE_CB_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_INDEX_INDEX] = TRUE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WEXTTEXTOUT_INDEX] = FALSE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WLONGTEXTOUT_INDEX] = FALSE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WLONGEXTTEXTOUT_INDEX] = FALSE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[24] = 0
-
-        (byte) 0xa1, 0x06,  //  TS_ORDER_CAPABILITYSET::textFlags = 0x06a1
-
-        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsB
-        0x40, 0x42, 0x0f, 0x00,  //  TS_ORDER_CAPABILITYSET::pad4octetsB
-
-        0x40, 0x42, 0x0f, 0x00,  //  TS_ORDER_CAPABILITYSET::desktopSaveSize = 0xf4240 = 1000000
-        0x01, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsC
-        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsD
-        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::textANSICodePage
-        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsE
-
-        // Color Table Cache Capability Set (8 bytes)
-        // 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 
-        // 
-        0x0a, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::capabilitySetType = CAPSTYPE_COLORCACHE (10)
-        0x08, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::lengthCapability = 8 bytes
-
-        0x06, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::colorTableCacheSize = 6
-        0x00, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::pad2octets
-
-        // Bitmap Cache Host Support Capability Set (8 bytes)
-        // 0x12, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 
-        // 
-        0x12, 0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::capabilitySetType  = CAPSTYPE_BITMAPCACHE_HOSTSUPPORT (18)
-        0x08, 0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::lengthCapability  = 8 bytes
-
-        0x01,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::CacheVersion = 1  (corresponds to rev. 2 capabilities)
-        0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::Pad1
-        0x00, 0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::Pad2
-
-        // Pointer Capability Set (10 bytes)
-        // 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00, 0x19, 0x00, 
-        // 
-        0x08, 0x00,  //  TS_POINTER_CAPABILITYSET::capabilitySetType = CAPSTYPE_POINTER (8)
-        0x0a, 0x00,  //  TS_POINTER_CAPABILITYSET::lengthCapability = 10 bytes
-
-        0x01, 0x00,  //  TS_POINTER_CAPABILITYSET::colorPointerFlag = TRUE
-        0x19, 0x00,  //  TS_POINTER_CAPABILITYSET::colorPointerCacheSize = 25
-        0x19, 0x00,  //  TS_POINTER_CAPABILITYSET::pointerCacheSize = 25
-
-        //  Input Capability Set (88 bytes)
-        // 0x0d, 0x00, 0x58, 0x00, 0x35, 0x00, 0x00, 0x00, (byte) 0xa1, 0x06, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 
-        // 0x0c, (byte) 0xf6, 0x13, (byte) 0xf3, (byte) 0x93, 0x5a, 0x37, (byte) 0xf3, 0x00, (byte) 0x90, 0x30, (byte) 0xe1, 0x34, 0x1c, 0x38, (byte) 0xf3, 
-        // 0x40, (byte) 0xf6, 0x13, (byte) 0xf3, 0x04, 0x00, 0x00, 0x00, 0x4c, 0x54, (byte) 0xdc, (byte) 0xe2, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 
-        // 0x01, 0x00, 0x00, 0x00, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 0x00, 0x00, 0x00, 0x00, 0x38, (byte) 0xf6, 0x13, (byte) 0xf3, 
-        // 0x2e, 0x05, 0x38, (byte) 0xf3, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 0x2c, (byte) 0xf6, 0x13, (byte) 0xf3, 0x00, 0x00, 0x00, 0x00, 
-        // 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00,
-        // 
-        0x0d, 0x00,  //  TS_INPUT_CAPABILITYSET::capabilitySetType = CAPSTYPE_INPUT (13)
-        0x58, 0x00,  //  TS_INPUT_CAPABILITYSET::lengthCapability = 88 bytes
-
-        0x35, 0x00,  //  TS_INPUT_CAPABILITYSET::inputFlags = 0x0035 = 0x0020 | 0x0010 | 0x0004 | 0x0001 = INPUT_FLAG_FASTPATH_INPUT2 | INPUT_FLAG_VKPACKET | INPUT_FLAG_MOUSEX | INPUT_FLAG_SCANCODES
-
-        0x00, 0x00,  //  TS_INPUT_CAPABILITYSET::pad2octetsA
-        (byte) 0xa1, 0x06, 0x00, 0x00,  //  TS_INPUT_CAPABILITYSET::keyboardLayout (not initialized by server)
-        0x40, 0x42, 0x0f, 0x00,  //  TS_INPUT_CAPABILITYSET::keyboardType (not initialized by server)
-        0x0c, (byte) 0xf6, 0x13, (byte) 0xf3,  //  TS_INPUT_CAPABILITYSET::keyboardSubType  (not initialized by server)
-        (byte) 0x93, 0x5a, 0x37, (byte) 0xf3,  //  TS_INPUT_CAPABILITYSET::keyboardFunctionKey (not initialized by server)
-
-        // TS_INPUT_CAPABILITYSET::imeFileName (not initialized by server)
-        0x00, (byte) 0x90, 0x30, (byte) 0xe1, 0x34, 0x1c, 0x38, (byte) 0xf3, 0x40, (byte) 0xf6, 0x13, (byte) 0xf3, 0x04, 0x00, 0x00, 0x00, 
-        0x4c, 0x54, (byte) 0xdc, (byte) 0xe2, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 0x01, 0x00, 0x00, 0x00, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 
-        0x00, 0x00, 0x00, 0x00, 0x38, (byte) 0xf6, 0x13, (byte) 0xf3, 0x2e, 0x05, 0x38, (byte) 0xf3, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 
-        0x2c, (byte) 0xf6, 0x13, (byte) 0xf3, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00, 
-
-        //  RAIL Capability Set (8 bytes)
-        // 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
-        // 
-        0x17, 0x00,  //  TS_RAIL_CAPABILITYSET::capabilitySetType = CAPSTYPE_RAIL (23)
-        0x08, 0x00,  //  TS_RAIL_CAPABILITYSET::lengthCapability = 8 bytes
-
-        0x00, 0x00, 0x00, 0x00,  //  TS_RAIL_CAPABILITYSET::railSupportLevel = TS_RAIL_LEVEL_DEFAULT (0)
-
-        //  Windowing Capability Set (11 bytes)
-        // 0x18, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-        //
-        0x18, 0x00,  //  TS_WINDOW_CAPABILITYSET::capabilitySetType =  CAPSTYPE_WINDOW (24)
-        0x0b, 0x00,  //  TS_WINDOW_CAPABILITYSET::lengthCapability = 11 bytes
-
-        0x00, 0x00, 0x00, 0x00,  //  TS_WINDOW_CAPABILITYSET::wndSupportLevel = TS_WINDOW_LEVEL_DEFAULT (0)
-        0x00,  //  TS_WINDOW_CAPABILITYSET::nIconCaches = 0
-        0x00, 0x00,  //  TS_WINDOW_CAPABILITYSET::nIconCacheEntries = 0
-
-        // Remainder of Demand Active PDU:
-
-        0x00, 0x00, 0x00, 0x00,  //  TS_DEMAND_ACTIVE_PDU::sessionId = 0    
-    };
-    /* @formatter:on */
-
-    RdpState rdpState = new RdpState();
-    ScreenDescription screenDescription = new ScreenDescription();
-
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
-    Element demandActive = new ServerDemandActivePDU("demand_active", screenDescription, rdpState);
-    Element sink = new FakeSink("sink");
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, demandActive, sink);
-    pipeline.link("source", "demand_active", "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerFastPath.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerFastPath.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerFastPath.java
deleted file mode 100644
index fbec1ce..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerFastPath.java
+++ /dev/null
@@ -1,259 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240621.aspx
- */
-public class ServerFastPath extends BaseElement {
-
-  /**
-   * TPKT protocol version (first byte).
-   */
-  public static final int PROTOCOL_TPKT = 3;
-  
-  /**
-   * Fast path protocol version (first two bits of first byte).
-   */
-  public static final int PROTOCOL_FASTPATH = 0;
-  
-  
-  /**
-   * TPKT packets will be pushed to that pad.
-   */
-  public static final String TPKT_PAD = "tpkt";
-
-  private static final String ORDERS_PAD = "orders";
-  private static final String BITMAP_PAD = "bitmap";
-  private static final String PALETTE_PAD = "palette";
-
-  /**
-   * Indicates that packet contains 8 byte secure checksum at top of packet. Top
-   * two bits of first byte.
-   */
-  public static final int FASTPATH_OUTPUT_SECURE_CHECKSUM = 1;
-
-  /**
-   * Indicates that packet contains 8 byte secure checksum at top of packet and
-   * packet content is encrypted. Top two bits of first byte.
-   */
-  public static final int FASTPATH_OUTPUT_ENCRYPTED = 2;
-
-  public static final int FASTPATH_UPDATETYPE_ORDERS = 0;
-  public static final int FASTPATH_UPDATETYPE_BITMAP = 1;
-  public static final int FASTPATH_UPDATETYPE_PALETTE = 2;
-  public static final int FASTPATH_UPDATETYPE_SYNCHRONIZE = 3;
-  public static final int FASTPATH_UPDATETYPE_SURFCMDS = 4;
-  public static final int FASTPATH_UPDATETYPE_PTR_NULL = 5;
-  public static final int FASTPATH_UPDATETYPE_PTR_DEFAULT = 6;
-  public static final int FASTPATH_UPDATETYPE_PTR_POSITION = 8;
-  public static final int FASTPATH_UPDATETYPE_COLOR = 9;
-  public static final int FASTPATH_UPDATETYPE_CACHED = 0xa;
-  public static final int FASTPATH_UPDATETYPE_POINTER = 0xb;
-
-  public static final int FASTPATH_FRAGMENT_SINGLE = 0;
-  public static final int FASTPATH_FRAGMENT_LAST = 1;
-  public static final int FASTPATH_FRAGMENT_FIRST = 2;
-  public static final int FASTPATH_FRAGMENT_NEXT = 3;
-
-  public static final int FASTPATH_OUTPUT_COMPRESSION_USED = 2;
-
-  public ServerFastPath(String id) {
-    super(id);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    //* DEBUG */System.out.println(buf.toHexString(buf.length));
-
-    // We need at 4 bytes to read packet type (TPKT or FastPath) and packet
-    // length
-    if (!cap(buf, 4, UNLIMITED, link, false))
-      return;
-
-    int typeAndFlags = buf.readUnsignedByte();
-
-    if (typeAndFlags == PROTOCOL_TPKT) {
-      //
-      // TPKT
-      //
-
-      // Reserved
-      buf.skipBytes(1);
-
-      // Read TPKT length
-      int length = buf.readUnsignedShort();
-
-      if (!cap(buf, length, length, link, false))
-        // Wait for full packet to arrive
-        return;
-
-      pushDataToPad(TPKT_PAD, buf);
-
-      // TPKT is handled
-      return;
-    }
-
-    //
-    // FastPath
-    //
-    // Number of bytes in updateData field (including header (1+1 or 2
-    // bytes))
-    int length = buf.readVariableUnsignedShort();
-
-    // Length is the size of payload, so we need to calculate from cursor
-    if (!cap(buf, length, length, link, false))
-      // Wait for full packet to arrive
-      return;
-
-    int type = typeAndFlags & 0x3;
-    int securityFlags = (typeAndFlags >> 6) & 0x3;
-
-    // Assertions
-    {
-      if (type != PROTOCOL_FASTPATH)
-        throw new RuntimeException("Unknown protocol. Expected protocol: 0 (FastPath). Actual protocol: " + type + ", data: " + buf + ".");
-
-      switch (securityFlags) {
-      case FASTPATH_OUTPUT_SECURE_CHECKSUM:
-        // TODO
-        throw new RuntimeException("Secure checksum is not supported in FastPath packets.");
-      case FASTPATH_OUTPUT_ENCRYPTED:
-        // TODO
-        throw new RuntimeException("Encryption is not supported in FastPath packets.");
-      }
-    }
-
-    // TODO: optional FIPS information, when FIPS is selected
-    // TODO: optional data signature (checksum), when checksum or FIPS is
-    // selected
-
-    // Array of FastPath update fields
-    while (buf.cursor < buf.length) {
-
-      int updateHeader = buf.readUnsignedByte();
-
-      int size = buf.readUnsignedShortLE();
-
-      int updateCode = updateHeader & 0xf;
-      int fragmentation = (updateHeader >> 4) & 0x3;
-      int compression = (updateHeader >> 6) & 0x3;
-
-      if (verbose)
-        System.out.println("[" + this + "] INFO: FastPath update received. UpdateCode: " + updateCode + ", fragmentation: " + fragmentation + ", compression: "
-            + compression + ", size: " + size + ".");
-
-      ByteBuffer data = buf.readBytes(size);
-      buf.putMetadata("fragmentation", fragmentation);
-      buf.putMetadata("compression", compression);
-
-      switch (updateCode) {
-
-      case FASTPATH_UPDATETYPE_ORDERS:
-        if (verbose)
-          System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_ORDERS.");
-        pushDataToPad(ORDERS_PAD, data);
-        break;
-
-      case FASTPATH_UPDATETYPE_BITMAP:
-        if (verbose)
-          System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_BITMAP.");
-        pushDataToPad(BITMAP_PAD, data);
-        break;
-
-      case FASTPATH_UPDATETYPE_PALETTE:
-        if (verbose)
-          System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PALETTE.");
-        pushDataToPad(PALETTE_PAD, data);
-        break;
-
-      case FASTPATH_UPDATETYPE_SYNCHRONIZE:
-        // @see http://msdn.microsoft.com/en-us/library/cc240625.aspx
-        if (verbose)
-          System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_SYNCHRONIZE.");
-
-        data.unref();
-
-        if (size != 0)
-          throw new RuntimeException("Size of FastPath synchronize packet must be 0. UpdateCode: " + updateCode + ", fragmentation: " + fragmentation
-              + ", compression: " + compression + ", size: " + size + ", data: " + data + ".");
-        break;
-
-      case FASTPATH_UPDATETYPE_SURFCMDS:
-        if (verbose)
-          System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_SURFCMDS.");
-
-        break;
-
-      case FASTPATH_UPDATETYPE_PTR_NULL:
-        if (verbose)
-          System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PTR_NULL.");
-
-        break;
-
-      case FASTPATH_UPDATETYPE_PTR_DEFAULT:
-        if (verbose)
-          System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PTR_DEFAULT.");
-
-        break;
-
-      case FASTPATH_UPDATETYPE_PTR_POSITION:
-        if (verbose)
-          System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PTR_POSITION.");
-
-        break;
-
-      case FASTPATH_UPDATETYPE_COLOR:
-        if (verbose)
-          System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_COLOR.");
-
-        break;
-
-      case FASTPATH_UPDATETYPE_CACHED:
-        if (verbose)
-          System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_CACHED.");
-
-        break;
-
-      case FASTPATH_UPDATETYPE_POINTER:
-        if (verbose)
-          System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_POINTER.");
-
-        break;
-
-      default:
-        throw new RuntimeException("Unknown FastPath update. UpdateCode: " + updateCode + ", fragmentation: " + fragmentation + ", compression: " + compression
-            + ", size: " + size + ", data: " + data + ".");
-
-      }
-
-    }
-
-    buf.unref();
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerLicenseErrorPDUValidClient.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerLicenseErrorPDUValidClient.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerLicenseErrorPDUValidClient.java
deleted file mode 100644
index 194ffe6..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerLicenseErrorPDUValidClient.java
+++ /dev/null
@@ -1,121 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-public class ServerLicenseErrorPDUValidClient extends OneTimeSwitch {
-
-  public ServerLicenseErrorPDUValidClient(String id) {
-    super(id);
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    // Ignore packet
-    buf.unref();
-    switchOff();
-  }
-
-  /* @formatter:off */
-//   * Server Error alert
-//
-//03 00 00 22 02 F0 80 68 00 01 03 EB 70 14 80 00 F1 BC FF 03 10 00 07 00 00 00 02 00 00 00 04 00 00 00
-//
-//
-// Frame: Number = 30, Captured Frame Length = 91, MediaType = DecryptedPayloadHeader
-//+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-// TLSSSLData: Transport Layer Security (TLS) Payload Data
-//+ TLS: TLS Rec Layer-1 SSL Application Data
-// ISOTS: TPKTCount = 1
-//- TPKT: version: 3, Length: 34
-//    version: 3 (0x3)
-//    Reserved: 0 (0x0)
-//    PacketLength: 34 (0x22)
-//- X224: Data
-//    Length: 2 (0x2)
-//    Type: Data
-//    EOT: 128 (0x80)
-//- T125: Data Packet
-// - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
-//  - Type: Send Data Indication
-//    - RootIndex: 26
-//      Value: (011010..) 0x1a
-//  - UserID: 0x3ea
-//    - UserID: 0x3ea
-//    - ChannelId: 1002
-//     - Align: No Padding
-//        Padding2: (00......) 0x0
-//       Value: 1 (0x1)
-//  - Channel: 0x3eb
-//    - ChannelId: 1003
-//      Align: No Padding
-//      Value: 1003 (0x3EB)
-//  - DataPriority: high
-//    - DataPriority: high
-//    - RootIndex: 1
-//       Value: (01......) 0x1
-//  - Segmentation: Begin End
-//     Begin: (1.......) Begin
-//     End:   (.1......) End
-//  - Length: 20
-//    - Align: No Padding
-//      Padding4: (0000....) 0x0
-//     Length: 20
-//    RDP: RDPBCGR
-//- RDPBCGR: RDPELE
-// - SecurityHeader: License Packet
-//  - Flags: 128 (0x80)
-//     SecurityExchange:        (...............0) Not Security Exchange PDU
-//     Reserved1:               (.............00.) Reserved
-//     Encrypted:               (............0...) Not Encrypted packet
-//     ResetSeqNumber:          (...........0....) MUST be ignored.
-//     IgnoreSeqNumber:         (..........0.....) MUST be ignored.
-//     InfoPacket:              (.........0......) Not Client Info PDU
-//     LicensePacket:           (........1.......) License Packet
-//     Reserved2:               (.......0........) Reserved
-//     LicensePacketEncryption: (......0.........) Not License Packet Encryption
-//     ServerRedirectionPacket: (.....0..........) Not Standard Security Server Redirection PDU
-//     ImprovedChecksumForMACG: (....0...........) Not Improved Checksum for MAC Generation
-//     Reserved3:               (.000............) Reserved
-//     FlagsHiValid:            (0...............) FlagsHi should be ignored
-//    FlagsHi: Should be ignored
-//- RDPELE: GM_ERROR_ALERT
-// - TsPreambleHeader: Type = GM_ERROR_ALERT
-//    MsgType: GM_ERROR_ALERT
-//  - Flags: 3 (0x3)
-//     LicenseProtocolVersionMask: (....0011) RDP 5.0, 5.1, 5.2, 6.0, 6.1, and 7.0
-//     Unused:                     (.000....)
-//     ExtendedErrorMSGsupported:  (0.......) that extended error information using the License Error Message is NOT supported.
-//    MsgSize: 16 (0x10)
-// - TsLicenseErrorMessage: ErrorCode = STATUS_VALID_CLIENT
-//    ErrorCode: STATUS_VALID_CLIENT
-//    StateTransition: ST_NO_TRANSITION
-//  - LiceseBinaryBlob: Type = Not Available
-//     RandomData: This value should be ignored
-//     BlobLen: 0 (0x0)
-//
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSAttachUserConfirmPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSAttachUserConfirmPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSAttachUserConfirmPDU.java
deleted file mode 100644
index 8373b83..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSAttachUserConfirmPDU.java
+++ /dev/null
@@ -1,133 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * Server response to MCS Attach User request.
- * 
- * Once the User Channel ID has been extracted, the client MUST send an MCS
- * Channel Join Request PDU for the user channel.
- * 
- * @see http://msdn.microsoft.com/en-us/library/cc240685.aspx
- */
-public class ServerMCSAttachUserConfirmPDU extends OneTimeSwitch {
-
-  public static final int MCS_ATTACH_USER_CONFIRM_PDU = 0xb;
-
-  public static final int INITIATOR_PRESENT = 0x2;
-
-  protected RdpState state;
-
-  public ServerMCSAttachUserConfirmPDU(String id, RdpState state) {
-    super(id);
-    this.state = state;
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    int typeAndFlags = buf.readUnsignedByte();
-    int type = typeAndFlags >> 2;
-    int flags = typeAndFlags & 0x3;
-    
-    if (type != MCS_ATTACH_USER_CONFIRM_PDU)
-      throw new RuntimeException("["+this+"] ERROR: Incorrect type of MCS AttachUserConfirm PDU. Expected value: 11, actual value: " + type + ", data: " + buf + ".");
-
-    if (flags != INITIATOR_PRESENT)
-      throw new RuntimeException("Initator field is not present in MCS AttachUserConfirm PDU. Data: " + buf + ".");
-
-    int rtSuccess = buf.readUnsignedByte() >> 4;
-    if (rtSuccess != 0)
-      throw new RuntimeException("["+this+"] ERROR: Cannot attach user: request failed. Error code: " + rtSuccess + ", data: " + buf + ".");
-
-    // If the initiator field is present, the client stores the value of the
-    // initiator in the User Channel ID store , because the initiator specifies
-    // the User Channel ID.
-    state.serverUserChannelId = buf.readUnsignedShort() + 1001;
-
-    buf.unref();
-
-    // Next: client MCS Channel Join Request PDU (s)
-    switchOff();
-  }
-
-  /**
-   * Example.
-   */
-  /**
-   * Example.
-   * 
-   * @see http://msdn.microsoft.com/en-us/library/cc240842.aspx
-   * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    byte[] packet = new byte[] { (byte) 0x2E, // MCS user confirm (001011..,
-                                              // 0xb), InitiatorPresent: 1
-                                              // (......01, 0x1)
-        (byte) 0x00, // RT successfull (0000...., 0x0)
-        // Initiator: 1001+3 = 1004
-        (byte) 0x00, (byte) 0x03, };
-
-    RdpState rdpState = new RdpState();
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet, new byte[] { 1, 2, 3 }));
-    Element atachUserConfirm = new ServerMCSAttachUserConfirmPDU("attach_user_confirm", rdpState);
-    Element sink = new MockSink("sink");
-    Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, atachUserConfirm, sink, mainSink);
-    pipeline.link("source", "attach_user_confirm", "mainSink");
-    pipeline.link("attach_user_confirm >" + OTOUT, "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-
-    if (rdpState.serverUserChannelId != 1004)
-      System.err.println("Incorrect user channel ID. Expected value: 1004, actual value: " + rdpState.serverUserChannelId + ".");
-  }
-
-}
-
-/*
- * 03 00 00 0B 02 F0 80 2E 00 00 03.
- * 
- * Frame: Number = 18, Captured Frame Length = 68, MediaType =
- * DecryptedPayloadHeader + DecryptedPayloadHeader: FrameCount = 1, ErrorStatus
- * = SUCCESS TLSSSLData: Transport Layer Security (TLS) Payload Data + TLS: TLS
- * Rec Layer-1 SSL Application Data ISOTS: TPKTCount = 1 - TPKT: version: 3,
- * Length: 11 version: 3 (0x3) Reserved: 0 (0x0) PacketLength: 11 (0xB) - X224:
- * Data Length: 2 (0x2) Type: Data EOT: 128 (0x80) - T125: Attach User Confirm,
- * Result = rt-successful, Indicator = 0x3ec - MCSHeader: Type=Attach User
- * Confirm - Type: Attach User Confirm - RootIndex: 11 Value: (001011..) 0xb -
- * MCSAttachUserConfirm: Result = rt-successful, Indicator = 0x3ec
- * InitiatorPresent: 1 (0x1) - Result: rt-successful - Result: rt-successful -
- * RootIndex: 0 Value: (0000....) 0x0 - Initiator: 0x3ec - UserID: 0x3ec -
- * ChannelId: 1004 - Align: No Padding Padding5: (00000...) 0x0 Value: 3 (0x3)
- */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSChannelJoinConfirmPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSChannelJoinConfirmPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSChannelJoinConfirmPDU.java
deleted file mode 100644
index d0a8e81..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSChannelJoinConfirmPDU.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-public class ServerMCSChannelJoinConfirmPDU  extends OneTimeSwitch {
-
-  protected int channel;
-
-  public ServerMCSChannelJoinConfirmPDU(String id, int channel) {
-    super(id);
-    this.channel=channel;
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-    
-    // Ignore packet
-    buf.unref();
-    switchOff();
-  }
-
-}
-
-/*
- * 03 00 00 0F 02 F0 80 3E 00 00 03 03 EC 03 EC 
-
-  Frame: Number = 22, Captured Frame Length = 72, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 15
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 15 (0xF)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: Channel Join Confirm, ChannelId = 1004, Result = rt-successful
-  - MCSHeader: Type=Channel Join Confirm
-   - Type: Channel Join Confirm
-    - RootIndex: 15
-       Value: (001111..) 0xf
-  - MCSChannelJoinConfirm: ChannelId = 1004, Result = rt-successful
-     ChannelIdPresent: 1 (0x1)
-   - Result: rt-successful
-    - Result: rt-successful
-     - RootIndex: 0
-        Value: (0000....) 0x0
-   - Initiator: 0x3ec
-    - UserID: 0x3ec
-     - ChannelId: 1004
-      - Align: No Padding
-         Padding5: (00000...) 0x0
-        Value: 3 (0x3)
-   - Requested: 0x3ec
-    - ChannelId: 1004
-       Align: No Padding
-       Value: 1004 (0x3EC)
-   - ChannelId: 0x3ec
-    - ChannelId: 1004
-       Align: No Padding
-       Value: 1004 (0x3EC)
- 
- */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSConnectResponse.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSConnectResponse.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSConnectResponse.java
deleted file mode 100644
index 30b196b..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSConnectResponse.java
+++ /dev/null
@@ -1,283 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-/**
- * Once the basic server settings data blocks have been processed successfully, the client MUST send the MCS Attach User Request PDU to the server.
- * 
- * @see http://msdn.microsoft.com/en-us/library/cc240682.aspx
- */
-public class ServerMCSConnectResponse  extends OneTimeSwitch {
-
-  public ServerMCSConnectResponse(String id) {
-    super(id);
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-    
-    // Ignore packet
-    buf.unref();
-    switchOff();
-  }
-
-}
-
-/*
- * @formatter:off
- * 03 00 00 64 02 F0 80 7F 66 5A 0A 01 00 02 01 00 30 1A 02 01 22 02 01 03 02 01 00 02 01 01 02 01 00 02 01 01 02 03 00 FF F8 02 01 02 04 36 00 05 00 14 7C 00 01 2A 14 76 0A 01 01 00 01 C0 00 4D 63 44 6E 20 01 0C 0C 00 04 00 08 00 01 00 00 00 03 0C 08 00 EB 03 00 00 02 0C 0C 00 00 00 00 00 00 00 00 00 
-
-  Frame: Number = 12, Captured Frame Length = 157, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 100
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 100 (0x64)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: MCSConnect Response
-  - MCSConnectResponse: Result = rt-successful
-   - ConnectResponseHeader: 
-    - AsnId: Application Constructed Tag (102)
-     - HighTag: 
-        Class:     (01......) Application (1)
-        Type:      (..1.....) Constructed
-        TagNumber: (...11111)
-        TagValueEnd: 102 (0x66)
-    - AsnLen: Length = 90, LengthOfLength = 0
-       Length: 90 bytes, LengthOfLength = 0
-   - Result: rt-successful
-    - Value: 0
-     - AsnIntegerHeader: 
-      - AsnId: Enumerated type (Universal 10)
-       - LowTag: 
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...01010) 10
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 0 (0x0)
-   - CalledConnectId: 0
-    - AsnIntegerHeader: 
-     - AsnId: Integer type (Universal 2)
-      - LowTag: 
-         Class:    (00......) Universal (0)
-         Type:     (..0.....) Primitive
-         TagValue: (...00010) 2
-     - AsnLen: Length = 1, LengthOfLength = 0
-        Length: 1 bytes, LengthOfLength = 0
-      AsnInt: 0 (0x0)
-   - DomainParameters: Length = 26, LengthOfLength = 0
-    - DomainParametersHeader: 0x1
-     - AsnId: Sequence and SequenceOf types (Universal 16)
-      - LowTag: 
-         Class:    (00......) Universal (0)
-         Type:     (..1.....) Constructed
-         TagValue: (...10000) 16
-     - AsnLen: Length = 26, LengthOfLength = 0
-        Length: 26 bytes, LengthOfLength = 0
-    - ChannelIds: 34
-     - AsnIntegerHeader: 
-      - AsnId: Integer type (Universal 2)
-       - LowTag: 
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 34 (0x22)
-    - UserIDs: 3
-     - AsnIntegerHeader: 
-      - AsnId: Integer type (Universal 2)
-       - LowTag: 
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 3 (0x3)
-    - TokenIds: 0
-     - AsnIntegerHeader: 
-      - AsnId: Integer type (Universal 2)
-       - LowTag: 
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 0 (0x0)
-    - NumPriorities: 1
-     - AsnIntegerHeader: 
-      - AsnId: Integer type (Universal 2)
-       - LowTag: 
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 1 (0x1)
-    - MinThroughput: 0
-     - AsnIntegerHeader: 
-      - AsnId: Integer type (Universal 2)
-       - LowTag: 
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 0 (0x0)
-    - Height: 1
-     - AsnIntegerHeader: 
-      - AsnId: Integer type (Universal 2)
-       - LowTag: 
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 1 (0x1)
-    - MCSPDUsize: 65528
-     - AsnIntegerHeader: 
-      - AsnId: Integer type (Universal 2)
-       - LowTag: 
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 3, LengthOfLength = 0
-         Length: 3 bytes, LengthOfLength = 0
-       AsnInt: 65528 (0xFFF8)
-    - protocolVersion: 2
-     - AsnIntegerHeader: 
-      - AsnId: Integer type (Universal 2)
-       - LowTag: 
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 2 (0x2)
-   - UserData: Identifier = Generic Conference Contro (0.0.20.124.0.1)
-    - UserDataHeader: 
-     - AsnId: OctetString type (Universal 4)
-      - LowTag: 
-         Class:    (00......) Universal (0)
-         Type:     (..0.....) Primitive
-         TagValue: (...00100) 4
-     - AsnLen: Length = 54, LengthOfLength = 0
-        Length: 54 bytes, LengthOfLength = 0
-    - AsnBerObjectIdentifier: Generic Conference Contro (0.0.20.124.0.1)
-     - AsnObjectIdentifierHeader: 
-      - AsnId: Reserved for use by the encoding rules (Universal 0)
-       - LowTag: 
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00000) 0
-      - AsnLen: Length = 5, LengthOfLength = 0
-         Length: 5 bytes, LengthOfLength = 0
-       First: 0 (0x0)
-       Final: 20 (0x14)
-       Final: 124 (0x7C)
-       Final: 0 (0x0)
-       Final: 1 (0x1)
-    - ConnectPDULength: 42
-       Align: No Padding
-       Length: 42
-    - ConnectGCCPDU: conferenceCreateResponse
-       ExtensionBit: 0 (0x0)
-     - ChoiceValue: conferenceCreateResponse
-        Value: (001.....) 0x1
-     - conferenceCreateResponse: 
-        ExtensionBit: 0 (0x0)
-        userDataPresent: 1 (0x1)
-      - nodeID: 0x79f3
-       - UserID: 31219
-        - Align: No Padding
-           Padding2: (00......) 0x0
-          Value: 30218 (0x760A)
-      - tag: 1 (0x1)
-       - Length: 1
-          Align: No Padding
-          Length: 1
-         Value: 1 (0x1)
-      - result: success
-         ExtensionBit: 0 (0x0)
-       - RootIndex: 0
-          Value: (000.....) 0x0
-      - userData: 
-       - Size: 1
-        - Align: No Padding
-           Padding4: (0000....) 0x0
-          Length: 1
-       - UserData: 0x4d63446e
-          valuePresent: 1 (0x1)
-        - key: h221NonStandard
-         - ChoiceValue: h221NonStandard
-            Value: (1.......) 0x1
-         - h221NonStandard: 
-          - H221NonStandardIdentifier: length: 4
-           - ConstrainedLength: 4
-              Value: (00000000) 0x0
-           - Align: No Padding
-              Padding6: (000000..) 0x0
-             Value: Binary Large Object (4 Bytes)
-        - ServerMcsConnectResponsePdu: 
-         - RDPGCCUserDataResponseLength: 32
-            Align: No Padding
-            Length: 32
-         - TsUd: SC_CORE
-          - TsUdHeader: Type = SC_CORE, Length = 12
-             Type: SC_CORE
-             Length: 12 (0xC)
-          - TsUdScCore: 
-             Version: RDP 5.0, 5.1, 5.2, 6.0, 6.1, and 7.0 
-             ClientRequestedProtocols: TLS 1.0
-         - TsUd: SC_NET
-          - TsUdHeader: Type = SC_NET, Length = 8
-             Type: SC_NET
-             Length: 8 (0x8)
-          - TsUdScNet: 
-             MCSChannelID: 1003 (0x3EB)
-             ChannelCount: 0 (0x0)
-             Pad: 0 Bytes
-         - TsUd: SC_SECURITY
-          - TsUdHeader: Type = SC_SECURITY, Length = 12
-             Type: SC_SECURITY
-             Length: 12 (0xC)
-          - TsUdSCSec1: 
-           - EncryptionMethod: 
-              Support40Bit:  (...............................0) Not Support 
-              Support128Bit: (..............................0.) Not Support 128-bit
-              Reserved1:     (.............................0..)
-              Support56Bit:  (............................0...) Not Support 56-bit
-              SupportFIPS:   (...........................0....) Not Support FIPS Compliant
-              Reserved2:     (000000000000000000000000000.....)
-             EncryptionLevel: TS_ENCRYPTION_NONE
- */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSPDU.java
deleted file mode 100644
index 5862e19..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSPDU.java
+++ /dev/null
@@ -1,149 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class ServerMCSPDU extends BaseElement {
-
-  public ServerMCSPDU(String id) {
-    super(id);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    byte headerByte = buf.readSignedByte();
-    int type = headerByte >> 2;
-
-    switch (type) {
-    // Expected type: send data indication: 26 (0x1a, top 6 bits, or 0x68)
-    case 0x1a: {
-      // int userId = buf.readUnsignedShort() + 1001; // User ID: 1002 (1001+1)
-      buf.skipBytes(2); // Ignore user ID
-
-      int channelId = buf.readUnsignedShort(); // Channel ID: 1003
-
-      int flags = buf.readSignedByte();
-      if ((flags & 0x30) != 0x30)
-        throw new RuntimeException("Fragmented MCS packets are not supported.");
-
-      int payloadLength = buf.readVariableUnsignedShort();
-
-      ByteBuffer data = buf.readBytes(payloadLength);
-
-      buf.unref();
-
-      pushDataToPad("channel_" + channelId, data);
-      break;
-    }
-
-    case 0x8: {
-      // Disconnection sequence.
-      buf.unref();
-      break;
-    }
-
-    default:
-      throw new RuntimeException("Unsupported MCS packet type: " + type + "(" + headerByte + "), data: " + buf + ".");
-    }
-
-  }
-
-  /**
-   * Example.
-   * 
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    // System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    byte[] packet = new byte[] {
-        // TPKT
-        (byte) 0x03, (byte) 0x00, // TPKT Header: TPKT version = 3
-        (byte) 0x00, (byte) 0x1B, // TPKT length: 27 bytes
-
-        // X224
-        (byte) 0x02, // X224 Length: 2 bytes
-        (byte) 0xF0, // X224 Type: Data
-        (byte) 0x80, // X224 EOT
-
-        // MCS
-        // Type: send data indication: 26 (0x1a, top 6 bits)
-        (byte) 0x68, // ??
-
-        (byte) 0x00, (byte) 0x01, // User ID: 1002 (1001+1)
-        (byte) 0x03, (byte) 0xEB, // Channel ID: 1003
-        (byte) 0x70, // Data priority: high, segmentation: begin|end
-        (byte) 0x0D, // Payload length: 13 bytes
-
-        // Deactivate all PDU
-        (byte) 0x0D, (byte) 0x00, // Length: 13 bytes (LE)
-
-        // - PDUType: 22 (0x16, LE)
-        // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
-        // ProtocolVersion: (000000000001....) 1
-        (byte) 0x16, (byte) 0x00,
-
-        (byte) 0xEA, (byte) 0x03, // PDU source: 1002 (LE)
-        (byte) 0xEA, (byte) 0x03, (byte) 0x01, (byte) 0x00, // ShareID = 66538
-
-        (byte) 0x01, (byte) 0x00, // Length if source descriptor: 1 (LE)
-        (byte) 0x00, // Source descriptor (should be set to 0): 0
-    };
-
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
-    Element mcs = new ServerMCSPDU("mcs") {
-      {
-        verbose = true;
-      }
-    };
-    Element tpkt = new ServerTpkt("tpkt");
-    Element x224 = new ServerX224DataPdu("x224");
-    Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
-        // Deactivate all PDU
-        (byte) 0x0D, (byte) 0x00, // Length: 13 bytes (LE)
-
-        // - PDUType: 22 (0x16, LE)
-        // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
-        // ProtocolVersion: (000000000001....) 1
-        (byte) 0x16, (byte) 0x00,
-
-        (byte) 0xEA, (byte) 0x03, // PDU source: 1002 (LE)
-        (byte) 0xEA, (byte) 0x03, (byte) 0x01, (byte) 0x00, // ShareID = 66538
-
-        (byte) 0x01, (byte) 0x00, // Length if source descriptor: 1 (LE)
-        (byte) 0x00, // Source descriptor (should be set to 0): 0
-    }));
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, tpkt, x224, mcs, sink);
-    pipeline.link("source", "tpkt", "x224", "mcs >channel_1003", "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPacketSniffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPacketSniffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPacketSniffer.java
deleted file mode 100644
index 8c39a02..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPacketSniffer.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-
-/**
- * Try to determine packet content by it header fingerprint.
- */
-public class ServerPacketSniffer extends PacketSniffer {
-
-  private static final Pair[] serverRegexps = new Pair[] {
-  // @formatter:off
-  new Pair("Server FastPath update",             "04"),
-  new Pair("Server X224ConnectionRequest",       "03 00 XX XX 0E D0"), 
-  new Pair("Server MCSConnectResponse",          "03 00 XX XX 02 F0 80 7F 66 5A"), 
-  new Pair("Server AttachUserConfirm",           "03 00 XX XX 02 F0 80 2E"),
-  new Pair("Server ChannelJoinConfirm",          "03 00 XX XX 02 F0 80 3E"),
-  new Pair("Server ErrorAlert",                  "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 14 80 00"),
-  new Pair("Server DemandActivePDU",             "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX XX 11"),
-  new Pair("Server ControlPDU",                  "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 17 00 EA 03 EA 03 XX 00 XX XX XX XX 14"),
-  new Pair("Server SynchronizePDU",              "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 17 00 EA 03 EA 03 XX 00 XX XX XX XX 1F"),
-  new Pair("Server FontMapPDU",                  "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 17 00 EA 03 EA 03 XX 00 XX XX XX XX 28"),
-  new Pair("Server SET_ERROR_INFO_PDU",          "03 00 XX XX 02 F0 80 68 00 01 03 EB 30 XX XX XX 17 00 00 00 EA 03 XX 00 XX XX XX XX 2F"),
-  new Pair("Server DeactivateAllPDU",            "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 16 00"),
-  new Pair("Server CloseConnection",             "03 00 00 09 02 F0 80 21 80"),
-  
-//  new Pair("Server TPKT unknown packet",         "03"),
-//  new Pair("Server FastPath update with flags or continuation",  ".*"),
-  // @formatter:on
-
-  };
-
-  public ServerPacketSniffer(String id) {
-    super(id, serverRegexps);
-  }
-
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPaletteUpdate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPaletteUpdate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPaletteUpdate.java
deleted file mode 100644
index 3b0762e..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPaletteUpdate.java
+++ /dev/null
@@ -1,78 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import java.awt.image.IndexColorModel;
-
-import common.ScreenDescription;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240623.aspx
- */
-public class ServerPaletteUpdate extends BaseElement {
-
-  public static final int UPDATETYPE_PALETTE = 0x0002;
-  protected ScreenDescription screen;
-
-  public ServerPaletteUpdate(String id, ScreenDescription screen) {
-    super(id);
-    this.screen = screen;
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    // (2 bytes): A 16-bit, unsigned integer. The update type. This field MUST
-    // be set to UPDATETYPE_PALETTE (0x0002).
-    int updateType = buf.readUnsignedShortLE();
-    if (updateType != UPDATETYPE_PALETTE)
-      throw new RuntimeException("Unexpected update type. Expected type: UPDATETYPE_PALETTE (0x0002), actual value: " + updateType + ", data: " + buf + ".");
-
-    // pad2Octets (2 bytes): A 16-bit, unsigned integer. Padding. Values in this
-    // field MUST be ignored.
-    buf.skipBytes(2);
-
-    // (4 bytes): A 32-bit, unsigned integer. The number of RGB triplets in the
-    // paletteData field. This field MUST be set to 256 (the number of entries
-    // in an 8 bpp palette).
-    int numberColors = (int) buf.readUnsignedIntLE();
-    if (numberColors != 256)
-      throw new RuntimeException("Unexpected value for number of color field in server Palette Update packet. Expected value: 256 colors, actual value: "
-          + numberColors + ", data: " + buf + ".");
-
-    // (variable): An array of palette entries in RGB triplet format packed on
-    // byte boundaries. The number of triplet entries is given by the
-    // numberColors field.
-    ByteBuffer paletteEntries = buf.readBytes(numberColors * 3);
-
-    // In the case of a Palette Update, the client MUST update the global
-    // palette on all drawing surfaces
-    screen.colorMap = new IndexColorModel(8, numberColors, paletteEntries.data, paletteEntries.offset, false);
-
-    /* DEBUG */buf.assertThatBufferIsFullyRead();
-
-    buf.unref();
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerSynchronizePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerSynchronizePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerSynchronizePDU.java
deleted file mode 100644
index 315fbfe..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerSynchronizePDU.java
+++ /dev/null
@@ -1,115 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-public class ServerSynchronizePDU  extends OneTimeSwitch {
-
-  public ServerSynchronizePDU(String id) {
-    super(id);
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-    
-    // Ignore packet
-    buf.unref();
-    switchOff();
-  }
-
-}
-
-/* @formatter:off */
-/*
-
- * 03 00 00 24 02 F0 80 68 00 01 03 EB 70 16 16 00 17 00 EA 03 EA 03 01 00 08 00 16 00 1F 00 00 00 01 00 86 A4 
-
-  Frame: Number = 36, Captured Frame Length = 93, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 36
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 36 (0x24)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: Data Packet
-  - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
-   - Type: Send Data Indication
-    - RootIndex: 26
-       Value: (011010..) 0x1a
-   - UserID: 0x3ea
-    - UserID: 0x3ea
-     - ChannelId: 1002
-      - Align: No Padding
-         Padding2: (00......) 0x0
-        Value: 1 (0x1)
-   - Channel: 0x3eb
-    - ChannelId: 1003
-       Align: No Padding
-       Value: 1003 (0x3EB)
-   - DataPriority: high
-    - DataPriority: high
-     - RootIndex: 1
-        Value: (01......) 0x1
-   - Segmentation: Begin End
-      Begin: (1.......) Begin
-      End:   (.1......) End
-   - Length: 22
-    - Align: No Padding
-       Padding4: (0000....) 0x0
-      Length: 22
-    RDP: RDPBCGR
-- RDPBCGR: SynchronizePDU
-  - SlowPathPacket: SynchronizePDU 
-   - SlowPath: Type = TS_PDUTYPE_DATAPDU
-    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
-       TotalLength: 22 (0x16)
-     - PDUType: 23 (0x17)
-        Type:            (............0111) TS_PDUTYPE_DATAPDU
-        ProtocolVersion: (000000000001....) 1
-       PDUSource: 1002 (0x3EA)
-    - SlowPathIoPacket: 0x0
-     - ShareDataHeader: TS_PDUTYPE2_SYNCHRONIZE
-        ShareID: 66538 (0x103EA)
-        Pad1: 8 (0x8)
-        StreamID: STREAM_UNDEFINED
-        UncompressedLength: 22 (0x16)
-        PDUType2: TS_PDUTYPE2_SYNCHRONIZE
-      - CompressedType: Not Compressed
-         MPPC:       (....0000) MPPC 8K
-         Reserved:   (...0....)
-         Compressed: (..0.....) Not Compressed
-         Front:      (.0......) Not At Front
-         Flush:      (0.......) Not Flushed
-        CompressedLength: 0 (0x0)
-     - TsSynchronizePDU: 0x1
-        MessageType: 0x1, MUST be set to SYNCMSGTYPE_SYNC (1)
-        TargetUser: 42118 (0xA486)
- */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerTpkt.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerTpkt.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerTpkt.java
deleted file mode 100644
index 0d19fa4..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerTpkt.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-public class ServerTpkt extends BaseElement {
-
-  /**
-   * TPKT protocol version (first byte).
-   */
-  public static final int PROTOCOL_TPKT = 3;
-  
-  public ServerTpkt(String id) {
-    super(id);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    // We need at least 4 bytes to get packet length
-    if(!cap(buf, 4, UNLIMITED, link, false))
-      return;
-
-    int version = buf.readUnsignedByte();
-    if (version != PROTOCOL_TPKT)
-      throw new RuntimeException("Unexpected data in TPKT header. Expected TPKT version: 0x03,  actual value: " + buf + ".");
-
-    buf.skipBytes(1); // Reserved byte
-
-    // Length of whole packet, including header
-    int length = buf.readUnsignedShort();
-    if(!cap(buf, length, length, link, false))
-      return;
-
-    int payloadLength = length - buf.cursor;
-
-    // Extract payload
-    ByteBuffer outBuf = buf.slice(buf.cursor, payloadLength, true);
-    buf.unref();
-    
-    if(verbose) {
-      outBuf.putMetadata("source", this);
-    }
-
-    pushDataToAllOuts(outBuf);
-  }
-
-}


[02/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
new file mode 100755
index 0000000..5dfa831
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
@@ -0,0 +1,63 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 vncclient.vnc;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class EncodingsMessage extends BaseElement {
+
+    protected final int[] encodings;
+
+    public EncodingsMessage(String id, int[] encodings) {
+        super(id);
+        this.encodings = encodings;
+        declarePads();
+    }
+
+    protected void declarePads() {
+        inputPads.put(STDIN, null);
+        outputPads.put(STDOUT, null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+        buf.unref();
+
+        ByteBuffer outBuf = new ByteBuffer(4 + encodings.length * 4);
+
+        outBuf.writeByte(RfbConstants.CLIENT_SET_ENCODINGS);
+
+        outBuf.writeByte(0);// padding
+
+        outBuf.writeShort(encodings.length);
+
+        for (int i = 0; i < encodings.length; i++) {
+            outBuf.writeInt(encodings[i]);
+        }
+
+        pushDataToAllOuts(outBuf);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
new file mode 100755
index 0000000..446aa54
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
@@ -0,0 +1,127 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 vncclient.vnc;
+
+import common.ScreenDescription;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class FrameBufferUpdateRequest extends BaseElement {
+    // TODO: use object with fields instead of raw values in map
+    public static final String INCREMENTAL_UPDATE = "incremental";
+    public static final String TARGET_X = "x";
+    public static final String TARGET_Y = "y";
+    public static final String WIDTH = "width";
+    public static final String HEIGHT = "height";
+
+    protected ScreenDescription screen;
+
+    public FrameBufferUpdateRequest(String id, ScreenDescription screen) {
+        super(id);
+        this.screen = screen;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        Boolean incremental = (Boolean)buf.getMetadata(INCREMENTAL_UPDATE);
+        Integer x = (Integer)buf.getMetadata(TARGET_X);
+        Integer y = (Integer)buf.getMetadata(TARGET_Y);
+        Integer width = (Integer)buf.getMetadata(WIDTH);
+        Integer height = (Integer)buf.getMetadata(HEIGHT);
+        buf.unref();
+
+        // Set default values when parameters are not set
+        if (incremental == null)
+            incremental = false;
+
+        if (x == null)
+            x = 0;
+        if (y == null)
+            y = 0;
+
+        if (width == null)
+            width = screen.getFramebufferWidth();
+        if (height == null)
+            height = screen.getFramebufferHeight();
+
+        ByteBuffer outBuf = new ByteBuffer(10);
+
+        outBuf.writeByte(RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST);
+        outBuf.writeByte((incremental) ? RfbConstants.FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST : RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST);
+        outBuf.writeShort(x);
+        outBuf.writeShort(y);
+        outBuf.writeShort(width);
+        outBuf.writeShort(height);
+
+        if (verbose) {
+            outBuf.putMetadata("sender", this);
+            outBuf.putMetadata("dimensions", width + "x" + height + "@" + x + "x" + y);
+        }
+
+        pushDataToAllOuts(outBuf);
+    }
+
+    public static void main(String args[]) {
+        System.setProperty("streamer.Element.debug", "true");
+
+        ScreenDescription screen = new ScreenDescription();
+        screen.setFramebufferSize(120, 80);
+        Element adapter = new FrameBufferUpdateRequest("renderer", screen);
+
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
+                // Request
+                RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST,
+                // Full update (redraw area)
+                RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST,
+                // X
+                0, 1,
+                // Y
+                0, 2,
+                // Width
+                0, 3,
+                // Height
+                0, 4}));
+
+        ByteBuffer buf = new ByteBuffer(new byte[0]);
+        buf.putMetadata(TARGET_X, 1);
+        buf.putMetadata(TARGET_Y, 2);
+        buf.putMetadata(WIDTH, 3);
+        buf.putMetadata(HEIGHT, 4);
+
+        Element source = new MockSource("source", new ByteBuffer[] {buf});
+
+        Pipeline pipeline = new PipelineImpl("test");
+
+        pipeline.addAndLink(source, adapter, sink);
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
new file mode 100755
index 0000000..d534f82
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
@@ -0,0 +1,90 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 vncclient.vnc;
+
+import common.ScreenDescription;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class RGB888LE32PixelFormatRequest extends BaseElement {
+    protected int bitsPerPixel = 32;
+    protected int depth = 24;
+    protected int bigEndianFlag = RfbConstants.LITTLE_ENDIAN;
+    protected int trueColourFlag = RfbConstants.TRUE_COLOR;
+    protected int redMax = 255;
+    protected int greenMax = 255;
+    protected int blueMax = 255;
+    protected int redShift = 0;
+    protected int greenShift = 8;
+    protected int blueShift = 16;
+
+    protected ScreenDescription screen;
+
+    public RGB888LE32PixelFormatRequest(String id, ScreenDescription screen) {
+        super(id);
+        this.screen = screen;
+    }
+
+    protected void declarePads() {
+        inputPads.put(STDIN, null);
+        outputPads.put(STDOUT, null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+        buf.unref();
+
+        ByteBuffer outBuf = new ByteBuffer(20);
+
+        outBuf.writeByte(RfbConstants.CLIENT_SET_PIXEL_FORMAT);
+
+        // Padding
+        outBuf.writeByte(0);
+        outBuf.writeByte(0);
+        outBuf.writeByte(0);
+
+        // Send pixel format
+        outBuf.writeByte(bitsPerPixel);
+        outBuf.writeByte(depth);
+        outBuf.writeByte(bigEndianFlag);
+        outBuf.writeByte(trueColourFlag);
+        outBuf.writeShort(redMax);
+        outBuf.writeShort(greenMax);
+        outBuf.writeShort(blueMax);
+        outBuf.writeByte(redShift);
+        outBuf.writeByte(greenShift);
+        outBuf.writeByte(blueShift);
+
+        // Padding
+        outBuf.writeByte(0);
+        outBuf.writeByte(0);
+        outBuf.writeByte(0);
+
+        screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag != RfbConstants.LITTLE_ENDIAN, trueColourFlag == RfbConstants.TRUE_COLOR, redMax, greenMax,
+                blueMax, redShift, greenShift, blueShift);
+
+        pushDataToAllOuts(outBuf);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
new file mode 100755
index 0000000..a3895d4
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
@@ -0,0 +1,85 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 vncclient.vnc;
+
+import java.nio.charset.Charset;
+
+public interface RfbConstants {
+
+    public static final String RFB_PROTOCOL_VERSION_MAJOR = "RFB 003.";
+    public static final String VNC_PROTOCOL_VERSION_MINOR = "003";
+    public static final String RFB_PROTOCOL_VERSION = RFB_PROTOCOL_VERSION_MAJOR + VNC_PROTOCOL_VERSION_MINOR;
+
+    /**
+     * Server message types.
+     */
+    final static int SERVER_FRAMEBUFFER_UPDATE = 0, SERVER_SET_COLOURMAP_ENTRIES = 1, SERVER_BELL = 2, SERVER_CUT_TEXT = 3;
+
+    /**
+     * Client message types.
+     */
+    public static final int CLIENT_SET_PIXEL_FORMAT = 0, CLIENT_FIX_COLOURMAP_ENTRIES = 1, CLIENT_SET_ENCODINGS = 2, CLIENT_FRAMEBUFFER_UPDATE_REQUEST = 3,
+            CLIENT_KEYBOARD_EVENT = 4, CLIENT_POINTER_EVENT = 5, CLIENT_CUT_TEXT = 6;
+
+    /**
+     * Server authorization type
+     */
+    public final static int CONNECTION_FAILED = 0, NO_AUTH = 1, VNC_AUTH = 2;
+
+    /**
+     * Server authorization reply.
+     */
+    public final static int VNC_AUTH_OK = 0, VNC_AUTH_FAILED = 1, VNC_AUTH_TOO_MANY = 2;
+
+    /**
+     * Encodings.
+     */
+    public final static int ENCODING_RAW = 0, ENCODING_COPY_RECT = 1, ENCODING_RRE = 2, ENCODING_CO_RRE = 4, ENCODING_HEXTILE = 5, ENCODING_ZRLE = 16;
+
+    /**
+     * Pseudo-encodings.
+     */
+    public final static int ENCODING_CURSOR = -239 /*0xFFFFFF11*/, ENCODING_DESKTOP_SIZE = -223 /*0xFFFFFF21*/;
+
+    /**
+     * Encodings, which we support.
+     */
+    public final static int[] SUPPORTED_ENCODINGS_ARRAY = {ENCODING_RAW, ENCODING_COPY_RECT, ENCODING_DESKTOP_SIZE};
+
+    /**
+     * Frame buffer update request type: update of whole screen or partial update.
+     */
+    public static final int FRAMEBUFFER_FULL_UPDATE_REQUEST = 0, FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST = 1;
+
+    public static final int KEY_UP = 0, KEY_DOWN = 1;
+
+    public static final int LITTLE_ENDIAN = 0, BIG_ENDIAN = 1;
+
+    public static final int EXCLUSIVE_ACCESS = 0, SHARED_ACCESS = 1;
+
+    public static final int PALETTE = 0, TRUE_COLOR = 1;
+
+    /**
+     * Default 8 bit charset to use when communicating with server.
+     */
+    public static final Charset US_ASCII_CHARSET = Charset.availableCharsets().get("US-ASCII");
+
+    /**
+     * Default 16 bit charset to use when communicating with server.
+     */
+    public static final Charset UCS2_CHARSET = Charset.availableCharsets().get("UTF-16LE");
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
new file mode 100755
index 0000000..b3bd176
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
@@ -0,0 +1,245 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 vncclient.vnc;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+import common.ScreenDescription;
+
+public class VncInitializer extends OneTimeSwitch {
+
+    // Pad names
+    public static final String CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD = "encodings";
+    public static final String CLIENT_PIXEL_FORMAT_ADAPTER_PAD = "pixel_format";
+
+    protected byte sharedFlag = RfbConstants.EXCLUSIVE_ACCESS;
+
+    /**
+     * Properties of remote screen .
+     */
+    protected ScreenDescription screen;
+
+    public VncInitializer(String id, boolean shared, ScreenDescription screen) {
+        super(id);
+
+        setSharedFlag(shared);
+        this.screen = screen;
+
+        declarePads();
+    }
+
+    @Override
+    protected void declarePads() {
+        super.declarePads();
+        outputPads.put(CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, null);
+        outputPads.put(CLIENT_PIXEL_FORMAT_ADAPTER_PAD, null);
+    }
+
+    public ScreenDescription getScreen() {
+        return screen;
+    }
+
+    public void setScreen(ScreenDescription screen) {
+        this.screen = screen;
+    }
+
+    public void setSharedFlag(boolean shared) {
+        if (shared)
+            sharedFlag = RfbConstants.SHARED_ACCESS;
+        else
+            sharedFlag = RfbConstants.EXCLUSIVE_ACCESS;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Server initialization message is at least 24 bytes long + length of
+        // desktop name
+        if (!cap(buf, 24, UNLIMITED, link, false))
+            return;
+
+        // Read server initialization message
+        // Read frame buffer size
+        int framebufferWidth = buf.readUnsignedShort();
+        int framebufferHeight = buf.readUnsignedShort();
+
+        // Read pixel format
+        int bitsPerPixel = buf.readUnsignedByte();
+        int depth = buf.readUnsignedByte();
+
+        int bigEndianFlag = buf.readUnsignedByte();
+        int trueColorFlag = buf.readUnsignedByte();
+
+        int redMax = buf.readUnsignedShort();
+        int greenMax = buf.readUnsignedShort();
+        int blueMax = buf.readUnsignedShort();
+
+        int redShift = buf.readUnsignedByte();
+        int greenShift = buf.readUnsignedByte();
+        int blueShift = buf.readUnsignedByte();
+
+        // Skip padding
+        buf.skipBytes(3);
+
+        // Read desktop name
+        int length = buf.readSignedInt();
+
+        // Consume exactly $length bytes, push back any extra bytes
+        if (!cap(buf, length, length, link, true))
+            return;
+
+        String desktopName = buf.readString(length, RfbConstants.US_ASCII_CHARSET);
+        buf.unref();
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Desktop name: \"" + desktopName + "\", bpp: " + bitsPerPixel + ", depth: " + depth + ", screen size: "
+                    + framebufferWidth + "x" + framebufferHeight + ".");
+
+        // Set screen properties
+        screen.setFramebufferSize(framebufferWidth, framebufferHeight);
+        screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag != RfbConstants.LITTLE_ENDIAN, trueColorFlag == RfbConstants.TRUE_COLOR, redMax, greenMax, blueMax, redShift,
+                greenShift, blueShift);
+        screen.setDesktopName(desktopName);
+
+        // If sever screen has different parameters than ours, then change it
+        if (!screen.isRGB888_32_LE()) {
+            // Send client pixel format
+            sendClientPixelFormat();
+        }
+
+        // Send encodings supported by client
+        sendSupportedEncodings();
+
+        switchOff();
+
+    }
+
+    @Override
+    protected void onStart() {
+        ByteBuffer buf = new ByteBuffer(new byte[] {sharedFlag});
+        pushDataToOTOut(buf);
+    }
+
+    private void sendClientPixelFormat() {
+        pushDataToPad(CLIENT_PIXEL_FORMAT_ADAPTER_PAD, new ByteBuffer(0));
+    }
+
+    private void sendSupportedEncodings() {
+        pushDataToPad(CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, new ByteBuffer(0));
+    }
+
+    public String toString() {
+        return "VncInit(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        final String desktopName = "test";
+
+        Element source = new MockSource("source") {
+            {
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(
+                        // Send screen description
+                        new byte[] {
+                                // Framebuffer width (short)
+                                0, (byte)200,
+                                // Framebuffer height (short)
+                                0, 100,
+                                // Bits per pixel
+                                32,
+                                // Depth,
+                                24,
+                                // Endianness flag
+                                RfbConstants.LITTLE_ENDIAN,
+                                // Truecolor flag
+                                RfbConstants.TRUE_COLOR,
+                                // Red max (short)
+                                0, (byte)255,
+                                // Green max (short)
+                                0, (byte)255,
+                                // Blue max (short)
+                                0, (byte)255,
+                                // Red shift
+                                16,
+                                // Green shift
+                                8,
+                                // Blue shift
+                                0,
+                                // Padding
+                                0, 0, 0,
+                                // Desktop name length (int)
+                                0, 0, 0, 4,
+                                // Desktop name ("test", 4 bytes)
+                                't', 'e', 's', 't',
+
+                                // Tail
+                                1, 2, 3
+
+                        },
+                        // Tail packet
+                        new byte[] {4, 5, 6});
+            }
+        };
+
+        ScreenDescription screen = new ScreenDescription();
+        final VncInitializer init = new VncInitializer("init", true, screen);
+        Element initSink = new MockSink("initSink") {
+            {
+                // Expect shared flag
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {RfbConstants.SHARED_ACCESS});
+            }
+        };
+        Element mainSink = new MockSink("mainSink") {
+            {
+                // Expect two tail packets
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}, new byte[] {4, 5, 6});
+            }
+        };
+        ByteBuffer[] emptyBuf = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {});
+        Element encodingsSink = new MockSink("encodings", emptyBuf);
+        Element pixelFormatSink = new MockSink("pixel_format", emptyBuf);
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.addAndLink(source, init, mainSink);
+        pipeline.add(encodingsSink, pixelFormatSink, initSink);
+        pipeline.link("init >otout", "initSink");
+        pipeline.link("init >" + CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, "encodings");
+        pipeline.link("init >" + CLIENT_PIXEL_FORMAT_ADAPTER_PAD, "pixel_format");
+
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        if (!screen.isRGB888_32_LE())
+            System.err.println("Screen description was read incorrectly: " + screen + ".");
+        if (!desktopName.equals(screen.getDesktopName()))
+            System.err.println("Screen desktop name was read incorrectly: \"" + screen.getDesktopName() + "\".");
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java
new file mode 100755
index 0000000..845ed3a
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java
@@ -0,0 +1,419 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 vncclient.vnc;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+import common.BitmapOrder;
+import common.BitmapRectangle;
+import common.CopyRectOrder;
+import common.ScreenDescription;
+import common.adapter.AwtClipboardAdapter;
+
+public class VncMessageHandler extends BaseElement {
+    protected ScreenDescription screen = null;
+
+    // Pad names
+    public static final String SERVER_BELL_ADAPTER_PAD = "bell";
+    public static final String SERVER_CLIPBOARD_ADAPTER_PAD = "clipboard";
+    public static final String PIXEL_ADAPTER_PAD = "pixels";
+    public static final String FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD = "fbur";
+
+    // Keys for metadata
+    public static final String TARGET_X = "x";
+    public static final String TARGET_Y = "y";
+    public static final String WIDTH = "width";
+    public static final String HEIGHT = "height";
+    public static final String SOURCE_X = "srcX";
+    public static final String SOURCE_Y = "srcY";
+    public static final String PIXEL_FORMAT = "pixel_format";
+
+    private static final String NUM_OF_PROCESSED_RECTANGLES = "rects";
+    private static final String SAVED_CURSOR_POSITION = "cursor";
+
+    // Pixel format: RGB888 LE 32
+    public static final String RGB888LE32 = "RGB888LE32";
+
+    public VncMessageHandler(String id, ScreenDescription screen) {
+        super(id);
+        this.screen = screen;
+        declarePads();
+    }
+
+    private void declarePads() {
+        outputPads.put(SERVER_BELL_ADAPTER_PAD, null);
+        outputPads.put(SERVER_BELL_ADAPTER_PAD, null);
+        outputPads.put(SERVER_CLIPBOARD_ADAPTER_PAD, null);
+        outputPads.put(PIXEL_ADAPTER_PAD, null);
+        outputPads.put(FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, null);
+
+        inputPads.put("stdin", null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        try {
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+            if (!cap(buf, 1, UNLIMITED, link, false))
+                return;
+
+            // Read server message type
+            int messageType = buf.readUnsignedByte();
+
+            // Invoke packet handler by packet type.
+            switch (messageType) {
+
+            case RfbConstants.SERVER_FRAMEBUFFER_UPDATE: {
+                // Handle frame buffer update
+                if (!handleFBU(buf, link))
+                    return;
+
+                // Frame buffer update is received and fully processed, send request for
+                // another frame buffer update to server.
+                sendFBUR();
+
+                break;
+            }
+
+            case RfbConstants.SERVER_BELL: {
+                if (!handleBell(buf, link))
+                    return;
+                break;
+            }
+
+            case RfbConstants.SERVER_CUT_TEXT: {
+                if (!handleClipboard(buf, link))
+                    return;
+                break;
+            }
+
+            default:
+                // TODO: allow to extend functionality
+                throw new RuntimeException("Unknown server packet type: " + messageType + ".");
+            }
+
+            // Cut tail, if any
+            cap(buf, 0, 0, link, true);
+        } finally {
+
+            // Return processed buffer back to pool
+            buf.unref();
+        }
+    }
+
+    private boolean handleClipboard(ByteBuffer buf, Link link) {
+        if (!cap(buf, 3 + 4, UNLIMITED, link, true))
+            return false;
+
+        // Skip padding
+        buf.skipBytes(3);
+
+        // Read text length
+        int length = buf.readSignedInt();
+
+        // We need full string to parse it
+        if (!cap(buf, length, UNLIMITED, link, true))
+            return false;
+
+        String content = buf.readString(length, RfbConstants.US_ASCII_CHARSET);
+
+        // Send content in metadata
+        ByteBuffer outBuf = new ByteBuffer(0);
+        outBuf.putMetadata(AwtClipboardAdapter.CLIPBOARD_CONTENT, content);
+
+        pushDataToPad(SERVER_CLIPBOARD_ADAPTER_PAD, outBuf);
+
+        return true;
+    }
+
+    private boolean handleBell(ByteBuffer buf, Link link) {
+        // Send empty packet to bell adapter to produce bell
+        pushDataToPad(SERVER_BELL_ADAPTER_PAD, new ByteBuffer(0));
+
+        return true;
+    }
+
+    // FIXME: this method is too complex
+    private boolean handleFBU(ByteBuffer buf, Link link) {
+
+        // We need at least 3 bytes here, 1 - padding, 2 - number of rectangles
+        if (!cap(buf, 3, UNLIMITED, link, true))
+            return false;
+
+        buf.skipBytes(1);// Skip padding
+
+        // Read number of rectangles
+        int numberOfRectangles = buf.readUnsignedShort();
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Frame buffer update. Number of rectangles: " + numberOfRectangles + ".");
+
+        // Each rectangle must have header at least, header length is 12 bytes.
+        if (!cap(buf, 12 * numberOfRectangles, UNLIMITED, link, true))
+            return false;
+
+        // For all rectangles
+
+        // Restore saved point, to avoid flickering and performance problems when
+        // frame buffer update is split between few incoming packets.
+        int numberOfProcessedRectangles = (buf.getMetadata(NUM_OF_PROCESSED_RECTANGLES) != null) ? (Integer)buf.getMetadata(NUM_OF_PROCESSED_RECTANGLES) : 0;
+        if (buf.getMetadata(SAVED_CURSOR_POSITION) != null)
+            buf.cursor = (Integer)buf.getMetadata(SAVED_CURSOR_POSITION);
+
+        if (verbose && numberOfProcessedRectangles > 0)
+            System.out.println("[" + this + "] INFO: Restarting from saved point. Number of already processed rectangles: " + numberOfRectangles + ", cursor: "
+                    + buf.cursor + ".");
+
+        // For all new rectangles
+        for (int i = numberOfProcessedRectangles; i < numberOfRectangles; i++) {
+
+            // We need coordinates of rectangle (2x4 bytes) and encoding type (4
+            // bytes)
+            if (!cap(buf, 12, UNLIMITED, link, true))
+                return false;
+
+            // Read coordinates of rectangle
+            int x = buf.readUnsignedShort();
+            int y = buf.readUnsignedShort();
+            int width = buf.readUnsignedShort();
+            int height = buf.readUnsignedShort();
+
+            // Read rectangle encoding
+            int encodingType = buf.readSignedInt();
+
+            // Process rectangle
+            switch (encodingType) {
+
+            case RfbConstants.ENCODING_RAW: {
+                if (!handleRawRectangle(buf, link, x, y, width, height))
+                    return false;
+                break;
+            }
+
+            case RfbConstants.ENCODING_COPY_RECT: {
+                if (!handleCopyRect(buf, link, x, y, width, height))
+                    return false;
+                break;
+            }
+
+            case RfbConstants.ENCODING_DESKTOP_SIZE: {
+                if (!handleScreenSizeChangeRect(buf, link, x, y, width, height))
+                    return false;
+                break;
+            }
+
+            default:
+                // TODO: allow to extend functionality
+                throw new RuntimeException("Unsupported ecnoding: " + encodingType + ".");
+            }
+
+            // Update information about processed rectangles to avoid handling of same
+            // rectangle multiple times.
+            // TODO: push back partial rectangle only instead
+            buf.putMetadata(NUM_OF_PROCESSED_RECTANGLES, ++numberOfProcessedRectangles);
+            buf.putMetadata(SAVED_CURSOR_POSITION, buf.cursor);
+        }
+
+        return true;
+    }
+
+    private boolean handleScreenSizeChangeRect(ByteBuffer buf, Link link, int x, int y, int width, int height) {
+        // Remote screen size is changed
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Screen size rect. Width: " + width + ", height: " + height + ".");
+
+        screen.setFramebufferSize(width, height);
+
+        return true;
+    }
+
+    private boolean handleCopyRect(ByteBuffer buf, Link link, int x, int y, int width, int height) {
+        // Copy rectangle from one part of screen to another.
+        // Areas may overlap. Antialiasing may cause visible artifacts.
+
+        // We need 4 bytes with coordinates of source rectangle
+        if (!cap(buf, 4, UNLIMITED, link, true))
+            return false;
+
+        CopyRectOrder order = new CopyRectOrder();
+
+        order.srcX = buf.readUnsignedShort();
+        order.srcY = buf.readUnsignedShort();
+        order.x = x;
+        order.y = y;
+        order.width = width;
+        order.height = height;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Copy rect. X: " + x + ", y: " + y + ", width: " + width + ", height: " + height + ", srcX: " + order.srcX
+                    + ", srcY: " + order.srcY + ".");
+
+        pushDataToPad(PIXEL_ADAPTER_PAD, new ByteBuffer(order));
+
+        return true;
+    }
+
+    private boolean handleRawRectangle(ByteBuffer buf, Link link, int x, int y, int width, int height) {
+        // Raw rectangle is just array of pixels to draw on screen.
+        int rectDataLength = width * height * screen.getBytesPerPixel();
+
+        // We need at least rectDataLength bytes. Extra bytes may contain other
+        // rectangles.
+        if (!cap(buf, rectDataLength, UNLIMITED, link, true))
+            return false;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Raw rect. X: " + x + ", y: " + y + ", width: " + width + ", height: " + height + ", data length: "
+                    + rectDataLength + ".");
+
+        BitmapRectangle rectangle = new BitmapRectangle();
+        rectangle.x = x;
+        rectangle.y = y;
+        rectangle.width = width;
+        rectangle.height = height;
+        rectangle.bufferWidth = width;
+        rectangle.bufferHeight = height;
+        rectangle.bitmapDataStream = buf.readBytes(rectDataLength);
+        rectangle.colorDepth = screen.getColorDeph();
+
+        BitmapOrder order = new BitmapOrder();
+        order.rectangles = new BitmapRectangle[] {rectangle};
+
+        pushDataToPad(PIXEL_ADAPTER_PAD, new ByteBuffer(order));
+        return true;
+    }
+
+    public void onStart() {
+        // Send Frame Buffer Update request
+        sendFBUR();
+    }
+
+    private void sendFBUR() {
+        ByteBuffer buf = new ByteBuffer(0);
+        buf.putMetadata("incremental", true);
+        pushDataToPad(FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, buf);
+    }
+
+    public String toString() {
+        return "VNCMessageHandler(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String[] args) {
+
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        Element source = new MockSource("source") {
+            {
+                // Split messages at random boundaries to check "pushback" logic
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
+                        // Message type: server bell
+                        RfbConstants.SERVER_BELL,
+
+                        // Message type: clipboard text
+                        RfbConstants.SERVER_CUT_TEXT,
+                        // Padding
+                        0, 0, 0,
+                        // Length (test)
+                        0, 0, 0, 4,
+
+                }, new byte[] {
+                        // Clipboard text
+                        't', 'e', 's', 't',
+
+                        // Message type: frame buffer update
+                        RfbConstants.SERVER_FRAMEBUFFER_UPDATE,
+                        // Padding
+                        0,
+                        // Number of rectangles
+                        0, 3,},
+
+                        new byte[] {
+
+                                // x, y, width, height: 0x0@4x4
+                                0, 0, 0, 0, 0, 4, 0, 4,
+                                // Encoding: desktop size
+                                (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 24) & 0xff), (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 16) & 0xff),
+                                (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 8) & 0xff), (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 0) & 0xff),},
+
+                        new byte[] {
+
+                                // x, y, width, height: 0x0@4x4
+                                0, 0, 0, 0, 0, 4, 0, 4,
+                                // Encoding: raw rect
+                                (byte)((RfbConstants.ENCODING_RAW >> 24) & 0xff), (byte)((RfbConstants.ENCODING_RAW >> 16) & 0xff),
+                                (byte)((RfbConstants.ENCODING_RAW >> 8) & 0xff), (byte)((RfbConstants.ENCODING_RAW >> 0) & 0xff),
+                                // Raw pixel data 4x4x1 bpp
+                                1, 2, 3, 4, 5, 6, 7, 8, 9, 10,}, new byte[] {11, 12, 13, 14, 15, 16,
+
+                                // x, y, width, height: 0x0@2x2
+                                0, 0, 0, 0, 0, 2, 0, 2,
+                                // Encoding: copy rect
+                                (byte)((RfbConstants.ENCODING_COPY_RECT >> 24) & 0xff), (byte)((RfbConstants.ENCODING_COPY_RECT >> 16) & 0xff),
+                                (byte)((RfbConstants.ENCODING_COPY_RECT >> 8) & 0xff), (byte)((RfbConstants.ENCODING_COPY_RECT >> 0) & 0xff),
+                                // srcX, srcY: 2x2
+                                0, 2, 0, 2,});
+            }
+        };
+
+        ScreenDescription screen = new ScreenDescription() {
+            {
+                this.bytesPerPixel = 1;
+            }
+        };
+
+        final Element handler = new VncMessageHandler("handler", screen);
+
+        ByteBuffer[] emptyBuf = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {});
+        Element fburSink = new MockSink("fbur", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {}, new byte[] {}));
+        Element bellSink = new MockSink("bell", emptyBuf);
+        Element clipboardSink = new MockSink("clipboard", emptyBuf);
+        Element desktopSizeChangeSink = new MockSink("desktop_size", emptyBuf);
+        Element pixelsSink = new MockSink("pixels",
+                ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,}));
+        Element copyRectSink = new MockSink("copy_rect", emptyBuf);
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.addAndLink(source, handler);
+        pipeline.add(fburSink, bellSink, clipboardSink, desktopSizeChangeSink, pixelsSink, copyRectSink);
+
+        pipeline.link("handler >" + FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, "fbur");
+        pipeline.link("handler >" + SERVER_BELL_ADAPTER_PAD, "bell");
+        pipeline.link("handler >" + SERVER_CLIPBOARD_ADAPTER_PAD, "clipboard");
+        pipeline.link("handler >" + PIXEL_ADAPTER_PAD, "pixels");
+
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc_3_3_Authentication.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc_3_3_Authentication.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc_3_3_Authentication.java
new file mode 100755
index 0000000..93423da
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc_3_3_Authentication.java
@@ -0,0 +1,291 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 vncclient.vnc;
+
+import java.security.spec.KeySpec;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.FakeSink;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class Vnc_3_3_Authentication extends OneTimeSwitch {
+
+    /**
+     * Password to use when authentication is required.
+     */
+    protected String password = null;
+
+    /**
+     * Authentication stage:
+     * <ul>
+     * <li>0 - challenge received, response must be sent
+     * <li>1 - authentication result received.
+     * </ul>
+     */
+    protected int stage = 0;
+
+    public Vnc_3_3_Authentication(String id) {
+        super(id);
+    }
+
+    public Vnc_3_3_Authentication(String id, String password) {
+        super(id);
+        this.password = password;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        switch (stage) {
+        case 0: // Read security with optional challenge and response
+            stage0(buf, link);
+
+            break;
+        case 1: // Read authentication response
+            stage1(buf, link);
+            break;
+        }
+
+    }
+
+    /**
+     * Read security type. If connection type is @see
+     * RfbConstants.CONNECTION_FAILED, then throw exception. If connection type is @see
+     * RfbConstants.NO_AUTH, then switch off this element. If connection type is @see
+     * RfbConstants.VNC_AUTH, then read challenge, send encoded password, and read
+     * authentication response.
+     */
+    private void stage0(ByteBuffer buf, Link link) {
+        // At least 4 bytes are necessary
+        if (!cap(buf, 4, UNLIMITED, link, true))
+            return;
+
+        // Read security type
+        int authType = buf.readSignedInt();
+
+        switch (authType) {
+        case RfbConstants.CONNECTION_FAILED: {
+            // Server forbids to connect. Read reason and throw exception
+
+            int length = buf.readSignedInt();
+            String reason = new String(buf.data, buf.offset, length, RfbConstants.US_ASCII_CHARSET);
+
+            throw new RuntimeException("Authentication to VNC server is failed. Reason: " + reason);
+        }
+
+        case RfbConstants.NO_AUTH: {
+            // Client can connect without authorization. Nothing to do.
+            // Switch off this element from circuit
+            switchOff();
+            break;
+        }
+
+        case RfbConstants.VNC_AUTH: {
+            // Read challenge and generate response
+            responseToChallenge(buf, link);
+            break;
+        }
+
+        default:
+            throw new RuntimeException("Unsupported VNC protocol authorization scheme, scheme code: " + authType + ".");
+        }
+
+    }
+
+    private void responseToChallenge(ByteBuffer buf, Link link) {
+        // Challenge is exactly 16 bytes long
+        if (!cap(buf, 16, 16, link, true))
+            return;
+
+        ByteBuffer challenge = buf.slice(buf.cursor, 16, true);
+        buf.unref();
+
+        // Encode challenge with password
+        ByteBuffer response;
+        try {
+            response = encodePassword(challenge, password);
+            challenge.unref();
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot encrypt client password to send to server: " + e.getMessage());
+        }
+
+        if (verbose) {
+            response.putMetadata("sender", this);
+        }
+
+        // Send encoded challenge
+        nextStage();
+        pushDataToOTOut(response);
+
+    }
+
+    private void nextStage() {
+        stage++;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Next stage: " + stage + ".");
+    }
+
+    /**
+     * Encode password using DES encryption with given challenge.
+     * 
+     * @param challenge
+     *          a random set of bytes.
+     * @param password
+     *          a password
+     * @return DES hash of password and challenge
+     */
+    public ByteBuffer encodePassword(ByteBuffer challenge, String password) {
+        if (challenge.length != 16)
+            throw new RuntimeException("Challenge must be exactly 16 bytes long.");
+
+        // VNC password consist of up to eight ASCII characters.
+        byte[] key = {0, 0, 0, 0, 0, 0, 0, 0}; // Padding
+        byte[] passwordAsciiBytes = password.getBytes(RfbConstants.US_ASCII_CHARSET);
+        System.arraycopy(passwordAsciiBytes, 0, key, 0, Math.min(password.length(), 8));
+
+        // Flip bytes (reverse bits) in key
+        for (int i = 0; i < key.length; i++) {
+            key[i] = flipByte(key[i]);
+        }
+
+        try {
+            KeySpec desKeySpec = new DESKeySpec(key);
+            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
+            SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
+            Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
+            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
+
+            ByteBuffer buf = new ByteBuffer(cipher.doFinal(challenge.data, challenge.offset, challenge.length));
+
+            return buf;
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot encode password.", e);
+        }
+    }
+
+    /**
+     * Reverse bits in byte, so least significant bit will be most significant
+     * bit. E.g. 01001100 will become 00110010.
+     * 
+     * See also: http://www.vidarholen.net/contents/junk/vnc.html ,
+     * http://bytecrafter .blogspot.com/2010/09/des-encryption-as-used-in-vnc.html
+     * 
+     * @param b
+     *          a byte
+     * @return byte in reverse order
+     */
+    private static byte flipByte(byte b) {
+        int b1_8 = (b & 0x1) << 7;
+        int b2_7 = (b & 0x2) << 5;
+        int b3_6 = (b & 0x4) << 3;
+        int b4_5 = (b & 0x8) << 1;
+        int b5_4 = (b & 0x10) >>> 1;
+        int b6_3 = (b & 0x20) >>> 3;
+        int b7_2 = (b & 0x40) >>> 5;
+        int b8_1 = (b & 0x80) >>> 7;
+        byte c = (byte)(b1_8 | b2_7 | b3_6 | b4_5 | b5_4 | b6_3 | b7_2 | b8_1);
+        return c;
+    }
+
+    /**
+     * Read authentication result, send nothing.
+     */
+    private void stage1(ByteBuffer buf, Link link) {
+        // Read authentication response
+        if (!cap(buf, 4, 4, link, false))
+            return;
+
+        int authResult = buf.readSignedInt();
+
+        switch (authResult) {
+        case RfbConstants.VNC_AUTH_OK: {
+            // Nothing to do
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Authentication successfull.");
+            break;
+        }
+
+        case RfbConstants.VNC_AUTH_TOO_MANY:
+            throw new RuntimeException("Connection to VNC server failed: too many wrong attempts.");
+
+        case RfbConstants.VNC_AUTH_FAILED:
+            throw new RuntimeException("Connection to VNC server failed: wrong password.");
+
+        default:
+            throw new RuntimeException("Connection to VNC server failed, reason code: " + authResult);
+        }
+
+        switchOff();
+
+    }
+
+    public String toString() {
+        return "VNC3.3 Authentication(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        final String password = "test";
+
+        Element source = new MockSource("source") {
+            {
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(
+                        // Request authentication and send 16 byte challenge
+                        new byte[] {0, 0, 0, RfbConstants.VNC_AUTH, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
+                        // Respond to challenge with AUTH_OK
+                        new byte[] {0, 0, 0, RfbConstants.VNC_AUTH_OK});
+            }
+        };
+
+        Element mainSink = new FakeSink("mainSink");
+        final Vnc_3_3_Authentication auth = new Vnc_3_3_Authentication("auth", password);
+        Element initSink = new MockSink("initSink") {
+            {
+                // Expect encoded password
+                bufs = new ByteBuffer[] {auth.encodePassword(new ByteBuffer(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), password)};
+            }
+        };
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.addAndLink(source, auth, mainSink);
+        pipeline.add(initSink);
+        pipeline.link("auth >otout", "initSink");
+
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc_3_3_Hello.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc_3_3_Hello.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc_3_3_Hello.java
new file mode 100755
index 0000000..3afff83
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc_3_3_Hello.java
@@ -0,0 +1,115 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 vncclient.vnc;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import streamer.ByteBuffer;
+import streamer.InputStreamSource;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.OutputStreamSink;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+
+/**
+ * VNC server sends hello packet with RFB protocol version, e.g.
+ * "RFB 003.007\n". We need to send response packet with supported protocol
+ * version, e.g. "RFB 003.003\n".
+ */
+public class Vnc_3_3_Hello extends OneTimeSwitch {
+
+    public Vnc_3_3_Hello(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Initial packet is exactly 12 bytes long
+        if (!cap(buf, 12, 12, link, false))
+            return;
+
+        // Read protocol version
+        String rfbProtocol = new String(buf.data, buf.offset, buf.length, RfbConstants.US_ASCII_CHARSET);
+        buf.unref();
+
+        // Server should use RFB protocol 3.x
+        if (!rfbProtocol.contains(RfbConstants.RFB_PROTOCOL_VERSION_MAJOR))
+            throw new RuntimeException("Cannot handshake with VNC server. Unsupported protocol version: \"" + rfbProtocol + "\".");
+
+        // Send response: we support RFB 3.3 only
+        String ourProtocolString = RfbConstants.RFB_PROTOCOL_VERSION + "\n";
+
+        ByteBuffer outBuf = new ByteBuffer(ourProtocolString.getBytes(RfbConstants.US_ASCII_CHARSET));
+
+        if (verbose) {
+            outBuf.putMetadata("sender", this);
+            outBuf.putMetadata("version", RfbConstants.RFB_PROTOCOL_VERSION);
+        }
+
+        pushDataToOTOut(outBuf);
+
+        // Switch off this element from circuit
+        switchOff();
+
+    }
+
+    public String toString() {
+        return "Vnc3.3 Hello(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        InputStream is = new ByteArrayInputStream("RFB 003.007\ntest".getBytes(RfbConstants.US_ASCII_CHARSET));
+        ByteArrayOutputStream initOS = new ByteArrayOutputStream();
+        ByteArrayOutputStream mainOS = new ByteArrayOutputStream();
+        InputStreamSource inputStreamSource = new InputStreamSource("source", is);
+        OutputStreamSink outputStreamSink = new OutputStreamSink("mainSink", mainOS);
+
+        Vnc_3_3_Hello hello = new Vnc_3_3_Hello("hello");
+
+        Pipeline pipeline = new PipelineImpl("test");
+
+        pipeline.addAndLink(inputStreamSource, hello, outputStreamSink);
+        pipeline.add(new OutputStreamSink("initSink", initOS));
+
+        pipeline.link("hello >" + OneTimeSwitch.OTOUT, "initSink");
+
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        String initOut = new String(initOS.toByteArray(), RfbConstants.US_ASCII_CHARSET);
+        String mainOut = new String(mainOS.toByteArray(), RfbConstants.US_ASCII_CHARSET);
+
+        if (!"RFB 003.003\n".equals(initOut))
+            System.err.println("Unexpected value for hello response: \"" + initOut + "\".");
+
+        if (!"test".equals(mainOut))
+            System.err.println("Unexpected value for main data: \"" + mainOut + "\".");
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/resources/jaas_ntlm_config.txt
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/resources/jaas_ntlm_config.txt b/services/console-proxy-rdp/rdpconsole/src/main/resources/jaas_ntlm_config.txt
new file mode 100755
index 0000000..4137609
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/resources/jaas_ntlm_config.txt
@@ -0,0 +1,21 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+MyConfig { com.sun.security.auth.module.Krb5LoginModule required
+  useTicketCache=true
+  doNotPrompt=false;
+};

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/test/doc/README.txt
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/README.txt b/services/console-proxy-rdp/rdpconsole/src/test/doc/README.txt
old mode 100644
new mode 100755
index dd41683..704f5f5
--- a/services/console-proxy-rdp/rdpconsole/src/test/doc/README.txt
+++ b/services/console-proxy-rdp/rdpconsole/src/test/doc/README.txt
@@ -30,3 +30,5 @@ fingerprints.
 
 File rdp-key.pem contains private key in PEM format for use with
 Wireshark.
+
+As alternative, mimikatz can be used to extract RDP private key.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/test/doc/dev-rdp-config.bat
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/dev-rdp-config.bat b/services/console-proxy-rdp/rdpconsole/src/test/doc/dev-rdp-config.bat
old mode 100644
new mode 100755
index 14a7bbd..4e19157
--- a/services/console-proxy-rdp/rdpconsole/src/test/doc/dev-rdp-config.bat
+++ b/services/console-proxy-rdp/rdpconsole/src/test/doc/dev-rdp-config.bat
@@ -111,6 +111,19 @@ rem Start TS service
 
 net start Termservice
 
+rem Enable logs
+
+wevtutil sl Microsoft-Windows-TerminalServices-RemoteConnectionManager/Admin /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-RemoteConnectionManager/Analytic /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-RemoteConnectionManager/Debug /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-SessionBroker-Client/Admin /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-SessionBroker-Client/Analytic /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-SessionBroker-Client/Debug /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-SessionBroker-Client/Operational /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-NTLM/Operational /enabled:true /quiet:true
+
+
 
 rem For Network Monitor Decrypt Expert.
 


[05/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSink.java
deleted file mode 100644
index ce9fdf9..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSink.java
+++ /dev/null
@@ -1,111 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 streamer;
-
-import java.util.Arrays;
-
-/**
- * Compare incoming packets with expected packets.
- */
-public class MockSink extends BaseElement {
-
-  protected ByteBuffer bufs[] = null;
-
-  public MockSink(String id) {
-    super(id);
-  }
-
-  public MockSink(String id, ByteBuffer bufs[]) {
-    super(id);
-    this.bufs = bufs;
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Received buf #" + (packetNumber) + " " + buf + ".");
-
-    if (buf == null)
-      return;
-
-    if (packetNumber >= bufs.length)
-      throw new AssertionError("[" + this + "] Incoming buffer #" + packetNumber + " is not expected. Number of expected buffers: " + bufs.length
-          + ", unexpected buffer: " + buf + ".");
-
-    // Compare incoming buffer with expected buffer
-    if (!Arrays.equals(bufs[packetNumber].toByteArray(), buf.toByteArray()))
-      throw new AssertionError("[" + this + "] Incoming buffer #" + packetNumber + " is not equal to expected buffer.\n  Actual bufer: " + buf
-          + ",\n  expected buffer: " + bufs[packetNumber] + ".");
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: buffers are equal.");
-
-    // Use packetNumber variable to count incoming packets
-    packetNumber++;
-
-    buf.unref();
-  }
-
-  @Override
-  protected void onClose() {
-    super.onClose();
-
-    if (packetNumber != bufs.length)
-      throw new AssertionError("[" + this + "] Number of expected buffers: " + bufs.length + ", number of actual buffers: " + packetNumber + ".");
-  }
-
-  @Override
-  public String toString() {
-    return "MockSink(" + id + ")";
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-
-    Element mockSource = new MockSource("source") {
-      {
-        this.bufs = new ByteBuffer[] { new ByteBuffer(new byte[] { 1, 1, 2, 3, 4, 5 }), new ByteBuffer(new byte[] { 2, 1, 2, 3, 4 }),
-            new ByteBuffer(new byte[] { 3, 1, 2, 3 }), new ByteBuffer(new byte[] { 4, 1, 2 }), new ByteBuffer(new byte[] { 5, 1 }) };
-        this.verbose = true;
-        this.delay = 100;
-        this.numBuffers = this.bufs.length;
-      }
-    };
-
-    Element mockSink = new MockSink("sink") {
-      {
-        this.bufs = new ByteBuffer[] { new ByteBuffer(new byte[] { 1, 1, 2, 3, 4, 5 }), new ByteBuffer(new byte[] { 2, 1, 2, 3, 4 }),
-            new ByteBuffer(new byte[] { 3, 1, 2, 3 }), new ByteBuffer(new byte[] { 4, 1, 2 }), new ByteBuffer(new byte[] { 5, 1 }) };
-        this.verbose = true;
-      }
-    };
-
-    Link link = new SyncLink() {
-      {
-        this.verbose = true;
-      }
-    };
-
-    mockSource.setLink(STDOUT, link, Direction.OUT);
-    mockSink.setLink(STDIN, link, Direction.IN);
-
-    link.run();
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSource.java
deleted file mode 100644
index db47db2..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSource.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 streamer;
-
-public class MockSource extends FakeSource {
-
-  protected ByteBuffer bufs[] = null;
-
-  public MockSource(String id) {
-    super(id);
-  }
-
-  public MockSource(String id, ByteBuffer bufs[]) {
-    super(id);
-    this.bufs = bufs;
-  }
-
-  /**
-   * Initialize data.
-   */
-  @Override
-  public ByteBuffer initializeData() {
-    if (packetNumber >= bufs.length) {
-      sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
-      return null;
-    }
-
-    ByteBuffer buf = bufs[packetNumber];
-
-    buf.putMetadata(ByteBuffer.SEQUENCE_NUMBER, packetNumber);
-    return buf;
-  }
-
-  @Override
-  public void handleEvent(Event event, Direction direction) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Event received: " + event + ".");
-
-  }
-
-  @Override
-  public String toString() {
-    return "MockSource(" + id + ")";
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-
-    Element mockSource = new MockSource("source") {
-      {
-        this.bufs = new ByteBuffer[] { new ByteBuffer(new byte[] { 1, 1, 2, 3, 4, 5 }), new ByteBuffer(new byte[] { 2, 1, 2, 3, 4 }),
-            new ByteBuffer(new byte[] { 3, 1, 2, 3 }), new ByteBuffer(new byte[] { 4, 1, 2 }), new ByteBuffer(new byte[] { 5, 1 }) };
-        this.verbose = true;
-        this.delay = 100;
-        // this.numBuffers = this.bufs.length;
-      }
-    };
-
-    Element fakeSink = new FakeSink("sink") {
-      {
-        this.verbose = true;
-      }
-    };
-
-    Link link = new SyncLink();
-
-    mockSource.setLink(STDOUT, link, Direction.OUT);
-    fakeSink.setLink(STDIN, link, Direction.IN);
-
-    link.run();
-  }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OneTimeSwitch.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OneTimeSwitch.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OneTimeSwitch.java
old mode 100644
new mode 100755
index a7d4848..2e5d891
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OneTimeSwitch.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OneTimeSwitch.java
@@ -29,105 +29,108 @@ package streamer;
  */
 public abstract class OneTimeSwitch extends BaseElement {
 
-  /**
-   * One-time out - name of output pad for one time logic. By default, output
-   * directly to socket.
-   */
-  public static final String OTOUT = "otout";
-
-  private boolean switched = false;
-
-  public OneTimeSwitch(String id) {
-    super(id);
-    declarePads();
-  }
-
-  protected void declarePads() {
-    inputPads.put(STDIN, null);
-    outputPads.put(OTOUT, null);
-    outputPads.put(STDOUT, null);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (switched)
-      throw new RuntimeException(this + " element is switched off and must not receive any data or events anymore.");
-
-    if (buf == null)
-      return;
-
-    handleOneTimeData(buf, link);
-  }
-
-  public void pushDataToOTOut(ByteBuffer buf) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Sending data:  " + buf + ".");
-
-    outputPads.get(OTOUT).sendData(buf);
-  }
-
-  /**
-   * Switch this element off. Pass data directly to main output(s).
-   */
-  public void switchOff() {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Switching OFF.");
-
-    switched = true;
-    verbose = false;
-
-    // Rewire links: drop otout link, replace stdout link by stdin to send data
-    // directly to stdout
-    Link stdout = (Link) outputPads.get(STDOUT);
-    Link stdin = (Link) inputPads.get(STDIN);
-    Link otout = (Link) outputPads.get(OTOUT);
-
-    otout.drop();
-
-    // Wake up next peer(s)
-    sendEventToAllPads(Event.STREAM_START, Direction.OUT);
-
-    stdin.setSink(null);
-    inputPads.remove(STDIN);
-
-    Element nextPeer = stdout.getSink();
-    nextPeer.replaceLink(stdout, stdin);
-    stdout.drop();
-
-    for (Object link : inputPads.values().toArray())
-      ((Link) link).drop();
-    for (Object link : outputPads.values().toArray())
-      ((Link) link).drop();
-
-  }
-
-  public void switchOn() {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Switching ON.");
-
-    switched = false;
-  }
-
-  /**
-   * Override this method to handle one-time packet(s) at handshake or
-   * initialization stages. Execute method @see switchRoute() when this method
-   * is no longer necessary.
-   */
-  protected abstract void handleOneTimeData(ByteBuffer buf, Link link);
-
-  @Override
-  public void handleEvent(Event event, Direction direction) {
-    if (event == Event.STREAM_START) {
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Event " + event + " is received.");
-
-      switchOn();
-
-      // Execute this element onStart(), but do not propagate event further,
-      // to not wake up next elements too early
-      onStart();
-    } else
-      super.handleEvent(event, direction);
-  }
+    /**
+     * One-time out - name of output pad for one time logic. By default, output
+     * directly to socket.
+     */
+    public static final String OTOUT = "otout";
+
+    private boolean switched = false;
+
+    public OneTimeSwitch(String id) {
+        super(id);
+        declarePads();
+    }
+
+    protected void declarePads() {
+        inputPads.put(STDIN, null);
+        outputPads.put(OTOUT, null);
+        outputPads.put(STDOUT, null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (switched)
+            throw new RuntimeException(this + " element is switched off and must not receive any data or events anymore.");
+
+        if (buf == null)
+            return;
+
+        handleOneTimeData(buf, link);
+    }
+
+    public void pushDataToOTOut(ByteBuffer buf) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Sending data:  " + buf + ".");
+
+        outputPads.get(OTOUT).sendData(buf);
+    }
+
+    /**
+     * Switch this element off. Pass data directly to main output(s).
+     */
+    public void switchOff() {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Switching OFF.");
+
+        switched = true;
+        verbose = false;
+
+        // Rewire links: drop otout link, replace stdout link by stdin to send data
+        // directly to stdout
+        Link stdout = (Link)outputPads.get(STDOUT);
+        Link stdin = (Link)inputPads.get(STDIN);
+        Link otout = (Link)outputPads.get(OTOUT);
+
+        otout.drop();
+
+        // Wake up next peer(s)
+        sendEventToAllPads(Event.STREAM_START, Direction.OUT);
+
+        // Disconnect our stdin from this element
+        stdin.setSink(null);
+        inputPads.remove(STDIN);
+
+        // Replace next peer stdin (our stdout) by our stdin
+        Element nextPeer = stdout.getSink();
+        nextPeer.replaceLink(stdout, stdin);
+        stdout.drop();
+
+        // Drop all other links
+        for (Object link : inputPads.values().toArray())
+            ((Link)link).drop();
+        for (Object link : outputPads.values().toArray())
+            ((Link)link).drop();
+
+    }
+
+    public void switchOn() {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Switching ON.");
+
+        switched = false;
+    }
+
+    /**
+     * Override this method to handle one-time packet(s) at handshake or
+     * initialization stages. Execute method @see switchRoute() when this method
+     * is no longer necessary.
+     */
+    protected abstract void handleOneTimeData(ByteBuffer buf, Link link);
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        if (event == Event.STREAM_START) {
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Event " + event + " is received.");
+
+            switchOn();
+
+            // Execute this element onStart(), but do not propagate event further,
+            // to not wake up next elements too early
+            onStart();
+        } else
+            super.handleEvent(event, direction);
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Order.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Order.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Order.java
old mode 100644
new mode 100755
index 1d63850..8f5654e
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Order.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Order.java
@@ -18,6 +18,6 @@ package streamer;
 
 public class Order {
 
-  public Object type;
+    public Object type;
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OutputStreamSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OutputStreamSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OutputStreamSink.java
old mode 100644
new mode 100755
index d1aa5ce..104b8c3
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OutputStreamSink.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OutputStreamSink.java
@@ -20,134 +20,136 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import streamer.debug.FakeSource;
+
 public class OutputStreamSink extends BaseElement {
 
-  protected OutputStream os;
-  protected SocketWrapper socketWrapper;
-
-  public OutputStreamSink(String id) {
-    super(id);
-  }
-
-  public OutputStreamSink(String id, OutputStream os) {
-    super(id);
-    this.os = os;
-  }
-
-  public OutputStreamSink(String id, SocketWrapper socketWrapper) {
-    super(id);
-    this.socketWrapper = socketWrapper;
-  }
-
-  public void setOutputStream(OutputStream os) {
-    this.os = os;
-    // Resume links
-    resumeLinks();
-  }
-
-  /**
-   * Send incoming data to stream.
-   */
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    try {
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Writing data to stream: " + buf + ".");
-
-      os.write(buf.data, buf.offset, buf.length);
-      os.flush();
-    } catch (IOException e) {
-      System.err.println("[" + this + "] ERROR: " + e.getMessage());
-      closeStream();
+    protected OutputStream os;
+    protected SocketWrapperImpl socketWrapper;
+
+    public OutputStreamSink(String id) {
+        super(id);
+    }
+
+    public OutputStreamSink(String id, OutputStream os) {
+        super(id);
+        this.os = os;
+    }
+
+    public OutputStreamSink(String id, SocketWrapperImpl socketWrapper) {
+        super(id);
+        this.socketWrapper = socketWrapper;
     }
-  }
-
-  @Override
-  public void handleEvent(Event event, Direction direction) {
-    switch (event) {
-    case SOCKET_UPGRADE_TO_SSL:
-      socketWrapper.upgradeToSsl();
-      break;
-    default:
-      super.handleEvent(event, direction);
+
+    public void setOutputStream(OutputStream os) {
+        this.os = os;
+        // Resume links
+        resumeLinks();
+    }
+
+    /**
+     * Send incoming data to stream.
+     */
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        try {
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Writing data to stream: " + buf + ".");
+
+            os.write(buf.data, buf.offset, buf.length);
+            os.flush();
+        } catch (IOException e) {
+            System.err.println("[" + this + "] ERROR: " + e.getMessage());
+            closeStream();
+        }
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        switch (event) {
+        case SOCKET_UPGRADE_TO_SSL:
+            socketWrapper.upgradeToSsl();
+            break;
+        default:
+            super.handleEvent(event, direction);
+        }
     }
-  }
-
-  @Override
-  public void setLink(String padName, Link link, Direction direction) {
-    switch (direction) {
-    case IN:
-      super.setLink(padName, link, direction);
-
-      if (os == null)
-        // Pause links until data stream will be ready
-        link.pause();
-      break;
-    case OUT:
-      throw new RuntimeException("Cannot assign link to output pad in sink element. Element: " + this + ", pad: " + padName + ", link: " + link + ".");
+
+    @Override
+    public void setLink(String padName, Link link, Direction direction) {
+        switch (direction) {
+        case IN:
+            super.setLink(padName, link, direction);
+
+            if (os == null)
+                // Pause links until data stream will be ready
+                link.pause();
+            break;
+        case OUT:
+            throw new RuntimeException("Cannot assign link to output pad in sink element. Element: " + this + ", pad: " + padName + ", link: " + link + ".");
+        }
     }
-  }
 
-  private void resumeLinks() {
-    for (DataSource source : inputPads.values())
-      ((Link) source).resume();
-  }
+    private void resumeLinks() {
+        for (DataSource source : inputPads.values())
+            ((Link)source).resume();
+    }
 
-  @Override
-  protected void onClose() {
-    closeStream();
-  }
+    @Override
+    protected void onClose() {
+        closeStream();
+    }
 
-  private void closeStream() {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Closing stream.");
+    private void closeStream() {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Closing stream.");
+
+        try {
+            os.close();
+        } catch (IOException e) {
+        }
+        try {
+            sendEventToAllPads(Event.STREAM_CLOSE, Direction.IN);
+        } catch (Exception e) {
+        }
+    }
 
-    try {
-      os.close();
-    } catch (IOException e) {
+    @Override
+    public String toString() {
+        return "OutputStreamSink(" + id + ")";
     }
-    try {
-      sendEventToAllPads(Event.STREAM_CLOSE, Direction.IN);
-    } catch (Exception e) {
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        Element source = new FakeSource("source") {
+            {
+                this.verbose = true;
+                this.numBuffers = 3;
+                this.incommingBufLength = 5;
+                this.delay = 100;
+            }
+        };
+
+        OutputStreamSink sink = new OutputStreamSink("sink") {
+            {
+                verbose = true;
+            }
+        };
+
+        Link link = new SyncLink();
+
+        source.setLink(STDOUT, link, Direction.OUT);
+        sink.setLink(STDIN, link, Direction.IN);
+
+        sink.setOutputStream(new ByteArrayOutputStream());
+
+        link.sendEvent(Event.STREAM_START, Direction.IN);
+        link.run();
+
     }
-  }
-
-  @Override
-  public String toString() {
-    return "OutputStreamSink(" + id + ")";
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    Element source = new FakeSource("source") {
-      {
-        this.verbose = true;
-        this.numBuffers = 3;
-        this.incommingBufLength = 5;
-        this.delay = 100;
-      }
-    };
-
-    OutputStreamSink sink = new OutputStreamSink("sink") {
-      {
-        verbose = true;
-      }
-    };
-
-    Link link = new SyncLink();
-
-    source.setLink(STDOUT, link, Direction.OUT);
-    sink.setLink(STDIN, link, Direction.IN);
-
-    sink.setOutputStream(new ByteArrayOutputStream());
-
-    link.sendEvent(Event.STREAM_START, Direction.IN);
-    link.run();
-
-  }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Pipeline.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Pipeline.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Pipeline.java
old mode 100644
new mode 100755
index c369350..ad9d8d6
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Pipeline.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Pipeline.java
@@ -21,71 +21,73 @@ package streamer;
  */
 public interface Pipeline extends Element {
 
-  static final String IN = Direction.IN.toString();
-  static final String OUT = Direction.OUT.toString();
+    static final String IN = Direction.IN.toString();
+    static final String OUT = Direction.OUT.toString();
 
-  /**
-   * Add elements to pipeline.
-   * 
-   * @param elements
-   */
-  void add(Element... elements);
+    /**
+     * Add elements to pipeline.
+     * 
+     * @param elements
+     */
+    void add(Element... elements);
 
-  /**
-   * Add elements to pipeline and link them in given order.
-   * 
-   * @param elements
-   */
-  void addAndLink(Element... elements);
+    /**
+     * Add elements to pipeline and link them in given order.
+     * 
+     * @param elements
+     */
+    void addAndLink(Element... elements);
 
-  /**
-   * Link elements in given order using SyncLink. Element name can have prefix
-   * "PADNAME< " or/and suffix " >PADNAME" to use given named pads instead of
-   * "stdin" and "stdout". I.e. <code>link("foo", "bar", "baz");</code> is equal
-   * to <code>link("foo >stdin", "stdout< bar >stdin", "stdout< baz");</code> .
-   * 
-   * Special elements "IN" and "OUT" are pointing to pipeline outer interfaces,
-   * so when pipeline will be connected with other elements, outside of this
-   * pipeline, they will be connected to IN and OUT elements.
-   * 
-   * Example:
-   * 
-   * <pre>
-   * pipeline.link(&quot;IN&quot;, &quot;foo&quot;, &quot;bar&quot;, &quot;OUT&quot;);
-   * // Make additional branch from foo to baz, and then to OUT
-   * pipeline.link(&quot;foo &gt;baz_out&quot;, &quot;baz&quot;, &quot;baz_in&lt; OUT&quot;);
-   * </pre>
-   * 
-   * @param elements
-   *          elements to link
-   */
-  void link(String... elements);
+    /**
+     * Link elements in given order using SyncLink. Element name can have prefix
+     * "PADNAME< " or/and suffix " >PADNAME" to use given named pads instead of
+     * "stdin" and "stdout". I.e. <code>link("foo", "bar", "baz");</code> is equal
+     * to <code>link("foo >stdin", "stdout< bar >stdin", "stdout< baz");</code> .
+     * 
+     * Special elements "IN" and "OUT" are pointing to pipeline outer interfaces,
+     * so when pipeline will be connected with other elements, outside of this
+     * pipeline, they will be connected to IN and OUT elements.
+     * 
+     * Empty names are skipped.
+     * 
+     * Example:
+     * 
+     * <pre>
+     * pipeline.link(&quot;IN&quot;, &quot;foo&quot;, &quot;bar&quot;, &quot;OUT&quot;);
+     * // Make additional branch from foo to baz, and then to OUT
+     * pipeline.link(&quot;foo &gt;baz_out&quot;, &quot;baz&quot;, &quot;baz_in&lt; OUT&quot;);
+     * </pre>
+     * 
+     * @param elements
+     *          elements to link
+     */
+    void link(String... elements);
 
-  /**
-   * Get element by name.
-   * 
-   * @return an element
-   */
-  Element get(String elementName);
+    /**
+     * Get element by name.
+     * 
+     * @return an element
+     */
+    Element get(String elementName);
 
-  /**
-   * Get link by element name and pad name.
-   */
-  Link getLink(String elementName, String padName);
+    /**
+     * Get link by element name and pad name.
+     */
+    Link getLink(String elementName, String padName);
 
-  /**
-   * Set link by element name and pad name. Allows to link external elements
-   * into internal elements of pipeline. Special elements "IN" and "OUT" are
-   * pointing to pipeline outer interfaces.
-   */
-  void setLink(String elementName, String padName, Link link, Direction direction);
+    /**
+     * Set link by element name and pad name. Allows to link external elements
+     * into internal elements of pipeline. Special elements "IN" and "OUT" are
+     * pointing to pipeline outer interfaces.
+     */
+    void setLink(String elementName, String padName, Link link, Direction direction);
 
-  /**
-   * Get link connected to given pad in given element and run it main loop.
-   * @param separateThread
-   *          set to true to start main loop in separate thread.
-   * @param waitForStartEvent TODO
-   */
-  void runMainLoop(String element, String padName, boolean separateThread, boolean waitForStartEvent);
+    /**
+     * Get link connected to given pad in given element and run it main loop.
+     * @param separateThread
+     *          set to true to start main loop in separate thread.
+     * @param waitForStartEvent TODO
+     */
+    void runMainLoop(String element, String padName, boolean separateThread, boolean waitForStartEvent);
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/PipelineImpl.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/PipelineImpl.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/PipelineImpl.java
old mode 100644
new mode 100755
index abf132f..299d0a4
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/PipelineImpl.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/PipelineImpl.java
@@ -16,294 +16,325 @@
 // under the License.
 package streamer;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import streamer.debug.FakeSink;
+import streamer.debug.FakeSource;
+
 public class PipelineImpl implements Pipeline {
 
-  protected String id;
-  protected boolean verbose = System.getProperty("streamer.Pipeline.debug", "false").equals("true");
+    protected String id;
+    protected boolean verbose = System.getProperty("streamer.Pipeline.debug", "false").equals("true");
 
-  public PipelineImpl(String id) {
-    this.id = id;
-    elements = initElementMap(id);
-  }
+    public PipelineImpl(String id) {
+        this.id = id;
+        elements = initElementMap(id);
+    }
 
-  protected Map<String, Element> elements;
+    protected Map<String, Element> elements;
 
-  protected HashMap<String, Element> initElementMap(String id) {
-    HashMap<String, Element> map = new HashMap<String, Element>();
+    protected HashMap<String, Element> initElementMap(String id) {
+        HashMap<String, Element> map = new HashMap<String, Element>();
 
-    map.put(IN, new BaseElement(id + "." + IN));
-    map.put(OUT, new BaseElement(id + "." + OUT));
-    return map;
-  }
+        map.put(IN, new BaseElement(id + "." + IN));
+        map.put(OUT, new BaseElement(id + "." + OUT));
+        return map;
+    }
 
-  @Override
-  public Link getLink(String padName) {
-    Link link = elements.get(IN).getLink(padName);
-    if (link == null)
-      link = elements.get(OUT).getLink(padName);
-    return link;
-  }
+    @Override
+    public Link getLink(String padName) {
+        Link link = elements.get(IN).getLink(padName);
+        if (link == null)
+            link = elements.get(OUT).getLink(padName);
+        return link;
+    }
 
-  @Override
-  public Set<String> getPads(Direction direction) {
-    switch (direction) {
-    case IN:
-      return elements.get(IN).getPads(direction);
+    @Override
+    public Set<String> getPads(Direction direction) {
+        switch (direction) {
+        case IN:
+            return elements.get(IN).getPads(direction);
 
-    case OUT:
-      return elements.get(OUT).getPads(direction);
+        case OUT:
+            return elements.get(OUT).getPads(direction);
+        }
+        return null;
     }
-    return null;
-  }
-
-  @Override
-  public void validate() {
-    for (Element element : elements.values())
-      element.validate();
-
-    // Check IN element
-    {
-      Element element = get(IN);
-      int outPadsNumber = element.getPads(Direction.OUT).size();
-      int inPadsNumber = element.getPads(Direction.IN).size();
-      if ((outPadsNumber | inPadsNumber) > 0 && (outPadsNumber == 0 || inPadsNumber == 0))
-        throw new RuntimeException("[ " + this + "] Pads of input element of pipeline are not balanced. Element: " + element + ", output pads: "
-            + element.getPads(Direction.OUT).toString() + ", input pads: " + element.getPads(Direction.IN).toString() + ".");
+
+    @Override
+    public void validate() {
+        for (Element element : elements.values())
+            element.validate();
+
+        // Check IN element
+        {
+            Element element = get(IN);
+            int outPadsNumber = element.getPads(Direction.OUT).size();
+            int inPadsNumber = element.getPads(Direction.IN).size();
+            if ((outPadsNumber | inPadsNumber) > 0 && (outPadsNumber == 0 || inPadsNumber == 0))
+                throw new RuntimeException("[ " + this + "] Pads of input element of pipeline are not balanced. Element: " + element + ", output pads: "
+                        + element.getPads(Direction.OUT).toString() + ", input pads: " + element.getPads(Direction.IN).toString() + ".");
+        }
+
+        // Check OUT element
+        {
+            Element element = get(OUT);
+            int outPadsNumber = element.getPads(Direction.OUT).size();
+            int inPadsNumber = element.getPads(Direction.IN).size();
+            if ((outPadsNumber | inPadsNumber) > 0 && (outPadsNumber == 0 || inPadsNumber == 0))
+                throw new RuntimeException("[ " + this + "] Pads of output element of pipeline are not balanced. Element: " + element + ", output pads: "
+                        + element.getPads(Direction.OUT).toString() + ", input pads: " + element.getPads(Direction.IN).toString() + ".");
+        }
+
     }
 
-    // Check OUT element
-    {
-      Element element = get(OUT);
-      int outPadsNumber = element.getPads(Direction.OUT).size();
-      int inPadsNumber = element.getPads(Direction.IN).size();
-      if ((outPadsNumber | inPadsNumber) > 0 && (outPadsNumber == 0 || inPadsNumber == 0))
-        throw new RuntimeException("[ " + this + "] Pads of output element of pipeline are not balanced. Element: " + element + ", output pads: "
-            + element.getPads(Direction.OUT).toString() + ", input pads: " + element.getPads(Direction.IN).toString() + ".");
+    @Override
+    public void dropLink(String padName) {
+        if (elements.get(IN).getLink(padName) != null)
+            elements.get(IN).dropLink(padName);
+
+        if (elements.get(OUT).getLink(padName) != null)
+            elements.get(OUT).dropLink(padName);
     }
 
-  }
-
-  @Override
-  public void dropLink(String padName) {
-    if (elements.get(IN).getLink(padName) != null)
-      elements.get(IN).dropLink(padName);
-
-    if (elements.get(OUT).getLink(padName) != null)
-      elements.get(OUT).dropLink(padName);
-  }
-
-  @Override
-  public void dropLink(Link link) {
-    elements.get(IN).dropLink(link);
-    elements.get(OUT).dropLink(link);
-  }
-
-  @Override
-  public void replaceLink(Link existingLink, Link newLink) {
-    elements.get(IN).replaceLink(existingLink, newLink);
-    elements.get(OUT).replaceLink(existingLink, newLink);
-  }
-
-  @Override
-  public void setLink(String padName, Link link, Direction direction) {
-    // Wire links to internal elements instead
-    elements.get(direction.toString()).setLink(padName, link, direction);
-  }
-
-  @Override
-  public void poll(boolean block) {
-    throw new RuntimeException("Not implemented.");
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    get(IN).handleData(buf, link);
-  }
-
-  @Override
-  public void handleEvent(Event event, Direction direction) {
-    switch (direction) {
-    case IN:
-      get(IN).handleEvent(event, direction);
-      break;
-    case OUT:
-      get(OUT).handleEvent(event, direction);
-      break;
+    @Override
+    public void dropLink(Link link) {
+        elements.get(IN).dropLink(link);
+        elements.get(OUT).dropLink(link);
     }
-  }
 
-  @Override
-  public void add(Element... elements) {
-    for (Element element : elements) {
-      String id = element.getId();
+    @Override
+    public void replaceLink(Link existingLink, Link newLink) {
+        elements.get(IN).replaceLink(existingLink, newLink);
+        elements.get(OUT).replaceLink(existingLink, newLink);
+    }
 
-      if (this.elements.containsKey(id))
-        throw new RuntimeException("This pipeline already contains element with same ID. New element: " + element + ", existing element: "
-            + this.elements.get(id) + ".");
+    @Override
+    public void setLink(String padName, Link link, Direction direction) {
+        // Wire links to internal elements instead
+        elements.get(direction.toString()).setLink(padName, link, direction);
+    }
 
-      this.elements.put(id, element);
+    @Override
+    public void poll(boolean block) {
+        throw new RuntimeException("Not implemented.");
     }
-  }
-  
-  @Override
-  public void link(String... elementNames) {
-
-    if (elementNames.length < 2)
-      throw new RuntimeException("At least two elements are necessary to create link between them.");
-
-    // Parse array of element and pad names
-
-    Element elements[] = new Element[elementNames.length];
-    String inputPads[] = new String[elementNames.length];
-    String outputPads[] = new String[elementNames.length];
-
-    int i = 0;
-    for (String elementName : elementNames) {
-      if (elementName.contains("< ")) {
-        inputPads[i] = elementName.substring(0, elementName.indexOf("< "));
-        elementName = elementName.substring(elementName.indexOf("< ") + 2);
-      } else {
-        inputPads[i] = STDIN;
-      }
-
-      if (elementName.contains(" >")) {
-        outputPads[i] = elementName.substring(elementName.indexOf(" >") + 2);
-        elementName = elementName.substring(0, elementName.indexOf(" >"));
-      } else {
-        outputPads[i] = STDOUT;
-      }
-
-      elements[i] = get(elementName);
-
-      if (elements[i] == null)
-        throw new RuntimeException("Cannot find element by name in this pipeline. Element name: \"" + elementName + "\" (" + elementNames[i] + "), pipeline: "
-            + this + ".");
-
-      i++;
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        get(IN).handleData(buf, link);
     }
 
-    // Link elements
-    for (i = 0; i < elements.length - 1; i++) {
-      Element leftElement = elements[i];
-      Element rightElement = elements[i + 1];
-      String leftPad = outputPads[i];
-      String rightPad = inputPads[i + 1];
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        switch (direction) {
+        case IN:
+            get(IN).handleEvent(event, direction);
+            break;
+        case OUT:
+            get(OUT).handleEvent(event, direction);
+            break;
+        }
+    }
 
-      String linkId = leftElement.getId() + " >" + leftPad + " | " + rightPad + "< " + rightElement.getId();
+    @Override
+    public void add(Element... elements) {
+        for (Element element : elements) {
+            String id = element.getId();
 
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Linking: " + linkId + ".");
+            if (this.elements.containsKey(id))
+                throw new RuntimeException("This pipeline already contains element with same ID. New element: " + element + ", existing element: "
+                        + this.elements.get(id) + ".");
 
-      Link link = new SyncLink(linkId);
-      leftElement.setLink(leftPad, link, Direction.OUT);
-      rightElement.setLink(rightPad, link, Direction.IN);
+            this.elements.put(id, element);
+        }
     }
-  }
 
-  @Override
-  public void addAndLink(Element... elements) {
-    add(elements);
-    link(elements);
-  }
+    @Override
+    public void link(String... elementNames) {
+
+        elementNames = filterOutEmptyStrings(elementNames);
+
+        if (elementNames.length < 2)
+            throw new RuntimeException("At least two elements are necessary to create link between them.");
+
+        // Parse array of element and pad names
+
+        Element elements[] = new Element[elementNames.length];
+        String inputPads[] = new String[elementNames.length];
+        String outputPads[] = new String[elementNames.length];
+
+        int i = 0;
+        for (String elementName : elementNames) {
+            if (elementName.contains("< ")) {
+                inputPads[i] = elementName.substring(0, elementName.indexOf("< "));
+                elementName = elementName.substring(elementName.indexOf("< ") + 2);
+            } else {
+                inputPads[i] = STDIN;
+            }
+
+            if (elementName.contains(" >")) {
+                outputPads[i] = elementName.substring(elementName.indexOf(" >") + 2);
+                elementName = elementName.substring(0, elementName.indexOf(" >"));
+            } else {
+                outputPads[i] = STDOUT;
+            }
+
+            elements[i] = get(elementName);
+
+            if (elements[i] == null)
+                throw new RuntimeException("Cannot find element by name in this pipeline. Element name: \"" + elementName + "\" (" + elementNames[i] + "), pipeline: "
+                        + this + ".");
 
-  private void link(Element... elements) {
-    String elementNames[] = new String[elements.length];
+            i++;
+        }
 
-    int i = 0;
-    for (Element element : elements) {
-      elementNames[i++] = element.getId();
+        // Link elements
+        for (i = 0; i < elements.length - 1; i++) {
+            Element leftElement = elements[i];
+            Element rightElement = elements[i + 1];
+            String leftPad = outputPads[i];
+            String rightPad = inputPads[i + 1];
+
+            String linkId = leftElement.getId() + " >" + leftPad + " | " + rightPad + "< " + rightElement.getId();
+
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Linking: " + linkId + ".");
+
+            Link link = new SyncLink(linkId);
+            leftElement.setLink(leftPad, link, Direction.OUT);
+            rightElement.setLink(rightPad, link, Direction.IN);
+        }
+    }
+
+    /**
+     * Filter out empty strings from array and return new array with non-empty
+     * elements only. If array contains no empty string, returns same array.
+     */
+    private String[] filterOutEmptyStrings(String[] strings) {
+
+        boolean found = false;
+        for (String string : strings) {
+            if (string == null || string.isEmpty()) {
+                found = true;
+                break;
+            }
+        }
+
+        if (!found)
+            return strings;
+
+        List<String> filteredStrings = new ArrayList<String>(strings.length);
+        for (String string : strings)
+            if (string != null && !string.isEmpty())
+                filteredStrings.add(string);
+        return filteredStrings.toArray(new String[filteredStrings.size()]);
+    }
+
+    @Override
+    public void addAndLink(Element... elements) {
+        add(elements);
+        link(elements);
+    }
+
+    private void link(Element... elements) {
+        String elementNames[] = new String[elements.length];
+
+        int i = 0;
+        for (Element element : elements) {
+            elementNames[i++] = element.getId();
+        }
+
+        link(elementNames);
     }
 
-    link(elementNames);
-  }
+    @Override
+    public Element get(String elementName) {
+        return elements.get(elementName);
+    }
 
-  @Override
-  public Element get(String elementName) {
-    return elements.get(elementName);
-  }
+    @Override
+    public Link getLink(String elementName, String padName) {
+        return elements.get(elementName).getLink(padName);
 
-  @Override
-  public Link getLink(String elementName, String padName) {
-    return elements.get(elementName).getLink(padName);
+    }
 
-  }
+    @Override
+    public void setLink(String elementName, String padName, Link link, Direction direction) {
+        elements.get(elementName).setLink(padName, link, direction);
+    }
 
-  @Override
-  public void setLink(String elementName, String padName, Link link, Direction direction) {
-    elements.get(elementName).setLink(padName, link, direction);
-  }
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public void runMainLoop(String elementName, String padName, boolean separateThread, boolean waitForStartEvent) {
+        validate();
 
-  @Override
-  public String getId() {
-    return id;
-  }
+        Link link = getLink(elementName, padName);
 
-  @Override
-  public void runMainLoop(String elementName, String padName, boolean separateThread, boolean waitForStartEvent) {
-    validate();
+        if (link == null)
+            throw new NullPointerException("Cannot find link. Element name: " + elementName + ", element: " + get(elementName) + ", pad: " + padName + ".");
 
-    Link link = getLink(elementName, padName);
+        if (!waitForStartEvent)
+            link.sendEvent(Event.STREAM_START, Direction.OUT);
 
-    if (link == null)
-      throw new NullPointerException("Cannot find link. Element name: " + elementName + ", element: " + get(elementName) + ", pad: " + padName + ".");
+        if (separateThread) {
+            Thread thread = new Thread(link);
+            thread.setDaemon(true);
+            thread.start();
+        } else {
+            link.run();
+        }
+    }
 
-    if (!waitForStartEvent)
-      link.sendEvent(Event.STREAM_START, Direction.OUT);
+    @Override
+    public String toString() {
+        return "Pipeline(" + id + ")";
+    }
 
-    if (separateThread) {
-      Thread thread = new Thread(link);
-      thread.setDaemon(true);
-      thread.start();
-    } else {
-      link.run();
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        // System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        Pipeline pipeline = new PipelineImpl("main");
+
+        // Create elements
+        pipeline.add(new FakeSource("source") {
+            {
+                incommingBufLength = 3;
+                numBuffers = 10;
+                delay = 100;
+            }
+        });
+        pipeline.add(new BaseElement("tee"));
+        pipeline.add(new FakeSink("sink") {
+            {
+                verbose = true;
+            }
+        });
+        pipeline.add(new FakeSink("sink2") {
+            {
+                verbose = true;
+            }
+        });
+
+        // Link elements
+        pipeline.link("source", "tee", "sink");
+        pipeline.link("tee >out2", "sink2");
+
+        // Run main loop
+        pipeline.runMainLoop("source", STDOUT, false, false);
     }
-  }
-
-  @Override
-  public String toString() {
-    return "Pipeline(" + id + ")";
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    // System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    Pipeline pipeline = new PipelineImpl("main");
-
-    // Create elements
-    pipeline.add(new FakeSource("source") {
-      {
-        this.incommingBufLength = 3;
-        this.numBuffers = 10;
-        this.delay = 100;
-      }
-    });
-    pipeline.add(new BaseElement("tee"));
-    pipeline.add(new FakeSink("sink") {
-      {
-        this.verbose = true;
-      }
-    });
-    pipeline.add(new FakeSink("sink2") {
-      {
-        this.verbose = true;
-      }
-    });
-
-    // Link elements
-    pipeline.link("source", "tee", "sink");
-    pipeline.link("tee >out2", "sink2");
-
-    // Run main loop
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Queue.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Queue.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Queue.java
old mode 100644
new mode 100755
index 7a17340..ed952ce
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Queue.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Queue.java
@@ -19,118 +19,120 @@ package streamer;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
+import streamer.debug.FakeSink;
+import streamer.debug.FakeSource;
+
 /**
  * Message queue for safe transfer of packets between threads.
  */
 public class Queue extends BaseElement {
 
-  protected LinkedBlockingQueue<ByteBuffer> queue = new LinkedBlockingQueue<ByteBuffer>();
-
-  public Queue(String id) {
-    super(id);
-  }
-
-  @SuppressWarnings("incomplete-switch")
-  @Override
-  public void poll(boolean block) {
-    try {
-      ByteBuffer buf = null;
-      if (block) {
-        buf = queue.take();
-      } else {
-        buf = queue.poll(100, TimeUnit.MILLISECONDS);
-      }
-
-      if (buf != null)
-        pushDataToAllOuts(buf);
-
-    } catch (Exception e) {
-      sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
-      closeQueue();
+    protected LinkedBlockingQueue<ByteBuffer> queue = new LinkedBlockingQueue<ByteBuffer>();
+
+    public Queue(String id) {
+        super(id);
+    }
+
+    @Override
+    public void poll(boolean block) {
+        try {
+            ByteBuffer buf = null;
+            if (block) {
+                buf = queue.take();
+            } else {
+                buf = queue.poll(100, TimeUnit.MILLISECONDS);
+            }
+
+            if (buf != null)
+                pushDataToAllOuts(buf);
+
+        } catch (Exception e) {
+            sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
+            closeQueue();
+        }
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Put incoming data into queue
+        try {
+            queue.put(buf);
+        } catch (Exception e) {
+            sendEventToAllPads(Event.STREAM_CLOSE, Direction.IN);
+            closeQueue();
+        }
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        switch (event) {
+        case LINK_SWITCH_TO_PULL_MODE:
+            // Do not propagate this event, because this element is boundary between
+            // threads
+            break;
+        default:
+            super.handleEvent(event, direction);
+        }
+    }
+
+    @Override
+    protected void onClose() {
+        super.onClose();
+        closeQueue();
     }
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    // Put incoming data into queue
-    try {
-      queue.put(buf);
-    } catch (Exception e) {
-      sendEventToAllPads(Event.STREAM_CLOSE, Direction.IN);
-      closeQueue();
+
+    private void closeQueue() {
+        queue.clear();
+        queue.add(null);
+        // Drop queue to indicate that upstream is closed.
+        // May produce NPE in poll().
+        queue = null;
     }
-  }
-
-  @Override
-  public void handleEvent(Event event, Direction direction) {
-    switch (event) {
-    case LINK_SWITCH_TO_PULL_MODE:
-      // Do not propagate this event, because this element is boundary between
-      // threads
-      break;
-    default:
-      super.handleEvent(event, direction);
+
+    @Override
+    public String toString() {
+        return "Queue(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+
+        Element source1 = new FakeSource("source1") {
+            {
+                this.delay = 100;
+                this.numBuffers = 10;
+                this.incommingBufLength = 10;
+            }
+        };
+
+        Element source2 = new FakeSource("source2") {
+            {
+                this.delay = 100;
+                this.numBuffers = 10;
+                this.incommingBufLength = 10;
+            }
+        };
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source1);
+        pipeline.add(source2);
+        pipeline.add(new Queue("queue"));
+        pipeline.add(new FakeSink("sink"));
+
+        // Main flow
+        pipeline.link("source1", "in1< queue");
+        pipeline.link("source2", "in2< queue");
+        pipeline.link("queue", "sink");
+
+        new Thread(pipeline.getLink("source1", STDOUT)).start();
+        new Thread(pipeline.getLink("source2", STDOUT)).start();
+        pipeline.getLink("sink", STDIN).run();
     }
-  }
-
-  @Override
-  protected void onClose() {
-    super.onClose();
-    closeQueue();
-  }
-
-  private void closeQueue() {
-    queue.clear();
-    queue.add(null);
-    // Drop queue to indicate that upstream is closed.
-    // May produce NPE in poll().
-    queue = null;
-  }
-
-  @Override
-  public String toString() {
-    return "Queue(" + id + ")";
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-
-    Element source1 = new FakeSource("source1") {
-      {
-        this.delay = 100;
-        this.numBuffers = 10;
-        this.incommingBufLength = 10;
-      }
-    };
-
-    Element source2 = new FakeSource("source2") {
-      {
-        this.delay = 100;
-        this.numBuffers = 10;
-        this.incommingBufLength = 10;
-      }
-    };
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source1);
-    pipeline.add(source2);
-    pipeline.add(new Queue("queue"));
-    pipeline.add(new FakeSink("sink"));
-
-    // Main flow
-    pipeline.link("source1", "in1< queue");
-    pipeline.link("source2", "in2< queue");
-    pipeline.link("queue", "sink");
-
-    new Thread(pipeline.getLink("source1", STDOUT)).start();
-    new Thread(pipeline.getLink("source2", STDOUT)).start();
-    pipeline.getLink("sink", STDIN).run();
-  }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapper.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapper.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapper.java
old mode 100644
new mode 100755
index c23edd8..22d436e
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapper.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapper.java
@@ -16,224 +16,20 @@
 // under the License.
 package streamer;
 
-import static rdpclient.MockServer.Packet.PacketType.CLIENT;
-import static rdpclient.MockServer.Packet.PacketType.SERVER;
-
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.HashMap;
-
-import javax.net.SocketFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-
-import rdpclient.MockServer;
-import rdpclient.MockServer.Packet;
-import rdpclient.TrustAllX509TrustManager;
-
-public class SocketWrapper extends PipelineImpl {
-
-  protected InputStreamSource source;
-  protected OutputStreamSink sink;
-  protected Socket socket;
-  protected InetSocketAddress address;
-
-  protected SSLSocket sslSocket;
-
-  //protected String SSL_VERSION_TO_USE = "TLSv1.2";
-  /*DEBUG*/protected String SSL_VERSION_TO_USE = "TLSv1";
-
-  public SocketWrapper(String id) {
-    super(id);
-  }
-
-  @Override
-  protected HashMap<String, Element> initElementMap(String id) {
-    HashMap<String, Element> map = new HashMap<String, Element>();
-
-    source = new InputStreamSource(id + "." + OUT, this);
-    sink = new OutputStreamSink(id + "." + IN, this);
-
-    // Pass requests to read data to socket input stream
-    map.put(OUT, source);
-
-    // All incoming data, which is sent to this socket wrapper, will be sent
-    // to socket remote
-    map.put(IN, sink);
-
-    return map;
-  }
-
-  /**
-   * Connect this socket wrapper to remote server and start main loop on
-   * IputStreamSource stdout link, to watch for incoming data, and
-   * OutputStreamSink stdin link, to pull for outgoing data.
-   * 
-   * @param address
-   * @throws IOException
-   */
-  public void connect(InetSocketAddress address) throws IOException {
-    this.address = address;
-
-    // Connect socket to server
-    socket = SocketFactory.getDefault().createSocket();
-    try {
-      socket.connect(address);
-
-      InputStream is = socket.getInputStream();
-      source.setInputStream(is);
-
-      OutputStream os = socket.getOutputStream();
-      sink.setOutputStream(os);
-
-      // Start polling for data to send to remote sever
-      runMainLoop(IN, STDIN, true, true);
-
-      // Push incoming data from server to handlers
-      runMainLoop(OUT, STDOUT, false, false);
-
-    } finally {
-      socket.close();
-    }
-  }
-
-  @Override
-  public void handleEvent(Event event, Direction direction) {
-    switch (event) {
-    case SOCKET_UPGRADE_TO_SSL:
-      upgradeToSsl();
-      break;
-    default:
-      super.handleEvent(event, direction);
-      break;
-    }
-  }
-
-  public void upgradeToSsl() {
-
-    if (sslSocket != null)
-      // Already upgraded
-      return;
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Upgrading socket to SSL.");
-
-    try {
-      // Use most secure implementation of SSL available now.
-      // JVM will try to negotiate TLS1.2, then will fallback to TLS1.0, if
-      // TLS1.2 is not supported.
-      SSLContext sslContext = SSLContext.getInstance(SSL_VERSION_TO_USE);
-
-      // Trust all certificates (FIXME: insecure)
-      sslContext.init(null, new TrustManager[] { new TrustAllX509TrustManager() }, null);
-
-      SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
-      sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, address.getHostName(), address.getPort(), true);
-      sslSocket.startHandshake();
-
-      InputStream sis = sslSocket.getInputStream();
-      source.setInputStream(sis);
-
-      OutputStream sos = sslSocket.getOutputStream();
-      sink.setOutputStream(sos);
-
-    } catch (Exception e) {
-      throw new RuntimeException("Cannot upgrade socket to SSL: " + e.getMessage(), e);
-    }
-
-  }
-
-  @Override
-  public void validate() {
-    for (Element element : elements.values())
-      element.validate();
-
-    if (get(IN).getPads(Direction.IN).size() == 0)
-      throw new RuntimeException("[ " + this + "] Input of socket is not connected.");
-
-    if (get(OUT).getPads(Direction.OUT).size() == 0)
-      throw new RuntimeException("[ " + this + "] Output of socket is not connected.");
-
-  }
-
-  public void shutdown() {
-    try {
-      handleEvent(Event.STREAM_CLOSE, Direction.IN);
-    } catch (Exception e) {
-    }
-    try {
-      handleEvent(Event.STREAM_CLOSE, Direction.OUT);
-    } catch (Exception e) {
-    }
-    try {
-      if (sslSocket != null)
-        sslSocket.close();
-    } catch (Exception e) {
-    }
-    try {
-      socket.close();
-    } catch (Exception e) {
-    }
-  }
-
-  @Override
-  public String toString() {
-    return "SocketWrapper(" + id + ")";
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    try {
-      System.setProperty("streamer.Link.debug", "true");
-      System.setProperty("streamer.Element.debug", "true");
-      System.setProperty("rdpclient.MockServer.debug", "true");
-
-      Pipeline pipeline = new PipelineImpl("echo client");
-
-      SocketWrapper socketWrapper = new SocketWrapper("socket");
-
-      pipeline.add(socketWrapper);
-      pipeline.add(new BaseElement("echo"));
 
-      pipeline.link("socket", "echo", "socket");
+public interface SocketWrapper extends Element {
 
-      final byte[] mockData = new byte[] { 0x01, 0x02, 0x03 };
-      MockServer server = new MockServer(new Packet[] { new Packet("Server hello") {
-        {
-          type = SERVER;
-          data = mockData;
-        }
-      }, new Packet("Client hello") {
-        {
-          type = CLIENT;
-          data = mockData;
-        }
-      }, new Packet("Server hello") {
-        {
-          type = SERVER;
-          data = mockData;
-        }
-      }, new Packet("Client hello") {
-        {
-          type = CLIENT;
-          data = mockData;
-        }
-      } });
-      server.start();
-      InetSocketAddress address = server.getAddress();
+    /**
+     * Connect this socket wrapper to remote server and start main loop on
+     * Source stdout link, to watch for incoming data, and
+     * Sink stdin link, to pull for outgoing data.
+     */
+    public void connect(InetSocketAddress address) throws IOException;
 
-      socketWrapper.connect(address);
+    public void shutdown();
 
-    } catch (IOException e) {
-      e.printStackTrace(System.err);
-    }
+    void upgradeToSsl();
 
-  }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapperImpl.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapperImpl.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapperImpl.java
new file mode 100755
index 0000000..07b3dc9
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapperImpl.java
@@ -0,0 +1,250 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer;
+
+import static streamer.debug.MockServer.Packet.PacketType.CLIENT;
+import static streamer.debug.MockServer.Packet.PacketType.SERVER;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.HashMap;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+import streamer.debug.MockServer;
+import streamer.debug.MockServer.Packet;
+import streamer.ssl.SSLState;
+import streamer.ssl.TrustAllX509TrustManager;
+
+public class SocketWrapperImpl extends PipelineImpl implements SocketWrapper {
+
+    protected InputStreamSource source;
+    protected OutputStreamSink sink;
+    protected Socket socket;
+    protected InetSocketAddress address;
+
+    protected SSLSocket sslSocket;
+
+    protected String SSL_VERSION_TO_USE = "TLSv1.2";
+    //protected String SSL_VERSION_TO_USE = "SSLv3";
+
+    protected SSLState sslState;
+
+    public SocketWrapperImpl(String id, SSLState sslState) {
+        super(id);
+        this.sslState = sslState;
+    }
+
+    @Override
+    protected HashMap<String, Element> initElementMap(String id) {
+        HashMap<String, Element> map = new HashMap<String, Element>();
+
+        source = new InputStreamSource(id + "." + OUT, this);
+        sink = new OutputStreamSink(id + "." + IN, this);
+
+        // Pass requests to read data to socket input stream
+        map.put(OUT, source);
+
+        // All incoming data, which is sent to this socket wrapper, will be sent
+        // to socket remote
+        map.put(IN, sink);
+
+        return map;
+    }
+
+    /**
+     * Connect this socket wrapper to remote server and start main loop on
+     * IputStreamSource stdout link, to watch for incoming data, and
+     * OutputStreamSink stdin link, to pull for outgoing data.
+     * 
+     * @param address
+     * @throws IOException
+     */
+    @Override
+    public void connect(InetSocketAddress address) throws IOException {
+        this.address = address;
+
+        // Connect socket to server
+        socket = SocketFactory.getDefault().createSocket();
+        try {
+            socket.connect(address);
+
+            InputStream is = socket.getInputStream();
+            source.setInputStream(is);
+
+            OutputStream os = socket.getOutputStream();
+            sink.setOutputStream(os);
+
+            // Start polling for data to send to remote sever
+            runMainLoop(IN, STDIN, true, true);
+
+            // Push incoming data from server to handlers
+            runMainLoop(OUT, STDOUT, false, false);
+
+        } finally {
+            socket.close();
+        }
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        switch (event) {
+        case SOCKET_UPGRADE_TO_SSL:
+            upgradeToSsl();
+            break;
+        default:
+            super.handleEvent(event, direction);
+            break;
+        }
+    }
+
+    @Override
+    public void upgradeToSsl() {
+
+        if (sslSocket != null)
+            // Already upgraded
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Upgrading socket to SSL.");
+
+        try {
+            // Use most secure implementation of SSL available now.
+            // JVM will try to negotiate TLS1.2, then will fallback to TLS1.0, if
+            // TLS1.2 is not supported.
+            SSLContext sslContext = SSLContext.getInstance(SSL_VERSION_TO_USE);
+
+            // Trust all certificates (FIXME: insecure)
+            sslContext.init(null, new TrustManager[] {new TrustAllX509TrustManager(sslState)}, null);
+
+            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+            sslSocket = (SSLSocket)sslSocketFactory.createSocket(socket, address.getHostName(), address.getPort(), true);
+
+            sslSocket.startHandshake();
+
+            InputStream sis = sslSocket.getInputStream();
+            source.setInputStream(sis);
+
+            OutputStream sos = sslSocket.getOutputStream();
+            sink.setOutputStream(sos);
+
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot upgrade socket to SSL: " + e.getMessage(), e);
+        }
+
+    }
+
+    @Override
+    public void validate() {
+        for (Element element : elements.values())
+            element.validate();
+
+        if (get(IN).getPads(Direction.IN).size() == 0)
+            throw new RuntimeException("[ " + this + "] Input of socket is not connected.");
+
+        if (get(OUT).getPads(Direction.OUT).size() == 0)
+            throw new RuntimeException("[ " + this + "] Output of socket is not connected.");
+
+    }
+
+    @Override
+    public void shutdown() {
+        try {
+            handleEvent(Event.STREAM_CLOSE, Direction.IN);
+        } catch (Exception e) {
+        }
+        try {
+            handleEvent(Event.STREAM_CLOSE, Direction.OUT);
+        } catch (Exception e) {
+        }
+        try {
+            if (sslSocket != null)
+                sslSocket.close();
+        } catch (Exception e) {
+        }
+        try {
+            socket.close();
+        } catch (Exception e) {
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "SocketWrapper(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        try {
+            System.setProperty("streamer.Link.debug", "true");
+            System.setProperty("streamer.Element.debug", "true");
+            System.setProperty("rdpclient.MockServer.debug", "true");
+
+            Pipeline pipeline = new PipelineImpl("echo client");
+
+            SocketWrapperImpl socketWrapper = new SocketWrapperImpl("socket", null);
+
+            pipeline.add(socketWrapper);
+            pipeline.add(new BaseElement("echo"));
+            pipeline.add(new Queue("queue")); // To decouple input and output
+
+            pipeline.link("socket", "echo", "queue", "socket");
+
+            final byte[] mockData = new byte[] {0x01, 0x02, 0x03};
+            MockServer server = new MockServer(new Packet[] {new Packet("Server hello") {
+                {
+                    type = SERVER;
+                    data = mockData;
+                }
+            }, new Packet("Client hello") {
+                {
+                    type = CLIENT;
+                    data = mockData;
+                }
+            }, new Packet("Server hello") {
+                {
+                    type = SERVER;
+                    data = mockData;
+                }
+            }, new Packet("Client hello") {
+                {
+                    type = CLIENT;
+                    data = mockData;
+                }
+            }});
+            server.start();
+            InetSocketAddress address = server.getAddress();
+
+            /*DEBUG*/System.out.println("Address: " + address);
+            socketWrapper.connect(address);
+
+        } catch (Exception e) {
+            e.printStackTrace(System.err);
+        }
+
+    }
+}


[13/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmCompute.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmCompute.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmCompute.java
new file mode 100755
index 0000000..1ac220d
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmCompute.java
@@ -0,0 +1,23 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp;
+
+public class NtlmCompute {
+
+    public void compute_ntlm_v2_hash() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmConstants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmConstants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmConstants.java
new file mode 100755
index 0000000..e096626
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmConstants.java
@@ -0,0 +1,157 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp;
+
+public interface NtlmConstants {
+
+    /**
+     * Attribute type: Indicates that this is the last AV_PAIR in the list. AvLen
+     * MUST be 0. This type of information MUST be present in the AV pair list.
+     */
+    public final static int MSV_AV_EOL = 0x0000;
+
+    /**
+     * Attribute type: The server's NetBIOS computer name. The name MUST be in
+     * Unicode, and is not null-terminated. This type of information MUST be
+     * present in the AV_pair list.
+     */
+    public final static int MSV_AV_NETBIOS_COMPUTER_NAME = 0x0001;
+
+    /**
+     * Attribute type: The server's NetBIOS domain name. The name MUST be in
+     * Unicode, and is not null-terminated. This type of information MUST be
+     * present in the AV_pair list.
+     */
+    public final static int MSV_AV_NETBIOS_DOMAIN_NAME = 0x0002;
+
+    /**
+     * Attribute type: The fully qualified domain name (FQDN (1)) of the computer.
+     * The name MUST be in Unicode, and is not null-terminated.
+     */
+    public final static int MSV_AV_DNS_COMPUTER_NAME = 0x0003;
+
+    /**
+     * Attribute type: The FQDN of the domain. The name MUST be in Unicode, and is
+     * not null-terminated.
+     */
+    public final static int MSV_AV_DNS_DOMAIN_NAME = 0x0004;
+
+    /**
+     * Attribute type: The FQDN of the forest. The name MUST be in Unicode, and is
+     * not null-terminated.
+     */
+    public final static int MSV_AV_DNS_TREE_NAME = 0x0005;
+
+    /**
+     * Attribute type: A 32-bit value indicating server or client configuration.
+     * 
+     * <li>0x00000001: indicates to the client that the account authentication is
+     * constrained.
+     * 
+     * <li>0x00000002: indicates that the client is providing message integrity in
+     * the MIC field (section 2.2.1.3) in the AUTHENTICATE_MESSAGE.
+     * 
+     * <li>0x00000004: indicates that the client is providing a target SPN
+     * generated from an untrusted source.
+     **/
+    public final static int MSV_AV_FLAGS = 0x0006;
+
+    public static final int MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK = 0x00000002;
+
+    /**
+     * Attribute type: A FILETIME structure ([MS-DTYP] section 2.3.3) in
+     * little-endian byte order that contains the server local time.
+     */
+    public final static int MSV_AV_TIMESTAMP = 0x0007;
+
+    /**
+     * Attribute type: A Single_Host_Data (section 2.2.2.2) structure. The Value
+     * field contains a platform-specific blob, as well as a MachineID created at
+     * computer startup to identify the calling machine.<15>
+     */
+    public final static int MSV_AV_SINGLE_HOST = 0x0008;
+
+    /**
+     * Attribute type: The SPN of the target server. The name MUST be in Unicode
+     * and is not null-terminated.<16>
+     */
+    public final static int MSV_AV_TARGET_NAME = 0x0009;
+
+    /**
+     * Attribute type: A channel bindings hash. The Value field contains an MD5
+     * hash ([RFC4121] section 4.1.1.2) of a gss_channel_bindings_struct
+     * ([RFC2744] section 3.11). An all-zero value of the hash is used to indicate
+     * absence of channel bindings.
+     */
+    public final static int MSV_AV_CHANNEL_BINDINGS = 0x000A;
+
+    /**
+     * Signature of NTLMSSP blob.
+     */
+    public static final String NTLMSSP = "NTLMSSP";
+
+    public static final String GSS_RDP_SERVICE_NAME = "TERMSRV";
+
+    /**
+     * NTLM message type: NEGOTIATE.
+     */
+    public static final int NEGOTIATE = 0x00000001;
+
+    /**
+     * NTLM message type: CHALLENGE.
+     */
+    public static final int CHALLENGE = 0x00000002;
+
+    /**
+     * NTLM message type: NTLMSSP_AUTH.
+     */
+    public static final int NTLMSSP_AUTH = 0x00000003;
+
+    public static final String OID_SPNEGO = "1.3.6.1.5.5.2";
+
+    public static final String OID_KERBEROS5 = "1.2.840.113554.1.2.2";
+    public static final String OID_MSKERBEROS5 = "1.2.840.48018.1.2.2";
+
+    public static final String OID_KRB5USERTOUSER = "1.2.840.113554.1.2.2.3";
+
+    public static final String OID_NTLMSSP = "1.3.6.1.4.1.311.2.2.10";
+
+    /**
+     * Magic constant used in calculation of Lan Manager response.
+     */
+    public static final String LM_MAGIC = "KGS!@#$%";
+
+    /**
+     * Magic constant used in generation of client signing key.
+     */
+    public static final String CLIENT_SIGN_MAGIC = "session key to client-to-server signing key magic constant";
+
+    /**
+     * Magic constant used in generation of client sealing key.
+     */
+    public static final String CLIENT_SEAL_MAGIC = "session key to client-to-server sealing key magic constant";
+
+    public static final String SERVER_SIGN_MAGIC = "session key to server-to-client signing key magic constant";
+    public static final String SERVER_SEAL_MAGIC = "session key to server-to-client sealing key magic constant";
+
+    /**
+     * In Windows XP, Windows Server 2003, Windows Vista, Windows Server 2008,
+     * Windows 7, Windows Server 2008 R2, Windows 8, Windows Server 2012, Windows
+     * 8.1, and Windows Server 2012 R2, the maximum lifetime of challenge is 36 hours.
+     */
+    public static final int CHALLENGE_MAX_LIFETIME = 36 * 60 * 60;
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmState.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmState.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmState.java
new file mode 100755
index 0000000..5b4f36e
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmState.java
@@ -0,0 +1,887 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp;
+
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+
+public class NtlmState implements NtlmConstants {
+
+    /**
+     * The set of configuration flags (section 2.2.2.5) that specifies the
+     * negotiated capabilities of the client and server for the current NTLM
+     * session.
+     */
+    public NegoFlags negotiatedFlags;
+
+    /**
+     * Target Information extracted from Type2 server response.
+     */
+    public byte[] serverTargetInfo;
+
+    /**
+     * Challenge extracted from Type2 server response.
+     */
+    public byte[] serverChallenge;
+
+    public byte[] clientChallenge;
+
+    public byte[] keyExchangeKey;
+
+    /**
+     * A 128-bit (16-byte) session key used to derive ClientSigningKey,
+     * ClientSealingKey, ServerSealingKey, and ServerSigningKey.
+     */
+    public byte[] exportedSessionKey;
+
+    /**
+     * The signing key used by the client to sign messages and used by the server
+     * to verify signed client messages. It is generated after the client is
+     * authenticated by the server and is not passed over the wire.
+     */
+    public byte[] clientSigningKey;
+
+    /**
+     * The sealing key used by the client to seal messages and used by the server
+     * to unseal client messages. It is generated after the client is
+     * authenticated by the server and is not passed over the wire.
+     */
+    public byte[] clientSealingKey;
+
+    public byte[] encryptedRandomSessionKey;
+
+    public byte[] sessionBaseKey;
+
+    public byte[] responseKeyNT;
+
+    public byte[] ntProofStr;
+
+    public String domain;
+
+    public String user;
+
+    public String workstation;
+
+    public String password;
+
+    public String serverNetbiosDomainName;
+
+    public String serverNetbiosComputerName;
+
+    public String serverDnsDomainName;
+
+    public String serverDnsComputerName;
+
+    public String serverDnsTreeName;
+
+    public String serverTargetName;
+
+    public byte[] serverTimestamp;
+    public byte[] clientChallengeTimestamp;
+
+    public byte[] lmChallengeResponse;
+
+    public byte[] ntChallengeResponse;
+
+    public byte[] nt_proof_str;
+
+    public byte[] randomSessionKey;
+
+    public byte[] serverSigningKey;
+
+    public byte[] serverSealingKey;
+
+    public byte[] sendSigningKey;
+
+    public byte[] recvSigningKey;
+
+    public byte[] sendSealingKey;
+
+    public byte[] recvSealingKey;
+
+    public Cipher sendRc4Seal;
+
+    public Cipher recvRc4Seal;
+
+    public byte[] messageIntegrityCheck;
+
+    public byte[] negotiateMessage;
+
+    public byte[] challengeMessage;
+
+    public byte[] authenticateMessage;
+
+    /**
+     * A 4-byte sequence number.
+     * 
+     * In the case of connection-oriented authentication, the SeqNum parameter
+     * MUST start at 0 and is incremented by one for each message sent. The
+     * receiver expects the first received message to have SeqNum equal to 0, and
+     * to be one greater for each subsequent message received. If a received
+     * message does not contain the expected SeqNum, an error MUST be returned to
+     * the receiving application, and SeqNum is not incremented.
+     */
+    public int sendSeqNum;
+    public int recvSeqNum;
+
+    public byte[] authenticateTargetInfo;
+
+    public String servicePrincipalName;
+
+    private byte[] channelBindingsHash = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+    public byte[] subjectPublicKey;
+
+    public byte[] ntlm_generate_timestamp() {
+        clientChallengeTimestamp = serverTimestamp;
+        return clientChallengeTimestamp;
+    }
+
+    /**
+     * MD4(UNICODE(Password))
+     */
+    public byte[] NTOWFv1W(String password) {
+        return CryptoAlgos.MD4(password.getBytes(RdpConstants.CHARSET_16));
+    }
+
+    public void testNTOWFv1W() {
+        byte[] expected = new byte[] {(byte)0x25, (byte)0xf3, (byte)0x39, (byte)0xc9, (byte)0x86, (byte)0xb5, (byte)0xc2, (byte)0x6f, (byte)0xdc,
+                (byte)0xab, (byte)0x91, (byte)0x34, (byte)0x93, (byte)0xa2, (byte)0x18, (byte)0x2a};
+        byte[] actual = NTOWFv1W("R2Preview!");
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    /**
+     * HMAC_MD5(NTOWFv1W(Password), UNICODE(ConcatenationOf(UpperCase(User),
+     * Domain)))
+     */
+    public byte[] NTOWFv2W(String password, String user, String domain) {
+        return CryptoAlgos.HMAC_MD5(NTOWFv1W(password), (user.toUpperCase() + domain).getBytes(RdpConstants.CHARSET_16));
+    }
+
+    public void testNTOWFv2W() {
+        byte[] expected = new byte[] {(byte)0x5f, (byte)0xcc, (byte)0x4c, (byte)0x48, (byte)0x74, (byte)0x6b, (byte)0x94, (byte)0xce, (byte)0xb7,
+                (byte)0xae, (byte)0xf1, (byte)0x0d, (byte)0xc9, (byte)0x11, (byte)0x22, (byte)0x8f,};
+        byte[] actual = NTOWFv2W("R2Preview!", "Administrator", "workgroup");
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_compute_ntlm_v2_hash() {
+        return NTOWFv2W(password, user, domain);
+    }
+
+    public byte[] ntlm_generate_client_challenge() {
+        if (clientChallenge == null) {
+            clientChallenge = CryptoAlgos.NONCE(8);
+        }
+        return clientChallenge;
+    }
+
+    public byte[] ntlm_compute_lm_v2_response() {
+        if (lmChallengeResponse == null) {
+
+            byte[] ntlm_v2_hash = ntlm_compute_ntlm_v2_hash();
+
+            ntlm_generate_client_challenge();
+
+            byte[] challenges = CryptoAlgos.concatenationOf(serverChallenge, clientChallenge);
+
+            lmChallengeResponse = CryptoAlgos.concatenationOf(CryptoAlgos.HMAC_MD5(ntlm_v2_hash, challenges), clientChallenge);
+        }
+
+        return lmChallengeResponse;
+    }
+
+    public void testComputeLmV2Response() {
+        serverChallenge = new byte[] {(byte)0x34, (byte)0xe4, (byte)0x4c, (byte)0xd5, (byte)0x75, (byte)0xe3, (byte)0x43, (byte)0x0f};
+        clientChallenge = new byte[] {1, 2, 3, 4, 5, 6, 7, 8};
+        password = "R2Preview!";
+        user = "Administrator";
+        domain = "workgroup";
+        byte[] expected = new byte[] {(byte)0xa8, (byte)0xae, (byte)0xd7, (byte)0x46, (byte)0x06, (byte)0x32, (byte)0x02, (byte)0x35, (byte)0x1d,
+                (byte)0x95, (byte)0x99, (byte)0x36, (byte)0x20, (byte)0x36, (byte)0xac, (byte)0xc3, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+                (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08,};
+        byte[] actual = ntlm_compute_lm_v2_response();
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] computeNtProofStr(byte[] ntlm_v2_hash, byte[] data) {
+        return CryptoAlgos.HMAC_MD5(ntlm_v2_hash, data);
+    }
+
+    public void testComputeNtProofStr() {
+        byte[] ntlm_v2_hash = new byte[] {(byte)0x5f, (byte)0xcc, (byte)0x4c, (byte)0x48, (byte)0x74, (byte)0x6b, (byte)0x94, (byte)0xce, (byte)0xb7,
+                (byte)0xae, (byte)0xf1, (byte)0x0d, (byte)0xc9, (byte)0x11, (byte)0x22, (byte)0x8f,};
+        byte[] data = new byte[] {(byte)0x4a, (byte)0x25, (byte)0x50, (byte)0xa5, (byte)0x11, (byte)0x9b, (byte)0xd6, (byte)0x16, (byte)0x01,
+                (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c,
+                (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07,
+                (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00,
+                (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34,
+                (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57,
+                (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00,
+                (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c,
+                (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x1e, (byte)0x00,
+                (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f,
+                (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00,
+                (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x1e,
+                (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32,
+                (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x07, (byte)0x00,
+                (byte)0x08, (byte)0x00, (byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x06,
+                (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x10, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x26, (byte)0x00, (byte)0x54, (byte)0x00,
+                (byte)0x45, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x4d, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x56,
+                (byte)0x00, (byte)0x2f, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x2e, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x36, (byte)0x00, (byte)0x38, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x2e,
+                (byte)0x00, (byte)0x33, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,};
+
+        byte[] expected = new byte[] {(byte)0x19, (byte)0x4b, (byte)0xeb, (byte)0xad, (byte)0xda, (byte)0x24, (byte)0xd5, (byte)0x96, (byte)0x85,
+                (byte)0x2e, (byte)0x24, (byte)0x94, (byte)0xd6, (byte)0x4a, (byte)0xb8, (byte)0x5e,};
+        byte[] actual = computeNtProofStr(ntlm_v2_hash, data);
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] computeSessionBaseKey(byte[] ntlm_v2_hash, byte[] nt_proof_str) {
+        return CryptoAlgos.HMAC_MD5(ntlm_v2_hash, nt_proof_str);
+    }
+
+    public void testComputeSessionBaseKey() {
+        byte[] ntlm_v2_hash = new byte[] {(byte)0x5f, (byte)0xcc, (byte)0x4c, (byte)0x48, (byte)0x74, (byte)0x6b, (byte)0x94, (byte)0xce, (byte)0xb7,
+                (byte)0xae, (byte)0xf1, (byte)0x0d, (byte)0xc9, (byte)0x11, (byte)0x22, (byte)0x8f,};
+        byte[] nt_proof_str = new byte[] {(byte)0x19, (byte)0x4b, (byte)0xeb, (byte)0xad, (byte)0xda, (byte)0x24, (byte)0xd5, (byte)0x96, (byte)0x85,
+                (byte)0x2e, (byte)0x24, (byte)0x94, (byte)0xd6, (byte)0x4a, (byte)0xb8, (byte)0x5e,};
+
+        byte[] expected = new byte[] {(byte)0x8e, (byte)0x0f, (byte)0xdd, (byte)0x12, (byte)0x4c, (byte)0x3b, (byte)0x11, (byte)0x7f, (byte)0x22,
+                (byte)0xb9, (byte)0x4b, (byte)0x59, (byte)0x52, (byte)0xbc, (byte)0xa7, (byte)0x18,};
+        byte[] actual = computeSessionBaseKey(ntlm_v2_hash, nt_proof_str);
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public String generateServicePrincipalName(String serverHostName) {
+        servicePrincipalName = GSS_RDP_SERVICE_NAME + "/" + serverHostName;
+        return servicePrincipalName;
+    }
+
+    public void writeAVPair(ByteBuffer buf, int avPairType, byte[] value) {
+        if (value != null) {
+            buf.writeShortLE(avPairType);
+            buf.writeShortLE(value.length);
+            buf.writeBytes(value);
+        }
+    }
+
+    public void writeAVPair(ByteBuffer buf, int avPairType, String value) {
+        if (value != null) {
+            writeAVPair(buf, avPairType, value.getBytes(RdpConstants.CHARSET_16));
+        }
+    }
+
+    public byte[] ntlm_construct_authenticate_target_info() {
+        ByteBuffer buf = new ByteBuffer(4096);
+
+        writeAVPair(buf, MSV_AV_NETBIOS_DOMAIN_NAME, serverNetbiosDomainName);
+
+        writeAVPair(buf, MSV_AV_NETBIOS_COMPUTER_NAME, serverNetbiosComputerName);
+
+        writeAVPair(buf, MSV_AV_DNS_DOMAIN_NAME, serverDnsDomainName);
+
+        writeAVPair(buf, MSV_AV_DNS_COMPUTER_NAME, serverDnsComputerName);
+
+        writeAVPair(buf, MSV_AV_DNS_TREE_NAME, serverDnsTreeName);
+
+        writeAVPair(buf, MSV_AV_TIMESTAMP, serverTimestamp);
+
+        byte[] flags = new byte[] {(byte)MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK, 0, 0, 0};
+        writeAVPair(buf, MSV_AV_FLAGS, flags);
+
+        writeAVPair(buf, MSV_AV_CHANNEL_BINDINGS, channelBindingsHash);
+
+        writeAVPair(buf, MSV_AV_TARGET_NAME, servicePrincipalName);
+
+        writeAVPair(buf, MSV_AV_EOL, "");
+        // DEBUG: put EOL 4 times, for compatibility with FreeRDP output
+        //*DEBUG*/writeAVPair(buf, MSV_AV_EOL, "");
+        //*DEBUG*/writeAVPair(buf, MSV_AV_EOL, "");
+        //*DEBUG*/writeAVPair(buf, MSV_AV_EOL, "");
+        buf.trimAtCursor();
+
+        authenticateTargetInfo = buf.toByteArray();
+        buf.unref();
+
+        return authenticateTargetInfo;
+    }
+
+    public void testConstructAuthenticateTargetInfo() {
+        serverNetbiosDomainName = "WIN-LO419B2LSR0";
+        serverNetbiosComputerName = "WIN-LO419B2LSR0";
+        serverDnsDomainName = "WIN-LO419B2LSR0";
+        serverDnsComputerName = "WIN-LO419B2LSR0";
+        serverTimestamp = new byte[] {(byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01,};
+        servicePrincipalName = "TERMSRV/192.168.1.3";
+
+        byte[] expected = new byte[] {(byte)0x02, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e,
+                (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00,
+                (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00,
+                (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31,
+                (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00,
+                (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49,
+                (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53,
+                (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00,
+                (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34,
+                (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0xa0,
+                (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x06, (byte)0x00, (byte)0x04, (byte)0x00,
+                (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x26, (byte)0x00, (byte)0x54, (byte)0x00, (byte)0x45, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x4d, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x56, (byte)0x00, (byte)0x2f, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x36,
+                (byte)0x00, (byte)0x38, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x33, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,};
+        byte[] actual = ntlm_construct_authenticate_target_info();
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_compute_ntlm_v2_response() {
+        ByteBuffer buf = new ByteBuffer(4096);
+
+        byte[] ntlm_v2_hash = ntlm_compute_ntlm_v2_hash();
+
+        buf.writeByte(0x1); // RespType
+        buf.writeByte(0x1); // HighRespType
+        buf.writeShort(0); // reserved
+        buf.writeInt(0); // reserved
+        buf.writeBytes(clientChallengeTimestamp); // Timestamp, 8 bytes
+        buf.writeBytes(clientChallenge); // Client nonce, 8 bytes
+        buf.writeInt(0); // reserved
+        buf.writeBytes(authenticateTargetInfo); // Target Info block
+        buf.trimAtCursor();
+        byte[] bufBytes = buf.toByteArray();
+        buf.unref();
+
+        nt_proof_str = computeNtProofStr(ntlm_v2_hash, CryptoAlgos.concatenationOf(serverChallenge, bufBytes));
+
+        ntChallengeResponse = CryptoAlgos.concatenationOf(nt_proof_str, bufBytes);
+
+        sessionBaseKey = computeSessionBaseKey(ntlm_v2_hash, nt_proof_str);
+
+        return ntChallengeResponse;
+    }
+
+    public void testComputeNtlmV2Response() {
+        serverChallenge = new byte[] {(byte)0x4a, (byte)0x25, (byte)0x50, (byte)0xa5, (byte)0x11, (byte)0x9b, (byte)0xd6, (byte)0x16,};
+        clientChallenge = new byte[] {1, 2, 3, 4, 5, 6, 7, 8};
+        password = "R2Preview!";
+        user = "Administrator";
+        domain = "workgroup";
+        clientChallengeTimestamp = new byte[] {(byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01,};
+        authenticateTargetInfo = new byte[] {(byte)0x02, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e,
+                (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00,
+                (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00,
+                (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31,
+                (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00,
+                (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49,
+                (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53,
+                (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00,
+                (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34,
+                (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0xa0,
+                (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x06, (byte)0x00, (byte)0x04, (byte)0x00,
+                (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x26, (byte)0x00, (byte)0x54, (byte)0x00, (byte)0x45, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x4d, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x56, (byte)0x00, (byte)0x2f, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x36,
+                (byte)0x00, (byte)0x38, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x33, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,};
+
+        byte[] expected = new byte[] {(byte)0x19, (byte)0x4b, (byte)0xeb, (byte)0xad, (byte)0xda, (byte)0x24, (byte)0xd5, (byte)0x96, (byte)0x85,
+                (byte)0x2e, (byte)0x24, (byte)0x94, (byte)0xd6, (byte)0x4a, (byte)0xb8, (byte)0x5e, (byte)0x01, (byte)0x01, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce,
+                (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e,
+                (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00,
+                (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00,
+                (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31,
+                (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00,
+                (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49,
+                (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53,
+                (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00,
+                (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34,
+                (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0xa0,
+                (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x06, (byte)0x00, (byte)0x04, (byte)0x00,
+                (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x26, (byte)0x00, (byte)0x54, (byte)0x00, (byte)0x45, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x4d, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x56, (byte)0x00, (byte)0x2f, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x36,
+                (byte)0x00, (byte)0x38, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x33, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,};
+        byte[] actual = ntlm_compute_ntlm_v2_response();
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_generate_key_exchange_key() {
+        keyExchangeKey = sessionBaseKey;
+        return keyExchangeKey;
+    }
+
+    public byte[] ntlm_generate_random_session_key() {
+        randomSessionKey = CryptoAlgos.NONCE(16);
+        return randomSessionKey;
+    }
+
+    public byte[] ntlm_generate_exported_session_key() {
+        exportedSessionKey = randomSessionKey;
+        return exportedSessionKey;
+    }
+
+    public byte[] ntlm_encrypt_random_session_key() {
+        encryptedRandomSessionKey = CryptoAlgos.RC4K(keyExchangeKey, randomSessionKey);
+        return encryptedRandomSessionKey;
+    }
+
+    public void testComputeEncryptedRandomSessionKey() {
+        keyExchangeKey = new byte[] {(byte)0x8e, (byte)0x0f, (byte)0xdd, (byte)0x12, (byte)0x4c, (byte)0x3b, (byte)0x11, (byte)0x7f, (byte)0x22,
+                (byte)0xb9, (byte)0x4b, (byte)0x59, (byte)0x52, (byte)0xbc, (byte)0xa7, (byte)0x18,};
+        randomSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+
+        byte[] expected = new byte[] {(byte)0xe4, (byte)0xe9, (byte)0xc2, (byte)0xad, (byte)0x41, (byte)0x02, (byte)0x2f, (byte)0x3c, (byte)0xf9,
+                (byte)0x4c, (byte)0x72, (byte)0x84, (byte)0xc5, (byte)0x2a, (byte)0x7c, (byte)0x6f,};
+        byte[] actual = ntlm_encrypt_random_session_key();
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_generate_signing_key(String signMagic) {
+        return CryptoAlgos.MD5(CryptoAlgos.concatenationOf(exportedSessionKey, signMagic.getBytes(RdpConstants.CHARSET_8), new byte[] {0}));
+    }
+
+    public void testGenerateSigningKey() {
+        exportedSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+        byte[] expected = new byte[] {(byte)0xf6, (byte)0xae, (byte)0x96, (byte)0xcb, (byte)0x05, (byte)0xe2, (byte)0xab, (byte)0x54, (byte)0xf6,
+                (byte)0xdd, (byte)0x59, (byte)0xf3, (byte)0xc9, (byte)0xd9, (byte)0xa0, (byte)0x43,};
+        byte[] actual = ntlm_generate_signing_key(CLIENT_SIGN_MAGIC);
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_generate_client_signing_key() {
+        clientSigningKey = ntlm_generate_signing_key(CLIENT_SIGN_MAGIC);
+        return clientSigningKey;
+    }
+
+    public void testGenerateClientSigningKey() {
+        exportedSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+        byte[] expected = new byte[] {(byte)0xf6, (byte)0xae, (byte)0x96, (byte)0xcb, (byte)0x05, (byte)0xe2, (byte)0xab, (byte)0x54, (byte)0xf6,
+                (byte)0xdd, (byte)0x59, (byte)0xf3, (byte)0xc9, (byte)0xd9, (byte)0xa0, (byte)0x43,};
+        byte[] actual = ntlm_generate_client_signing_key();
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_generate_server_signing_key() {
+        serverSigningKey = ntlm_generate_signing_key(SERVER_SIGN_MAGIC);
+        return serverSigningKey;
+    }
+
+    public void testGenerateServerSigningKey() {
+        exportedSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+        byte[] expected = new byte[] {(byte)0xb6, (byte)0x58, (byte)0xc5, (byte)0x98, (byte)0x7a, (byte)0x25, (byte)0xf8, (byte)0x6e, (byte)0xd8,
+                (byte)0xe5, (byte)0x6c, (byte)0xe9, (byte)0x3e, (byte)0x3c, (byte)0xc0, (byte)0x88,};
+        byte[] actual = ntlm_generate_server_signing_key();
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_generate_client_sealing_key() {
+        clientSealingKey = ntlm_generate_signing_key(CLIENT_SEAL_MAGIC);
+        return clientSealingKey;
+    }
+
+    public void testGenerateClientSealingKey() {
+        exportedSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+        byte[] expected = new byte[] {(byte)0x58, (byte)0x19, (byte)0x44, (byte)0xc2, (byte)0x7a, (byte)0xc6, (byte)0x34, (byte)0x45, (byte)0xe4,
+                (byte)0xb8, (byte)0x2b, (byte)0x55, (byte)0xb9, (byte)0x0b, (byte)0x1f, (byte)0xb5,};
+        byte[] actual = ntlm_generate_client_sealing_key();
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_generate_server_sealing_key() {
+        serverSealingKey = ntlm_generate_signing_key(SERVER_SEAL_MAGIC);
+        return serverSealingKey;
+    }
+
+    public void testGenerateServerSealingKey() {
+        exportedSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+        byte[] expected = new byte[] {(byte)0x92, (byte)0x3a, (byte)0x73, (byte)0x5c, (byte)0x92, (byte)0xa7, (byte)0x04, (byte)0x34, (byte)0xbe,
+                (byte)0x9a, (byte)0xa2, (byte)0x9f, (byte)0xed, (byte)0xc1, (byte)0xe6, (byte)0x13,};
+        byte[] actual = ntlm_generate_server_sealing_key();
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public void ntlm_init_rc4_seal_states() {
+        ntlm_generate_client_signing_key();
+        ntlm_generate_server_signing_key();
+        ntlm_generate_client_sealing_key();
+        ntlm_generate_server_sealing_key();
+
+        sendSigningKey = clientSigningKey;
+        recvSigningKey = serverSigningKey;
+        sendSealingKey = clientSealingKey;
+        recvSealingKey = serverSealingKey;
+
+        sendRc4Seal = CryptoAlgos.initRC4(sendSealingKey);
+        recvRc4Seal = CryptoAlgos.initRC4(recvSealingKey);
+    }
+
+    public byte[] ntlm_compute_message_integrity_check() {
+        //* DEBUG */System.out.println("ntlm_compute_message_integrity_check: exportedSessionKey:\n" + new ByteBuffer(exportedSessionKey).dump() + "\n");
+        //* DEBUG */System.out.println("ntlm_compute_message_integrity_check: negotiateMessage:\n" + new ByteBuffer(negotiateMessage).dump() + "\n");
+        //* DEBUG */System.out.println("ntlm_compute_message_integrity_check: challengeMessage:\n" + new ByteBuffer(challengeMessage).dump() + "\n");
+        //* DEBUG */System.out.println("ntlm_compute_message_integrity_check: authenticateMessage:\n" + new ByteBuffer(authenticateMessage).dump() + "\n");
+        messageIntegrityCheck = CryptoAlgos.HMAC_MD5(exportedSessionKey, CryptoAlgos.concatenationOf(negotiateMessage, challengeMessage, authenticateMessage));
+        //* DEBUG */System.out.println("ntlm_compute_message_integrity_check: messageIntegrityCheck:\n" + new ByteBuffer(messageIntegrityCheck).dump() + "\n");
+        return messageIntegrityCheck;
+    }
+
+    public void testComputeMessageIntegrityCheck() {
+        exportedSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+
+        negotiateMessage = new byte[] {(byte)0x4e, (byte)0x54, (byte)0x4c, (byte)0x4d, (byte)0x53, (byte)0x53, (byte)0x50, (byte)0x00, (byte)0x01,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xb7, (byte)0x82, (byte)0x08, (byte)0xe2, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f,};
+
+        challengeMessage = new byte[] {(byte)0x4e, (byte)0x54, (byte)0x4c, (byte)0x4d, (byte)0x53, (byte)0x53, (byte)0x50, (byte)0x00, (byte)0x02,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x38, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x35, (byte)0x82, (byte)0x8a, (byte)0xe2, (byte)0x4a, (byte)0x25, (byte)0x50, (byte)0xa5, (byte)0x11, (byte)0x9b, (byte)0xd6,
+                (byte)0x16, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x98, (byte)0x00,
+                (byte)0x98, (byte)0x00, (byte)0x56, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x03, (byte)0xd7, (byte)0x24, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x0f, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00,
+                (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42,
+                (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00,
+                (byte)0x02, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d,
+                (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00,
+                (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30,
+                (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00,
+                (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39,
+                (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00,
+                (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e,
+                (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00,
+                (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00,
+                (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31,
+                (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00,
+                (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0xa0, (byte)0xe8, (byte)0x85,
+                (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,};
+
+        authenticateMessage = new byte[] {(byte)0x4e, (byte)0x54, (byte)0x4c, (byte)0x4d, (byte)0x53, (byte)0x53, (byte)0x50, (byte)0x00, (byte)0x03,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x18, (byte)0x00, (byte)0x18, (byte)0x00, (byte)0x90, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x16, (byte)0x01, (byte)0x16, (byte)0x01, (byte)0xa8, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x12, (byte)0x00, (byte)0x12,
+                (byte)0x00, (byte)0x58, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x1a, (byte)0x00, (byte)0x1a, (byte)0x00, (byte)0x6a, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x84, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10,
+                (byte)0x00, (byte)0x10, (byte)0x00, (byte)0xbe, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x35, (byte)0xb2, (byte)0x88, (byte)0xe2,
+                (byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x77, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x6b, (byte)0x00, (byte)0x67,
+                (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x75, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x41, (byte)0x00,
+                (byte)0x64, (byte)0x00, (byte)0x6d, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6e, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x73,
+                (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x6f, (byte)0x00,
+                (byte)0x72, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x6c,
+                (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x7c, (byte)0xc0, (byte)0xfd, (byte)0x08, (byte)0xc5, (byte)0x14, (byte)0x05, (byte)0x34,
+                (byte)0xf3, (byte)0x12, (byte)0x9e, (byte)0x3e, (byte)0xa3, (byte)0x09, (byte)0xbc, (byte)0xc6, (byte)0x01, (byte)0x02, (byte)0x03,
+                (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x19, (byte)0x4b, (byte)0xeb, (byte)0xad, (byte)0xda, (byte)0x24,
+                (byte)0xd5, (byte)0x96, (byte)0x85, (byte)0x2e, (byte)0x24, (byte)0x94, (byte)0xd6, (byte)0x4a, (byte)0xb8, (byte)0x5e, (byte)0x01,
+                (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c,
+                (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07,
+                (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00,
+                (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34,
+                (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57,
+                (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00,
+                (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c,
+                (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x1e, (byte)0x00,
+                (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f,
+                (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00,
+                (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x1e,
+                (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32,
+                (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x07, (byte)0x00,
+                (byte)0x08, (byte)0x00, (byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x06,
+                (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x10, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x26, (byte)0x00, (byte)0x54, (byte)0x00,
+                (byte)0x45, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x4d, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x56,
+                (byte)0x00, (byte)0x2f, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x2e, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x36, (byte)0x00, (byte)0x38, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x2e,
+                (byte)0x00, (byte)0x33, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xe4, (byte)0xe9, (byte)0xc2,
+                (byte)0xad, (byte)0x41, (byte)0x02, (byte)0x2f, (byte)0x3c, (byte)0xf9, (byte)0x4c, (byte)0x72, (byte)0x84, (byte)0xc5, (byte)0x2a,
+                (byte)0x7c, (byte)0x6f,};
+
+        byte[] expected = new byte[] {(byte)0xd9, (byte)0xe9, (byte)0xbc, (byte)0x9b, (byte)0x6f, (byte)0xa5, (byte)0xf9, (byte)0xc8, (byte)0x70,
+                (byte)0x16, (byte)0x10, (byte)0x20, (byte)0xf8, (byte)0xf1, (byte)0x61, (byte)0x42,};
+        byte[] actual = ntlm_compute_message_integrity_check();
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_EncryptMessage(byte[] message) {
+        byte[] versionBytes = new byte[] {0x01, 0x00, 0x00, 0x00}; // 0x00000001
+                                                                   // LE
+        byte[] seqNumBytes = new byte[] {(byte)(sendSeqNum & 0xff), (byte)((sendSeqNum >> 8) & 0xff), (byte)((sendSeqNum >> 16) & 0xff),
+                (byte)((sendSeqNum >> 24) & 0xff)};
+
+        byte[] digest = CryptoAlgos.HMAC_MD5(sendSigningKey, CryptoAlgos.concatenationOf(seqNumBytes, message));
+
+        byte[] encrypted = CryptoAlgos.RC4(sendRc4Seal, message);
+
+        // Encrypt first 8 bytes of digest only
+        byte[] checksum = CryptoAlgos.RC4(sendRc4Seal, Arrays.copyOf(digest, 8));
+
+        byte[] signature = CryptoAlgos.concatenationOf(versionBytes, checksum, seqNumBytes);
+
+        sendSeqNum++;
+
+        return CryptoAlgos.concatenationOf(signature, encrypted);
+    }
+
+    public void testNtlmEncryptMessage() {
+        sendSigningKey = new byte[] {(byte)0xf6, (byte)0xae, (byte)0x96, (byte)0xcb, (byte)0x05, (byte)0xe2, (byte)0xab, (byte)0x54, (byte)0xf6,
+                (byte)0xdd, (byte)0x59, (byte)0xf3, (byte)0xc9, (byte)0xd9, (byte)0xa0, (byte)0x43,};
+        sendRc4Seal = CryptoAlgos.initRC4(new byte[] {(byte)0x58, (byte)0x19, (byte)0x44, (byte)0xc2, (byte)0x7a, (byte)0xc6, (byte)0x34, (byte)0x45,
+                (byte)0xe4, (byte)0xb8, (byte)0x2b, (byte)0x55, (byte)0xb9, (byte)0x0b, (byte)0x1f, (byte)0xb5,});
+        sendSeqNum = 0;
+        byte[] serverPublicKey = new byte[] {(byte)0x30, (byte)0x82, (byte)0x01, (byte)0x0a, (byte)0x02, (byte)0x82, (byte)0x01, (byte)0x01, (byte)0x00,
+                (byte)0xa8, (byte)0x56, (byte)0x65, (byte)0xd3, (byte)0xce, (byte)0x8a, (byte)0x54, (byte)0x4d, (byte)0x9d, (byte)0xb0, (byte)0x84,
+                (byte)0x31, (byte)0x19, (byte)0x71, (byte)0x7f, (byte)0xdd, (byte)0x42, (byte)0xfb, (byte)0x2a, (byte)0x7a, (byte)0x72, (byte)0x13,
+                (byte)0xa1, (byte)0xb9, (byte)0x72, (byte)0xbb, (byte)0xd3, (byte)0x08, (byte)0xad, (byte)0x7d, (byte)0x6c, (byte)0x15, (byte)0x65,
+                (byte)0x03, (byte)0xd1, (byte)0xc4, (byte)0x54, (byte)0xc5, (byte)0x33, (byte)0x6b, (byte)0x7d, (byte)0x69, (byte)0x89, (byte)0x5e,
+                (byte)0xfe, (byte)0xe0, (byte)0x01, (byte)0xc0, (byte)0x7e, (byte)0x9b, (byte)0xcb, (byte)0x5d, (byte)0x65, (byte)0x36, (byte)0xcd,
+                (byte)0x77, (byte)0x5d, (byte)0xf3, (byte)0x7a, (byte)0x5b, (byte)0x29, (byte)0x44, (byte)0x72, (byte)0xd5, (byte)0x38, (byte)0xe2,
+                (byte)0xcf, (byte)0xb1, (byte)0xc7, (byte)0x78, (byte)0x9b, (byte)0x58, (byte)0xb9, (byte)0x17, (byte)0x7c, (byte)0xb7, (byte)0xd6,
+                (byte)0xc7, (byte)0xc7, (byte)0xbf, (byte)0x90, (byte)0x4e, (byte)0x7c, (byte)0x39, (byte)0x93, (byte)0xcb, (byte)0x2e, (byte)0xe0,
+                (byte)0xc2, (byte)0x33, (byte)0x2d, (byte)0xa5, (byte)0x7e, (byte)0xe0, (byte)0x7b, (byte)0xb6, (byte)0xf9, (byte)0x91, (byte)0x32,
+                (byte)0xb7, (byte)0xd4, (byte)0x85, (byte)0xb7, (byte)0x35, (byte)0x2d, (byte)0x2b, (byte)0x00, (byte)0x6d, (byte)0xf8, (byte)0xea,
+                (byte)0x8c, (byte)0x97, (byte)0x5f, (byte)0x51, (byte)0x1d, (byte)0x68, (byte)0x04, (byte)0x3c, (byte)0x79, (byte)0x14, (byte)0x71,
+                (byte)0xa7, (byte)0xc7, (byte)0xd7, (byte)0x70, (byte)0x7a, (byte)0xe0, (byte)0xba, (byte)0x12, (byte)0x69, (byte)0xc8, (byte)0xd3,
+                (byte)0xd9, (byte)0x4e, (byte)0xab, (byte)0x51, (byte)0x47, (byte)0xa3, (byte)0xec, (byte)0x99, (byte)0xd4, (byte)0x88, (byte)0xca,
+                (byte)0xda, (byte)0xc2, (byte)0x7f, (byte)0x79, (byte)0x4b, (byte)0x66, (byte)0xed, (byte)0x87, (byte)0xbe, (byte)0xc2, (byte)0x5f,
+                (byte)0xea, (byte)0xcf, (byte)0xe1, (byte)0xb5, (byte)0xf0, (byte)0x3d, (byte)0x9b, (byte)0xf2, (byte)0x19, (byte)0xc3, (byte)0xe0,
+                (byte)0xe1, (byte)0x7a, (byte)0x45, (byte)0x71, (byte)0x12, (byte)0x3d, (byte)0x72, (byte)0x1d, (byte)0x6f, (byte)0x2b, (byte)0x1c,
+                (byte)0x46, (byte)0x68, (byte)0xc0, (byte)0x8f, (byte)0x4f, (byte)0xce, (byte)0x3a, (byte)0xc5, (byte)0xcd, (byte)0x22, (byte)0x65,
+                (byte)0x2d, (byte)0x43, (byte)0xb0, (byte)0x5c, (byte)0xdd, (byte)0x89, (byte)0xae, (byte)0xbe, (byte)0x70, (byte)0x59, (byte)0x5e,
+                (byte)0x0c, (byte)0xbd, (byte)0xf5, (byte)0x46, (byte)0x82, (byte)0x1e, (byte)0xe4, (byte)0x86, (byte)0x95, (byte)0x7b, (byte)0x60,
+                (byte)0xae, (byte)0x45, (byte)0x50, (byte)0xc2, (byte)0x54, (byte)0x08, (byte)0x49, (byte)0x9a, (byte)0x9e, (byte)0xfb, (byte)0xb2,
+                (byte)0xb6, (byte)0x78, (byte)0xe5, (byte)0x2f, (byte)0x9c, (byte)0x5a, (byte)0xd0, (byte)0x8a, (byte)0x03, (byte)0x77, (byte)0x68,
+                (byte)0x30, (byte)0x93, (byte)0x78, (byte)0x6d, (byte)0x90, (byte)0x6d, (byte)0x50, (byte)0xfa, (byte)0xa7, (byte)0x65, (byte)0xfe,
+                (byte)0x59, (byte)0x33, (byte)0x27, (byte)0x4e, (byte)0x4b, (byte)0xf8, (byte)0x38, (byte)0x44, (byte)0x3a, (byte)0x12, (byte)0xf4,
+                (byte)0x07, (byte)0xa0, (byte)0x8d, (byte)0x02, (byte)0x03, (byte)0x01, (byte)0x00, (byte)0x01,};
+
+        byte[] expected = new byte[] {(byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x72, (byte)0x76, (byte)0x1e, (byte)0x57, (byte)0x49,
+                (byte)0xb5, (byte)0x0f, (byte)0xad, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x15, (byte)0xf7, (byte)0xf2, (byte)0x54,
+                (byte)0xda, (byte)0xa9, (byte)0xe5, (byte)0xad, (byte)0x85, (byte)0x04, (byte)0x67, (byte)0x4d, (byte)0x0b, (byte)0xcb, (byte)0xf9,
+                (byte)0xb1, (byte)0xf8, (byte)0x02, (byte)0x8a, (byte)0x77, (byte)0xc2, (byte)0x63, (byte)0xab, (byte)0xd5, (byte)0x74, (byte)0x23,
+                (byte)0x9f, (byte)0x9d, (byte)0x5d, (byte)0x1f, (byte)0xd3, (byte)0xb3, (byte)0xa0, (byte)0xac, (byte)0x16, (byte)0x8a, (byte)0x4b,
+                (byte)0x08, (byte)0xf5, (byte)0x47, (byte)0x70, (byte)0x58, (byte)0x10, (byte)0xb4, (byte)0xe7, (byte)0x87, (byte)0xb3, (byte)0x4b,
+                (byte)0xc9, (byte)0xa2, (byte)0xd5, (byte)0xd1, (byte)0xca, (byte)0x0f, (byte)0xd4, (byte)0xe3, (byte)0x8d, (byte)0x76, (byte)0x5a,
+                (byte)0x60, (byte)0x28, (byte)0xf8, (byte)0x06, (byte)0x5d, (byte)0xe4, (byte)0x7e, (byte)0x21, (byte)0xc8, (byte)0xbb, (byte)0xac,
+                (byte)0xe5, (byte)0x79, (byte)0x85, (byte)0x30, (byte)0x9b, (byte)0x88, (byte)0x13, (byte)0x2f, (byte)0x8f, (byte)0xfc, (byte)0x04,
+                (byte)0x52, (byte)0xfe, (byte)0x87, (byte)0x94, (byte)0xcf, (byte)0xcb, (byte)0x49, (byte)0x4a, (byte)0xda, (byte)0x6f, (byte)0xdd,
+                (byte)0xee, (byte)0x57, (byte)0xa5, (byte)0xe4, (byte)0x4d, (byte)0x0e, (byte)0x5c, (byte)0x3d, (byte)0x0b, (byte)0x63, (byte)0x1f,
+                (byte)0xf6, (byte)0x3d, (byte)0x1b, (byte)0xae, (byte)0x5a, (byte)0xf6, (byte)0x42, (byte)0x2a, (byte)0x46, (byte)0xfa, (byte)0x42,
+                (byte)0x71, (byte)0x67, (byte)0x46, (byte)0x02, (byte)0x71, (byte)0xea, (byte)0x51, (byte)0x98, (byte)0xf7, (byte)0xd4, (byte)0x43,
+                (byte)0xbf, (byte)0x8e, (byte)0xe8, (byte)0x3c, (byte)0xc8, (byte)0xfa, (byte)0x79, (byte)0x9d, (byte)0x8c, (byte)0xfc, (byte)0xc2,
+                (byte)0x42, (byte)0xc9, (byte)0xbb, (byte)0xd0, (byte)0xab, (byte)0x81, (byte)0xc4, (byte)0x53, (byte)0xfd, (byte)0x41, (byte)0xda,
+                (byte)0xab, (byte)0x0f, (byte)0x25, (byte)0x79, (byte)0x5f, (byte)0xbd, (byte)0xa3, (byte)0x8c, (byte)0xd3, (byte)0xf5, (byte)0x1b,
+                (byte)0xab, (byte)0x20, (byte)0xd1, (byte)0xf4, (byte)0xd8, (byte)0x81, (byte)0x9c, (byte)0x18, (byte)0x4a, (byte)0xa4, (byte)0x77,
+                (byte)0xee, (byte)0xe1, (byte)0x51, (byte)0xee, (byte)0x2a, (byte)0xc1, (byte)0x94, (byte)0x37, (byte)0xc5, (byte)0x06, (byte)0x7a,
+                (byte)0x3f, (byte)0x0f, (byte)0x25, (byte)0x5b, (byte)0x4e, (byte)0x6a, (byte)0xdc, (byte)0x0b, (byte)0x62, (byte)0x6f, (byte)0x12,
+                (byte)0x83, (byte)0x03, (byte)0xae, (byte)0x4e, (byte)0xce, (byte)0x2b, (byte)0x6e, (byte)0xd4, (byte)0xd5, (byte)0x23, (byte)0x27,
+                (byte)0xf6, (byte)0xa6, (byte)0x38, (byte)0x67, (byte)0xec, (byte)0x95, (byte)0x82, (byte)0xc6, (byte)0xba, (byte)0xd4, (byte)0xf6,
+                (byte)0xe6, (byte)0x22, (byte)0x7d, (byte)0xb9, (byte)0xe4, (byte)0x81, (byte)0x97, (byte)0x24, (byte)0xff, (byte)0x40, (byte)0xb2,
+                (byte)0x42, (byte)0x3c, (byte)0x11, (byte)0x24, (byte)0xd0, (byte)0x3a, (byte)0x96, (byte)0xd9, (byte)0xc1, (byte)0x13, (byte)0xd6,
+                (byte)0x62, (byte)0x45, (byte)0x21, (byte)0x60, (byte)0x5b, (byte)0x7b, (byte)0x2b, (byte)0x62, (byte)0x44, (byte)0xf7, (byte)0x40,
+                (byte)0x93, (byte)0x29, (byte)0x5b, (byte)0x44, (byte)0xb7, (byte)0xda, (byte)0x9c, (byte)0xa6, (byte)0xa9, (byte)0x3b, (byte)0xe1,
+                (byte)0x3b, (byte)0x9d, (byte)0x31, (byte)0xf2, (byte)0x21, (byte)0x53, (byte)0x0f, (byte)0xb3, (byte)0x70, (byte)0x55, (byte)0x84,
+                (byte)0x2c, (byte)0xb4,};
+        byte[] actual = ntlm_EncryptMessage(serverPublicKey);
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_DecryptMessage(byte[] wrappedMssage) {
+
+        byte[] versionBytes = new byte[] {0x01, 0x00, 0x00, 0x00}; // 0x00000001
+                                                                   // LE
+        byte[] seqNumBytes = new byte[] {(byte)(recvSeqNum & 0xff), (byte)((recvSeqNum >> 8) & 0xff), (byte)((recvSeqNum >> 16) & 0xff),
+                (byte)((recvSeqNum >> 24) & 0xff)};
+
+        // Unwrap message
+        byte[] actualSignature = Arrays.copyOf(wrappedMssage, 16);
+        byte[] encryptedMessage = Arrays.copyOfRange(wrappedMssage, 16, wrappedMssage.length);
+
+        // Decrypt message
+        byte[] decryptedMessage = CryptoAlgos.RC4(recvRc4Seal, encryptedMessage);
+
+        // Compare actual signature with expected signature
+        byte[] digest = CryptoAlgos.HMAC_MD5(recvSigningKey, CryptoAlgos.concatenationOf(seqNumBytes, decryptedMessage));
+
+        // Encrypt first 8 bytes of digest only
+        byte[] checksum = CryptoAlgos.RC4(recvRc4Seal, Arrays.copyOf(digest, 8));
+
+        byte[] expectedSignature = CryptoAlgos.concatenationOf(versionBytes, checksum, seqNumBytes);
+
+        if (!Arrays.equals(expectedSignature, actualSignature))
+            throw new RuntimeException("Unexpected signature of message:\nExpected signature: " + new ByteBuffer(expectedSignature).toPlainHexString()
+                    + "\n  Actual signature: " + new ByteBuffer(actualSignature).toPlainHexString());
+
+        recvSeqNum++;
+
+        return decryptedMessage;
+    }
+
+    public void testNtlmDecryptMessage() {
+        recvSigningKey = new byte[] {(byte)0xb6, (byte)0x58, (byte)0xc5, (byte)0x98, (byte)0x7a, (byte)0x25, (byte)0xf8, (byte)0x6e, (byte)0xd8,
+                (byte)0xe5, (byte)0x6c, (byte)0xe9, (byte)0x3e, (byte)0x3c, (byte)0xc0, (byte)0x88,};
+        recvRc4Seal = CryptoAlgos.initRC4(new byte[] {(byte)0x92, (byte)0x3a, (byte)0x73, (byte)0x5c, (byte)0x92, (byte)0xa7, (byte)0x04, (byte)0x34,
+                (byte)0xbe, (byte)0x9a, (byte)0xa2, (byte)0x9f, (byte)0xed, (byte)0xc1, (byte)0xe6, (byte)0x13,});
+        recvSeqNum = 0;
+        byte[] encryptedMessage = new byte[] {(byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x25, (byte)0xf8, (byte)0x2d, (byte)0x1e, (byte)0x4e,
+                (byte)0x6a, (byte)0xec, (byte)0x4f, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x03, (byte)0x12, (byte)0xdd, (byte)0xea,
+                (byte)0x47, (byte)0xb3, (byte)0xff, (byte)0xe1, (byte)0x66, (byte)0x08, (byte)0xf6, (byte)0x6b, (byte)0xa0, (byte)0x62, (byte)0x42,
+                (byte)0x67, (byte)0xbf, (byte)0x3d, (byte)0x59, (byte)0x60, (byte)0xef, (byte)0x52, (byte)0xb0, (byte)0x26, (byte)0x95, (byte)0xed,
+                (byte)0x84, (byte)0x48, (byte)0x44, (byte)0xbb, (byte)0x8d, (byte)0x65, (byte)0xcf, (byte)0xe4, (byte)0x8e, (byte)0x6f, (byte)0x69,
+                (byte)0xae, (byte)0xed, (byte)0x44, (byte)0xbb, (byte)0x49, (byte)0x1d, (byte)0x2a, (byte)0x40, (byte)0x29, (byte)0x2b, (byte)0x13,
+                (byte)0x42, (byte)0x1c, (byte)0xeb, (byte)0xb1, (byte)0x6c, (byte)0x8a, (byte)0x3b, (byte)0x80, (byte)0xd1, (byte)0x70, (byte)0xfd,
+                (byte)0xdd, (byte)0x79, (byte)0xe4, (byte)0x93, (byte)0x0b, (byte)0x47, (byte)0xbd, (byte)0x3a, (byte)0x7e, (byte)0x31, (byte)0x66,
+                (byte)0x4b, (byte)0x65, (byte)0x8d, (byte)0x5c, (byte)0x2a, (byte)0xcd, (byte)0xc2, (byte)0x09, (byte)0x7a, (byte)0x3b, (byte)0xb2,
+                (byte)0xfd, (byte)0x09, (byte)0x52, (byte)0x09, (byte)0x47, (byte)0x05, (byte)0xa4, (byte)0x6f, (byte)0x32, (byte)0xd1, (byte)0x76,
+                (byte)0xb2, (byte)0xd4, (byte)0x59, (byte)0xe0, (byte)0x85, (byte)0xf1, (byte)0x36, (byte)0x7d, (byte)0x76, (byte)0x50, (byte)0x21,
+                (byte)0x0e, (byte)0x20, (byte)0x22, (byte)0x83, (byte)0x1a, (byte)0x08, (byte)0xc0, (byte)0x85, (byte)0x5d, (byte)0x4f, (byte)0x5c,
+                (byte)0x77, (byte)0x68, (byte)0x32, (byte)0x95, (byte)0xa9, (byte)0xa2, (byte)0x59, (byte)0x69, (byte)0xea, (byte)0x19, (byte)0x34,
+                (byte)0x08, (byte)0xed, (byte)0x76, (byte)0xa3, (byte)0x58, (byte)0x37, (byte)0xf2, (byte)0x0a, (byte)0x0c, (byte)0xba, (byte)0x4d,
+                (byte)0xbb, (byte)0x6f, (byte)0x82, (byte)0x94, (byte)0xd3, (byte)0x87, (byte)0xde, (byte)0xc9, (byte)0x8f, (byte)0xef, (byte)0x34,
+                (byte)0x2d, (byte)0x8f, (byte)0xd0, (byte)0x0c, (byte)0x91, (byte)0x59, (byte)0xfd, (byte)0xea, (byte)0x6b, (byte)0xcb, (byte)0xbd,
+                (byte)0xa2, (byte)0x20, (byte)0xed, (byte)0xb9, (byte)0x76, (byte)0xd3, (byte)0x64, (byte)0x1b, (byte)0xb3, (byte)0x3b, (byte)0xf5,
+                (byte)0x9b, (byte)0x61, (byte)0xd7, (byte)0xab, (byte)0x26, (byte)0x9b, (byte)0x0d, (byte)0xa0, (byte)0xea, (byte)0xbf, (byte)0xad,
+                (byte)0x2c, (byte)0xad, (byte)0x63, (byte)0x65, (byte)0xc6, (byte)0x70, (byte)0xc4, (byte)0xe5, (byte)0x8d, (byte)0x40, (byte)0xaa,
+                (byte)0x08, (byte)0x45, (byte)0x66, (byte)0xe2, (byte)0x4d, (byte)0xc9, (byte)0x46, (byte)0x00, (byte)0x33, (byte)0x43, (byte)0xe0,
+                (byte)0xba, (byte)0xd6, (byte)0x80, (byte)0x29, (byte)0x21, (byte)0x5e, (byte)0xd1, (byte)0x9a, (byte)0xbc, (byte)0x44, (byte)0xfa,
+                (byte)0x4d, (byte)0x46, (byte)0xf9, (byte)0x25, (byte)0x80, (byte)0x40, (byte)0xb5, (byte)0x27, (byte)0xdd, (byte)0xc5, (byte)0x02,
+                (byte)0xf8, (byte)0xa4, (byte)0x9a, (byte)0xcb, (byte)0xcf, (byte)0x3f, (byte)0xef, (byte)0xc7, (byte)0xcd, (byte)0x71, (byte)0x45,
+                (byte)0xa5, (byte)0x35, (byte)0xb1, (byte)0x21, (byte)0x14, (byte)0x39, (byte)0x57, (byte)0xf8, (byte)0x0a, (byte)0x24, (byte)0x98,
+                (byte)0xea, (byte)0x15, (byte)0xe1, (byte)0xe3, (byte)0xcb, (byte)0x9d, (byte)0xf2, (byte)0x4e, (byte)0xef, (byte)0x89, (byte)0x97,
+                (byte)0xc0, (byte)0xb2, (byte)0x96, (byte)0x9a, (byte)0x1e, (byte)0xad, (byte)0xd0, (byte)0x9a, (byte)0x99, (byte)0x62, (byte)0x9f,
+                (byte)0x13, (byte)0x2e,};
+
+        byte[] expected = new byte[] {
+                // First byte is increased by 1
+                (byte)0x31, (byte)0x82, (byte)0x01, (byte)0x0a, (byte)0x02, (byte)0x82, (byte)0x01, (byte)0x01, (byte)0x00, (byte)0xa8, (byte)0x56,
+                (byte)0x65, (byte)0xd3, (byte)0xce, (byte)0x8a, (byte)0x54, (byte)0x4d, (byte)0x9d, (byte)0xb0, (byte)0x84, (byte)0x31, (byte)0x19,
+                (byte)0x71, (byte)0x7f, (byte)0xdd, (byte)0x42, (byte)0xfb, (byte)0x2a, (byte)0x7a, (byte)0x72, (byte)0x13, (byte)0xa1, (byte)0xb9,
+                (byte)0x72, (byte)0xbb, (byte)0xd3, (byte)0x08, (byte)0xad, (byte)0x7d, (byte)0x6c, (byte)0x15, (byte)0x65, (byte)0x03, (byte)0xd1,
+                (byte)0xc4, (byte)0x54, (byte)0xc5, (byte)0x33, (byte)0x6b, (byte)0x7d, (byte)0x69, (byte)0x89, (byte)0x5e, (byte)0xfe, (byte)0xe0,
+                (byte)0x01, (byte)0xc0, (byte)0x7e, (byte)0x9b, (byte)0xcb, (byte)0x5d, (byte)0x65, (byte)0x36, (byte)0xcd, (byte)0x77, (byte)0x5d,
+                (byte)0xf3, (byte)0x7a, (byte)0x5b, (byte)0x29, (byte)0x44, (byte)0x72, (byte)0xd5, (byte)0x38, (byte)0xe2, (byte)0xcf, (byte)0xb1,
+                (byte)0xc7, (byte)0x78, (byte)0x9b, (byte)0x58, (byte)0xb9, (byte)0x17, (byte)0x7c, (byte)0xb7, (byte)0xd6, (byte)0xc7, (byte)0xc7,
+                (byte)0xbf, (byte)0x90, (byte)0x4e, (byte)0x7c, (byte)0x39, (byte)0x93, (byte)0xcb, (byte)0x2e, (byte)0xe0, (byte)0xc2, (byte)0x33,
+                (byte)0x2d, (byte)0xa5, (byte)0x7e, (byte)0xe0, (byte)0x7b, (byte)0xb6, (byte)0xf9, (byte)0x91, (byte)0x32, (byte)0xb7, (byte)0xd4,
+                (byte)0x85, (byte)0xb7, (byte)0x35, (byte)0x2d, (byte)0x2b, (byte)0x00, (byte)0x6d, (byte)0xf8, (byte)0xea, (byte)0x8c, (byte)0x97,
+                (byte)0x5f, (byte)0x51, (byte)0x1d, (byte)0x68, (byte)0x04, (byte)0x3c, (byte)0x79, (byte)0x14, (byte)0x71, (byte)0xa7, (byte)0xc7,
+                (byte)0xd7, (byte)0x70, (byte)0x7a, (byte)0xe0, (byte)0xba, (byte)0x12, (byte)0x69, (byte)0xc8, (byte)0xd3, (byte)0xd9, (byte)0x4e,
+                (byte)0xab, (byte)0x51, (byte)0x47, (byte)0xa3, (byte)0xec, (byte)0x99, (byte)0xd4, (byte)0x88, (byte)0xca, (byte)0xda, (byte)0xc2,
+                (byte)0x7f, (byte)0x79, (byte)0x4b, (byte)0x66, (byte)0xed, (byte)0x87, (byte)0xbe, (byte)0xc2, (byte)0x5f, (byte)0xea, (byte)0xcf,
+                (byte)0xe1, (byte)0xb5, (byte)0xf0, (byte)0x3d, (byte)0x9b, (byte)0xf2, (byte)0x19, (byte)0xc3, (byte)0xe0, (byte)0xe1, (byte)0x7a,
+                (byte)0x45, (byte)0x71, (byte)0x12, (byte)0x3d, (byte)0x72, (byte)0x1d, (byte)0x6f, (byte)0x2b, (byte)0x1c, (byte)0x46, (byte)0x68,
+                (byte)0xc0, (byte)0x8f, (byte)0x4f, (byte)0xce, (byte)0x3a, (byte)0xc5, (byte)0xcd, (byte)0x22, (byte)0x65, (byte)0x2d, (byte)0x43,
+                (byte)0xb0, (byte)0x5c, (byte)0xdd, (byte)0x89, (byte)0xae, (byte)0xbe, (byte)0x70, (byte)0x59, (byte)0x5e, (byte)0x0c, (byte)0xbd,
+                (byte)0xf5, (byte)0x46, (byte)0x82, (byte)0x1e, (byte)0xe4, (byte)0x86, (byte)0x95, (byte)0x7b, (byte)0x60, (byte)0xae, (byte)0x45,
+                (byte)0x50, (byte)0xc2, (byte)0x54, (byte)0x08, (byte)0x49, (byte)0x9a, (byte)0x9e, (byte)0xfb, (byte)0xb2, (byte)0xb6, (byte)0x78,
+                (byte)0xe5, (byte)0x2f, (byte)0x9c, (byte)0x5a, (byte)0xd0, (byte)0x8a, (byte)0x03, (byte)0x77, (byte)0x68, (byte)0x30, (byte)0x93,
+                (byte)0x78, (byte)0x6d, (byte)0x90, (byte)0x6d, (byte)0x50, (byte)0xfa, (byte)0xa7, (byte)0x65, (byte)0xfe, (byte)0x59, (byte)0x33,
+                (byte)0x27, (byte)0x4e, (byte)0x4b, (byte)0xf8, (byte)0x38, (byte)0x44, (byte)0x3a, (byte)0x12, (byte)0xf4, (byte)0x07, (byte)0xa0,
+                (byte)0x8d, (byte)0x02, (byte)0x03, (byte)0x01, (byte)0x00, (byte)0x01,};
+        byte[] actual = ntlm_DecryptMessage(encryptedMessage);
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public static void main(String args[]) {
+        CryptoAlgos.callAll(new NtlmState());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/SecBuffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/SecBuffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/SecBuffer.java
new file mode 100755
index 0000000..6aeb39b
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/SecBuffer.java
@@ -0,0 +1,21 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp;
+
+public class SecBuffer {
+
+}


[20/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpKeyboardAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpKeyboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpKeyboardAdapter.java
deleted file mode 100644
index f19f09c..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpKeyboardAdapter.java
+++ /dev/null
@@ -1,351 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import java.awt.event.KeyEvent;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-import common.KeyOrder;
-
-public class AwtRdpKeyboardAdapter extends BaseElement {
-
-  /**
-   * Absence of this flag indicates a key-down event, while its presence
-   * indicates a key-release event.
-   */
-  public static final int FASTPATH_INPUT_KBDFLAGS_RELEASE = 0x01;
-
-  /**
-   * Keystroke message contains an extended scancode. For enhanced 101-key and
-   * 102-key keyboards, extended keys include the right ALT and right CTRL keys
-   * on the main section of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE
-   * DOWN and ARROW keys in the clusters to the left of the numeric keypad; and
-   * the Divide ("/") and ENTER keys in the numeric keypad.
-   */
-  public static final int FASTPATH_INPUT_KBDFLAGS_EXTENDED = 0x02;
-
-  public static final int FASTPATH_INPUT_EVENT_SCANCODE = 0;
-
-  public AwtRdpKeyboardAdapter(String id) {
-    super(id);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    KeyOrder order = (KeyOrder) buf.getOrder();
-    buf.unref();
-
-    ByteBuffer outBuf = new ByteBuffer(2, true);
-
-    int scanCode = map_en_us(order.event);
-
-    // eventHeader (1 byte): An 8-bit, unsigned integer. The format of this
-    // field is the same as the eventHeader byte field described in section
-    // 2.2.8.1.2.2. The eventCode bitfield (3 bits in size) MUST be set to
-    // FASTPATH_INPUT_EVENT_SCANCODE (0). The eventFlags bitfield (5 bits in
-    // size) contains flags describing the keyboard event.
-    outBuf.writeByte((scanCode >> 8) | (FASTPATH_INPUT_EVENT_SCANCODE << 5) | ((order.pressed) ? 0 : FASTPATH_INPUT_KBDFLAGS_RELEASE));
-
-    // keyCode (1 byte): An 8-bit, unsigned integer. The scancode of the key
-    // which triggered the event.
-    outBuf.writeByte(scanCode);
-
-    // Push buffer to one pad only, so it can be modified without copying of
-    // data
-    pushDataToPad(STDOUT, outBuf);
-  }
-
-  /**
-   * Return key scan code (in lower byte) and extended flags (in second byte).
-   */
-  private int map_en_us(KeyEvent event) {
-    // Also set extended key flag when necessary.
-    // For enhanced 101-key and 102-key keyboards, extended keys include the
-    // right ALT and right CTRL keys on the main section of the keyboard; the
-    // INS, DEL, HOME, END, PAGE UP, PAGE DOWN and ARROW keys in the clusters to
-    // the left of the numeric keypad; and the Divide ("/") and ENTER keys in
-    // the numeric keypad.
-
-    switch (event.getKeyCode()) {
-    // Functional keys
-    case KeyEvent.VK_ESCAPE:
-      return 1;
-    case KeyEvent.VK_F1:
-      return 59;
-    case KeyEvent.VK_F2:
-      return 60;
-    case KeyEvent.VK_F3:
-      return 61;
-    case KeyEvent.VK_F4:
-      return 62;
-    case KeyEvent.VK_F5:
-      return 63;
-    case KeyEvent.VK_F6:
-      return 64;
-    case KeyEvent.VK_F7:
-      return 65;
-    case KeyEvent.VK_F8:
-      return 66;
-    case KeyEvent.VK_F9:
-      return 67;
-    case KeyEvent.VK_F10:
-      return 68;
-    case KeyEvent.VK_F11:
-      return 87;
-    case KeyEvent.VK_F12:
-      return 88;
-
-      // Row #1
-    case KeyEvent.VK_BACK_QUOTE:
-      return 41;
-    case KeyEvent.VK_1:
-      return 2;
-    case KeyEvent.VK_2:
-      return 3;
-    case KeyEvent.VK_3:
-      return 4;
-    case KeyEvent.VK_4:
-      return 5;
-    case KeyEvent.VK_5:
-      return 6;
-    case KeyEvent.VK_6:
-      return 7;
-    case KeyEvent.VK_7:
-      return 8;
-    case KeyEvent.VK_8:
-      return 9;
-    case KeyEvent.VK_9:
-      return 10;
-    case KeyEvent.VK_0:
-      return 11;
-    case KeyEvent.VK_MINUS:
-      return 12;
-    case KeyEvent.VK_EQUALS:
-      return 13;
-    case KeyEvent.VK_BACK_SPACE:
-      return 14;
-
-      // Row #2
-    case KeyEvent.VK_TAB:
-      return 15;
-    case KeyEvent.VK_Q:
-      return 16;
-    case KeyEvent.VK_W:
-      return 17;
-    case KeyEvent.VK_E:
-      return 18;
-    case KeyEvent.VK_R:
-      return 19;
-    case KeyEvent.VK_T:
-      return 20;
-    case KeyEvent.VK_Y:
-      return 21;
-    case KeyEvent.VK_U:
-      return 22;
-    case KeyEvent.VK_I:
-      return 23;
-    case KeyEvent.VK_O:
-      return 24;
-    case KeyEvent.VK_P:
-      return 25;
-    case KeyEvent.VK_OPEN_BRACKET:
-      return 26;
-    case KeyEvent.VK_CLOSE_BRACKET:
-      return 27;
-    case KeyEvent.VK_ENTER:
-      switch (event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_STANDARD:
-        return 28;
-      case KeyEvent.KEY_LOCATION_NUMPAD:
-        return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 28;
-      }
-
-      // Row #3
-    case KeyEvent.VK_CAPS_LOCK:
-      return 58;
-    case KeyEvent.VK_A:
-      return 30;
-    case KeyEvent.VK_S:
-      return 31;
-    case KeyEvent.VK_D:
-      return 32;
-    case KeyEvent.VK_F:
-      return 33;
-    case KeyEvent.VK_G:
-      return 34;
-    case KeyEvent.VK_H:
-      return 35;
-    case KeyEvent.VK_J:
-      return 36;
-    case KeyEvent.VK_K:
-      return 37;
-    case KeyEvent.VK_L:
-      return 38;
-    case KeyEvent.VK_SEMICOLON:
-      return 39;
-    case KeyEvent.VK_QUOTE:
-      return 40;
-
-      // Row #4
-    case KeyEvent.VK_SHIFT:
-      switch (event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 42;
-      case KeyEvent.KEY_LOCATION_RIGHT:
-        return 54;
-      }
-    case KeyEvent.VK_BACK_SLASH:
-      return 43;
-    case KeyEvent.VK_Z:
-      return 44;
-    case KeyEvent.VK_X:
-      return 45;
-    case KeyEvent.VK_C:
-      return 46;
-    case KeyEvent.VK_V:
-      return 47;
-    case KeyEvent.VK_B:
-      return 48;
-    case KeyEvent.VK_N:
-      return 49;
-    case KeyEvent.VK_M:
-      return 50;
-    case KeyEvent.VK_COMMA:
-      return 51;
-    case KeyEvent.VK_PERIOD:
-      return 52;
-    case KeyEvent.VK_SLASH:
-      return 53;
-
-      //
-      // Bottom row
-    case KeyEvent.VK_CONTROL:
-      switch (event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 29;
-      case KeyEvent.KEY_LOCATION_RIGHT:
-        return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 29;
-      }
-    case KeyEvent.VK_WINDOWS:
-      switch (event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 91;
-      case KeyEvent.KEY_LOCATION_RIGHT:
-        return 92;
-      }
-    case KeyEvent.VK_ALT:
-      switch (event.getKeyLocation()) {
-      default:
-      case KeyEvent.KEY_LOCATION_LEFT:
-        return 56;
-      case KeyEvent.KEY_LOCATION_RIGHT:
-        return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 56;
-      }
-    case KeyEvent.VK_ALT_GRAPH:
-      return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 56;
-
-    case KeyEvent.VK_SPACE:
-      return 57;
-
-    case KeyEvent.VK_CONTEXT_MENU:
-      return 93;
-
-      //
-      // Special keys
-    case KeyEvent.VK_PRINTSCREEN:
-      return 55;
-    case KeyEvent.VK_SCROLL_LOCK:
-      return 70;
-    case KeyEvent.VK_PAUSE:
-      return 29;
-
-      // Text navigation keys
-    case KeyEvent.VK_INSERT:
-      return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 82;
-    case KeyEvent.VK_HOME:
-      return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 71;
-    case KeyEvent.VK_PAGE_UP:
-      return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 73;
-    case KeyEvent.VK_DELETE:
-      return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 83;
-    case KeyEvent.VK_END:
-      return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 79;
-    case KeyEvent.VK_PAGE_DOWN:
-      return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 81;
-
-      // Cursor keys
-    case KeyEvent.VK_UP:
-      return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 72;
-    case KeyEvent.VK_LEFT:
-      return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 75;
-    case KeyEvent.VK_DOWN:
-      return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 80;
-    case KeyEvent.VK_RIGHT:
-      return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 77;
-
-      // Keypad
-    case KeyEvent.VK_NUM_LOCK:
-      return 69;
-    case KeyEvent.VK_DIVIDE:
-      return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 53;
-    case KeyEvent.VK_MULTIPLY:
-      return 55;
-    case KeyEvent.VK_SUBTRACT:
-      return 74;
-    case KeyEvent.VK_ADD:
-      return 78;
-
-    case KeyEvent.VK_NUMPAD7:
-      return 71;
-    case KeyEvent.VK_NUMPAD8:
-      return 72;
-    case KeyEvent.VK_NUMPAD9:
-      return 73;
-    case KeyEvent.VK_NUMPAD4:
-      return 75;
-    case KeyEvent.VK_NUMPAD5:
-      return 76;
-    case KeyEvent.VK_NUMPAD6:
-      return 77;
-    case KeyEvent.VK_NUMPAD1:
-      return 79;
-    case KeyEvent.VK_NUMPAD2:
-      return 80;
-    case KeyEvent.VK_NUMPAD3:
-      return 81;
-    case KeyEvent.VK_NUMPAD0:
-      return 82;
-    case KeyEvent.VK_DECIMAL:
-      return 83;
-
-    default:
-      System.err.println("Key is not mapped: " + event + ".");
-      return 57; // Space
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpMouseAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpMouseAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpMouseAdapter.java
deleted file mode 100644
index 371bffc..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpMouseAdapter.java
+++ /dev/null
@@ -1,180 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import java.awt.event.MouseEvent;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-import common.MouseOrder;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240594.aspx
- */
-public class AwtRdpMouseAdapter extends BaseElement {
-  public static int FASTPATH_INPUT_EVENT_MOUSE = 0x01;
-
-  /**
-   * Event is a mouse wheel rotation. The only valid flags in a wheel rotation
-   * event are PTRFLAGS_WHEEL_NEGATIVE and the WheelRotationMask; all other
-   * pointer flags are ignored.
-   */
-  public static int PTRFLAGS_WHEEL = 0x0200;
-
-  /**
-   * Wheel rotation value (contained in the WheelRotationMask bit field) is
-   * negative and MUST be sign-extended before injection at the server.
-   */
-  public static int PTRFLAGS_WHEEL_NEGATIVE = 0x0100;
-
-  /**
-   * Bit field describing the number of rotation units the mouse wheel was
-   * rotated. The value is negative if the PTRFLAGS_WHEEL_NEGATIVE flag is set.
-   */
-  public static int WHEEL_ROTATION_MASK = 0x01FF;
-
-  /**
-   * Indicates that the mouse position MUST be updated to the location specified
-   * by the xPos and yPos fields.
-   */
-  public static int PTRFLAGS_MOVE = 0x0800;
-
-  /**
-   * Indicates that a click event has occurred at the position specified by the
-   * xPos and yPos fields. The button flags indicate which button has been
-   * clicked and at least one of these flags MUST be set.
-   */
-  public static int PTRFLAGS_DOWN = 0x8000;
-
-  /**
-   * Mouse button 1 (left button) was clicked or released. If the PTRFLAGS_DOWN
-   * flag is set, then the button was clicked, otherwise it was released.
-   */
-  public static int PTRFLAGS_BUTTON1 = 0x1000;
-
-  /**
-   * Mouse button 2 (right button) was clicked or released. If the PTRFLAGS_DOWN
-   * flag is set, then the button was clicked, otherwise it was released.
-   */
-  public static int PTRFLAGS_BUTTON2 = 0x2000;
-
-  /**
-   * Mouse button 3 (middle button or wheel) was clicked or released. If the
-   * PTRFLAGS_DOWN flag is set, then the button was clicked, otherwise it was
-   * released.
-   */
-  public static int PTRFLAGS_BUTTON3 = 0x4000;
-
-  public AwtRdpMouseAdapter(String id) {
-    super(id);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    // Get mouse event
-    MouseOrder order = (MouseOrder) buf.getOrder();
-
-    ByteBuffer outBuf = new ByteBuffer(7, true);
-
-    // eventHeader (1 byte): An 8-bit, unsigned integer. EventCode bitfield (top
-    // 3 bits) MUST be set to FASTPATH_INPUT_EVENT_MOUSE (1). The
-    // eventFlags bitfield (low 5 bits) MUST be zeroed out.
-    outBuf.writeByte(FASTPATH_INPUT_EVENT_MOUSE << 5);
-
-    // pointerFlags (2 bytes): A 16-bit, unsigned integer.
-    outBuf.writeShortLE(getPointerFlags(order));
-
-    // xPos (2 bytes): A 16-bit, unsigned integer. The x-coordinate of the
-    // pointer.
-    outBuf.writeShortLE(order.event.getX());
-
-    // yPos (2 bytes): A 16-bit, unsigned integer. The y-coordinate of the
-    // pointer.
-    outBuf.writeShortLE(order.event.getY());
-
-    // Push buffer to one pad only, so it can be modified without copying of
-    // data
-    pushDataToPad(STDOUT, outBuf);
-  }
-
-  // Remember mouse buttons
-  protected boolean button1, button2, button3;
-
-  protected int getPointerFlags(MouseOrder order) {
-    int flags = 0;
-
-    int modifiers = order.event.getModifiersEx();
-
-    if (order.pressed) {
-      // Mouse pressed
-      flags |= PTRFLAGS_DOWN;
-      
-      // Check, which one of buttons is released
-      boolean b1 = ((modifiers & MouseEvent.BUTTON1_DOWN_MASK) > 0) && !button1;
-      boolean b2 = ((modifiers & MouseEvent.BUTTON2_DOWN_MASK) > 0) && !button2;
-      boolean b3 = ((modifiers & MouseEvent.BUTTON3_DOWN_MASK) > 0) && !button3;
-
-      if (b1) {
-        flags |= PTRFLAGS_BUTTON1;
-        button1 = true;
-      }
-
-      if (b2) {
-        flags |= PTRFLAGS_BUTTON3;
-        button2 = true;
-      }
-
-      if (b3) {
-        flags |= PTRFLAGS_BUTTON2;
-        button3 = true;
-      }
-    } else if (order.released) {
-      // Mouse released
-      
-      // Check, which one of buttons is released
-      boolean b1 = !((modifiers & MouseEvent.BUTTON1_DOWN_MASK) > 0) && button1;
-      boolean b2 = !((modifiers & MouseEvent.BUTTON2_DOWN_MASK) > 0) && button2;
-      boolean b3 = !((modifiers & MouseEvent.BUTTON3_DOWN_MASK) > 0) && button3;
-
-      if (b1) {
-        flags |= PTRFLAGS_BUTTON1;
-        button1 = false;
-      }
-
-      if (b2) {
-        flags |= PTRFLAGS_BUTTON3;
-        button2 = false;
-      }
-
-      if (b3) {
-        flags |= PTRFLAGS_BUTTON2;
-        button3 = false;
-      }
-    } else {
-      // Mouse moved
-      flags |= PTRFLAGS_MOVE;
-    }
-
-    return flags;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientConfirmActivePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientConfirmActivePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientConfirmActivePDU.java
deleted file mode 100644
index 9a1caab..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientConfirmActivePDU.java
+++ /dev/null
@@ -1,1132 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-import common.ScreenDescription;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240488.aspx
- */
-public class ClientConfirmActivePDU extends BaseElement {
-
-  public static final String SOURCE_DESC = "MSTSC";
-
-  public static final int CAPSTYPE_BITMAP = 0x2;
-
-  protected int numberCapabilities;
-  
-  protected RdpState state;
-  protected ScreenDescription screen;
-
-  protected boolean desktopResize = false;
-  protected int prefferedBitsPerPixel = 16;
-
-  public ClientConfirmActivePDU(String id, ScreenDescription screen, RdpState state) {
-    super(id);
-    this.state = state;
-    this.screen = screen;
-  }
-
-  @Override
-  public void handleData(ByteBuffer aBuf, Link link) {
-
-    // Body
-    ByteBuffer buf = new ByteBuffer(1024, true);
-    numberCapabilities = 0;
-    writeCapabilities(buf);
-    buf.trimAtCursor();
-
-    // Header
-    ByteBuffer header = createMCSHeader(buf);
-
-    // Length of source descriptor, including NULL character (LE)
-    header.writeShortLE(SOURCE_DESC.length() + 1);
-
-    // Length of combined capabilities + 4 bytes (number of capabilities and
-    // padding) (LE)
-    header.writeShortLE(buf.length + 4);
-
-    header.writeString(SOURCE_DESC, RdpConstants.CHARSET_8);
-    header.writeByte(0);
-
-    // Number of capabilities
-    header.writeShortLE(numberCapabilities);
-
-    // Padding 2 bytes
-    header.writeShortLE(0);
-
-    header.trimAtCursor();
-
-    // Prepend header to capabilities
-    buf.prepend(header);
-
-    // Trim buffer to actual length of data written
-    buf.length = buf.cursor;
-
-    pushDataToPad(STDOUT, buf);
-
-    sendOtherRequredPackets();
-
-  }
-
-  private ByteBuffer createMCSHeader(ByteBuffer buf) {
-    ByteBuffer header = new ByteBuffer(100);
-    // MCS Send Data Request
-    header.writeByte(0x64);
-
-    // Initiator: 1004 (1001+3)
-    header.writeShort(3);
-
-    // Channel ID: 1003 (I/O channel)
-    header.writeShort(1003);
-
-    // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-    header.writeByte(0x70);
-
-    int length = buf.length + 26;
-
-    // User data length: (variable length field, LE)
-    header.writeVariableShort(length);
-
-    // Total length: (LE)
-    header.writeShortLE(length);
-
-    // PDU type: Confirm Active PDU (0x3), TS_PROTOCOL_VERSION (0x10) (LE)
-    header.writeShortLE(0x13);
-
-    // PDU source: 1004 (LE)
-    header.writeShortLE(1004);
-
-    // Share ID, e.g. 0x000103ea (LE)
-    header.writeIntLE((int) state.serverShareId);
-
-    // Originator ID: 1002 (LE)
-    header.writeShortLE(1002);
-    return header;
-  }
-
-  private void sendOtherRequredPackets() {
-    // Send sequence in bulk
-
-    sendSynchronizePDU();
-    sendControlPDUActionCooperate();
-    sendControlPDUActionRequestControl();
-    // sendBitmapCachePersistentListPDU();
-    sendFontListPDU();
-  }
-
-  private void sendFontListPDU() {
-    {
-      int length = 1024; // Large enough
-      ByteBuffer buf = new ByteBuffer(length, true);
-
-      /* @formatter:off */
-      buf.writeBytes(new byte[] {
-          // MCS Send Data Request
-          (byte)0x64,
-          // Initiator: 1004 (1001+3)
-          (byte)0x00, (byte)0x03, 
-          // Channel ID: 1003 (I/O channel)
-          (byte)0x03, (byte)0xeb, 
-          // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-          (byte)0x70, 
-          // User data length: 26 bytes (0x1a, variable length field)
-          (byte)0x80, (byte)0x1a,
-          
-          // Total length: 26 bytes (0x1a, LE)
-          (byte)0x1a, (byte)0x00, 
-          // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE)
-          (byte)0x17, (byte)0x00, 
-          // PDU source: 1004 (LE)
-          (byte)0xec, (byte)0x03, 
-      });
-      // Share ID, 4 bytes  (LE)
-      buf.writeIntLE((int)state.serverShareId);
-      
-      buf.writeBytes(new byte[] {
-          // Padding 1 byte
-          (byte)0x00, 
-          // Stream ID: STREAM_LOW (1)
-          (byte)0x01, 
-          // uncompressedLength : 12 bytes (LE)
-          (byte)0x0c, (byte)0x00,
-          
-          // pduType2: PDUTYPE2_FONTLIST (39)
-          (byte)0x27, 
-          // generalCompressedType: 0
-          (byte)0x00, 
-          // generalCompressedLength: 0 (LE)
-          (byte)0x00, (byte)0x00, 
-
-          // numberEntries (should be set to zero): 0 (LE)
-          (byte)0x00, (byte)0x00,
-          // totalNumEntries (should be set to zero): 0 (LE)
-          (byte)0x00, (byte)0x00,
-          // listFlags  (should be set to 0x3): 0x0003 (LE), FONTLIST_LAST(0x2) | FONTLIST_FIRST(0x1) 
-          (byte)0x03, (byte)0x00,
-          // entrySize: 50 bytes (0x0032, LE)
-          (byte)0x32, (byte)0x00,
-      });
-      /* @formatter:on */
-
-      // Trim buffer to actual length of data written
-      buf.trimAtCursor();
-
-      pushDataToPad(STDOUT, buf);
-    }
-  }
-
-  private void sendControlPDUActionRequestControl() {
-    int length = 1024; // Large enough
-    ByteBuffer buf = new ByteBuffer(length, true);
-
-    /* @formatter:off */
-    buf.writeBytes(new byte[] {
-        // MCS Send Data Request
-        (byte)0x64, 
-        // Initiator: 1004 (1001+3)
-        (byte)0x00, (byte)0x03,
-        // Channel ID: 1003 (I/O channel)
-        (byte)0x03, (byte)0xeb, 
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        (byte)0x70, 
-        // User data length: 26 bytes (0x1a, variable length field)
-        (byte)0x80, (byte)0x1a,
-        
-        // Total length: 26 bytes (0x1a, LE)
-        (byte)0x1a, (byte)0x00,
-        // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE)
-        (byte)0x17, (byte)0x00, 
-        // PDU source: 1004 (LE)
-        (byte)0xec, (byte)0x03,
-    });
-        // Share ID, 4 bytes  (LE)
-    buf.writeIntLE((int)state.serverShareId);
-        
-    buf.writeBytes(new byte[] {
-        // Padding 1 byte
-        (byte)0x00, 
-        // Stream ID: STREAM_LOW (1)
-        (byte)0x01, 
-        // uncompressedLength : 12 bytes (LE)
-        (byte)0x0c, (byte)0x00, 
-        // pduType2: PDUTYPE2_CONTROL (20)
-        (byte)0x14, 
-        // generalCompressedType: 0
-        (byte)0x00, 
-        // generalCompressedLength: 0 (LE)
-        (byte)0x00, (byte)0x00,
-        
-        // action: CTRLACTION_REQUEST_CONTROL (1) (LE)
-        (byte)0x01, (byte)0x00,
-        // grantId: 0 (LE)
-        (byte)0x00, (byte)0x00, 
-        // controlId: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-    });
-    /* @formatter:on */
-
-    // Trim buffer to actual length of data written
-    buf.trimAtCursor();
-
-    pushDataToPad(STDOUT, buf);
-  }
-
-  private void sendControlPDUActionCooperate() {
-    int length = 1024; // Large enough
-    ByteBuffer buf = new ByteBuffer(length, true);
-
-    /* @formatter:off */
-    buf.writeBytes(new byte[] {
-        // MCS Send Data Request
-        (byte)0x64, 
-        // Initiator: 1004 (1001+3)
-        (byte)0x00, (byte)0x03, 
-        // Channel ID: 1003 (I/O channel)
-        (byte)0x03, (byte)0xeb, 
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        (byte)0x70, 
-        // User data length: 26 bytes (0x1a, variable length field)
-        (byte)0x80, (byte)0x1a,
-        
-        // Total length: 26 bytes (0x1a, LE)
-        (byte)0x1a,(byte)0x00,
-        // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE)
-        (byte)0x17, (byte)0x00, 
-        // PDU source: 1004 (LE)
-        (byte)0xec, (byte)0x03, 
-    });
-    // Share ID, 4 bytes  (LE)
-    buf.writeIntLE((int)state.serverShareId);
-    
-    buf.writeBytes(new byte[] {
-        // Padding 1 byte
-        (byte)0x00, 
-        // Stream ID: STREAM_LOW (1)
-        (byte)0x01, 
-        // uncompressedLength : 12 bytes (LE)
-        (byte)0x0c, (byte)0x00, 
-        // pduType2: PDUTYPE2_CONTROL (20)
-        (byte)0x14, 
-        // generalCompressedType: 0
-        (byte)0x00, 
-        // generalCompressedLength: 0 (LE?)
-        (byte)0x00, (byte)0x00, 
-        // action: CTRLACTION_COOPERATE (4) (LE)
-        (byte)0x04, (byte)0x00,
-        // grantId: 0 (LE)
-        (byte)0x00, (byte)0x00,
-        // controlId: 0
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-    });
-    /* @formatter:on */
-
-    buf.trimAtCursor();
-
-    pushDataToPad(STDOUT, buf);
-  }
-
-  private void sendSynchronizePDU() {
-
-    ByteBuffer buf = new ByteBuffer(1024, true);
-    /* @formatter:off */
-    buf.writeBytes(new byte[] {
-        // MCS send data request
-        (byte)0x64,
-        // Initiator: 1004 (1001+3)
-        (byte)0x00, (byte)0x03,
-        // Channel ID: 1003 (I/O Channel)
-        (byte)0x03, (byte)0xeb,
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        (byte)0x70, 
-        // Data length:  22 bytes (0x16, variable length field)
-        (byte)0x80,  (byte)0x16, 
-        
-        // RDP: total length: 22 bytes (LE)
-        (byte)0x16, (byte)0x00, 
-        
-        // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE)
-        (byte)0x17, (byte)0x00,
-        
-        // PDU source: 1007 (LE)
-        (byte)0xec, (byte)0x03,
-    });
-    // Share ID, 4 bytes  (LE)
-    buf.writeIntLE((int)state.serverShareId);
-    
-    buf.writeBytes(new byte[] {
-        // Padding: 1 byte
-        (byte)0x00,
-        // Stream ID: STREAM_LOW (1)
-        (byte)0x01, 
-        // uncompressedLength : 8 bytes (LE)
-        (byte)0x08, (byte)0x00,
-        // pduType2 = PDUTYPE2_SYNCHRONIZE (31)
-        (byte)0x1f, 
-        // generalCompressedType: 0
-        (byte)0x00,
-        // generalCompressedLength: 0 (LE?)
-        (byte)0x00, (byte)0x00,
-        //  messageType: SYNCMSGTYPE_SYNC (1) (LE)
-        (byte)0x01, (byte)0x00, 
-        // targetUser: 0x03ea
-        (byte)0xea, (byte)0x03,
-    });
-    /* @formatter:on */
-    buf.trimAtCursor();
-    pushDataToPad(STDOUT, buf);
-  }
-
-  private void writeCapabilities(ByteBuffer buf) {
-    writeGeneralCS(buf);
-
-    writeBitmapCS(buf);
-
-    writeOrderCS(buf);
-
-    writeBitmapCache2CS(buf);
-
-    writeColorTableCacheCS(buf);
-
-    writeWindowActivationCS(buf);
-
-    writeControlCS(buf);
-
-    writePointerCS(buf);
-
-    writeShareCS(buf);
-
-    writeInputCS(buf);
-
-    writeBrushCS(buf);
-
-    writeSoundCS(buf);
-
-    writeFontCS(buf);
-
-    writeOffscreenBitmapCS(buf);
-
-    writeGlyphCacheCS(buf);
-  }
-
-  private void writeBrushCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        //
-        // Brush Capability Set (8 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240564.aspx
-        (byte) 0x0f, (byte) 0x00, // capability set type: CAPSTYPE_BRUSH (15,
-                                  // LE)
-        (byte) 0x08, (byte) 0x00, // length of capability set: 8 bytes (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // brushSupportLevel:
-                                                            // BRUSH_DEFAULT
-                                                            // (0x0, LE)
-
-    });
-  }
-
-  private void writeInputCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        //
-        // Input Capability Set (88 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240563.aspx
-        (byte) 0x0d,
-        (byte) 0x00, // capability set type: CAPSTYPE_INPUT (13, LE)
-        (byte) 0x58,
-        (byte) 0x00, // length of capability set: 88 bytes (LE)
-        (byte) 0x35,
-        (byte) 0x00, // inputFlags: 0x0035 (LE), INPUT_FLAG_FASTPATH_INPUT2
-                     // (0x20), INPUT_FLAG_VKPACKET (0x10), INPUT_FLAG_MOUSEX
-                     // (0x4), INPUT_FLAG_SCANCODES (0x1)
-        (byte) 0x00,
-        (byte) 0x00, // Padding 2 bytes
-        (byte) 0x09,
-        (byte) 0x04,
-        (byte) 0x00,
-        (byte) 0x00, // keyboardLayout: "US" keyboard layout (0x000409, LE)
-        (byte) 0x00,
-        (byte) 0x00,
-        (byte) 0x00,
-        (byte) 0x00, // keyboardType: unknown (LE)
-        (byte) 0x00,
-        (byte) 0x00,
-        (byte) 0x00,
-        (byte) 0x00, // keyboardSubType: unknown (LE)
-        (byte) 0x00,
-        (byte) 0x00,
-        (byte) 0x00,
-        (byte) 0x00, // keyboardFunctionKey: unknown (LE)
-        // imeFileName: "", (64 bytes, including trailing NULL characters, UCS2)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-
-    });
-  }
-
-  private void writeShareCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        //
-        // Share Capability Set (8 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240570.aspx
-        (byte) 0x09, (byte) 0x00, // capability set type: CAPSTYPE_SHARE (9, LE)
-        (byte) 0x08, (byte) 0x00, // length of capability set: 8 bytes (LE)
-        (byte) 0x00, (byte) 0x00, // nodeID (must be set to 0 by client): 0 (LE)
-        (byte) 0x00, (byte) 0x00, // Padding 2 bytes (LE)
-
-    });
-  }
-
-  private void writePointerCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        //
-        // Pointer Capability Set (10 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240562.aspx
-        (byte) 0x08, (byte) 0x00, // capability set type: CAPSTYPE_POINTER (8,
-                                  // LE)
-        (byte) 0x0a, (byte) 0x00, // length of capability set: 10 bytes (LE)
-        (byte) 0x00, (byte) 0x00, // colorPointerFlag: FALSE (LE)
-        (byte) 0x00, (byte) 0x00, // colorPointerCacheSize: 0 (LE)
-        (byte) 0x14, (byte) 0x00, // pointerCacheSize: 20 (LE)
-
-    });
-  }
-
-  private void writeControlCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        //
-        // Control Capability Set (12 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240568.aspx
-        (byte) 0x05, (byte) 0x00, // capability set type: CAPSTYPE_ACTIVATION
-                                  // (7)
-        (byte) 0x0c, (byte) 0x00, // length of capability set: 12 bytes (LE)
-        (byte) 0x00, (byte) 0x00, // controlFlags (should be set to 0): 0 (LE)
-        (byte) 0x00, (byte) 0x00, // remoteDetachFlag (should be set to 0): 0
-                                  // (LE)
-        (byte) 0x02, (byte) 0x00, // controlInterest (should be set to
-                                  // CONTROLPRIORITY_NEVER):
-                                  // CONTROLPRIORITY_NEVER (2) (LE)
-        (byte) 0x02, (byte) 0x00, // detachInterest (should be set to
-                                  // CONTROLPRIORITY_NEVER):
-                                  // CONTROLPRIORITY_NEVER (2) (LE)
-
-    });
-  }
-
-  private void writeWindowActivationCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        //
-        // Window Activation Capability Set (12 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240569.aspx
-        (byte) 0x07, (byte) 0x00, // capability set type: CAPSTYPE_ACTIVATION
-                                  // (7) (LE)
-        (byte) 0x0c, (byte) 0x00, // length of capability set: 12 bytes (LE)
-        (byte) 0x00, (byte) 0x00, // helpKeyFlag (should be set to FALSE (0)):
-                                  // FALSE (0, LE)
-        (byte) 0x00, (byte) 0x00, // helpKeyIndexFlag (should be set to FALSE
-                                  // (0)): FALSE (0, LE)
-        (byte) 0x00, (byte) 0x00, // helpExtendedKeyFlag (should be set to FALSE
-                                  // (0)): FALSE (0, LE)
-        (byte) 0x00, (byte) 0x00, // windowManagerKeyFlag (should be set to
-                                  // FALSE (0)): FALSE (0, LE)
-
-    });
-  }
-
-  private void writeColorTableCacheCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-
-        //
-        // Color Table Cache Capability Set (8 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc241564.aspx
-        (byte) 0x0a, (byte) 0x00, // capability set type: CAPSTYPE_COLORCACHE
-                                  // (10) (LE)
-        (byte) 0x08, (byte) 0x00, // length of capability set: 8 bytes (LE)
-        (byte) 0x06, (byte) 0x00, // Color table cache size (must be ignored
-                                  // during capability exchange and is assumed
-                                  // to be 0x0006): 6 (LE)
-        (byte) 0x00, (byte) 0x00, // Padding 2 bytes
-
-    });
-  }
-
-  private void writeBitmapCache2CS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        //
-        // Bitmap Cache Rev. 2 Capability Set (40 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240560.aspx
-        (byte) 0x13, (byte) 0x00, // capability set type:
-                                  // CAPSTYPE_BITMAPCACHE_REV2 (19) (LE)
-        (byte) 0x28, (byte) 0x00, // length of capability set: 40 bytes (LE)
-        (byte) 0x00, (byte) 0x00, // Cache flags: 0 (LE)
-        (byte) 0x00, // Padding 1 byte
-        (byte) 0x00, // Number of cell caches: 0
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Bitmap cache0
-                                                            // cell info: 0 (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Bitmap cache1
-                                                            // cell info: 0 (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Bitmap cache2
-                                                            // cell info: 0 (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Bitmap cache3
-                                                            // cell info: 0 (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Bitmap cache4
-                                                            // cell info: 0 (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Padding 12 bytes
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Padding
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Padding
-    });
-  }
-
-  private void writeGeneralCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        // Capabilities, see
-        // http://msdn.microsoft.com/en-us/library/cc240486.aspx
-
-        //
-        // General capability set (24 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240549.aspx
-        (byte) 0x01, (byte) 0x00, // capability set type: CAPSTYPE_GENERAL (1)
-                                  // (LE)
-        (byte) 0x18, (byte) 0x00, // length of capability set: 24 bytes (LE)
-        (byte) 0x01, (byte) 0x00, // TS_OSMAJORTYPE_WINDOWS (1) (LE)
-        (byte) 0x03, (byte) 0x00, // TS_OSMINORTYPE_WINDOWS_NT (3) (LE)
-        (byte) 0x00, (byte) 0x02, // TS_CAPS_PROTOCOLVERSION (0x0200) (LE)
-        (byte) 0x00, (byte) 0x00, // Padding 2 bytes
-        (byte) 0x00, (byte) 0x00, // generalCompressionTypes: 0 (LE)
-
-        // Extra flags: 0x040d (LE)
-        // FastPathOutput: (...............1) Advertiser supports fast-path
-        // output
-        // ShadowCompression: (..............0.) Advertiser NOT supports shadow
-        // compression
-        // LongLengthCredentials: (.............1..) Advertiser supports
-        // long-length credentials for the user name, password, or domain name
-        // SessionAutoreconnection: (............1...) Advertiser supports
-        // session auto-reconnection
-        // ImprovedEncryptionChecksum: (...........0....) Client and server NOT
-        // support improved encryption checksum
-        // Reserved1: (......00000.....)
-        // CompressedBitMapDataFlag: (.....1..........) No 8-UINT8 header is
-        // present for compressed bitmap data
-        // Reserved2: (00000...........)
-        (byte) 0x0d, (byte) 0x04,
-
-        (byte) 0x00, (byte) 0x00, // updateCapabilityFlag: 0 (LE)
-        (byte) 0x00, (byte) 0x00, // remoteUnshareFlag: 0 (LE)
-        (byte) 0x00, (byte) 0x00, // generalCompressionLevel: 0 (LE)
-        (byte) 0x00, // refreshRectSupport: FALSE (0)
-        (byte) 0x00, // suppressOutputSupport: FALSE (0)
-
-    });
-  }
-
-  private void writeBitmapCS(ByteBuffer buf) {
-    // Bitmap capability set (28 bytes), see
-    // http://msdn.microsoft.com/en-us/library/cc240554.aspx
-    
-    numberCapabilities++;
-    
-    // Capability set type: CAPSTYPE_BITMAP (2) (LE)
-    buf.writeShortLE(CAPSTYPE_BITMAP);
-    
-    // Length of capability set: 28 bytes (LE)
-    buf.writeShortLE(28);
-    
-    // preferredBitsPerPixel: 16 bpp (LE)
-    buf.writeShortLE(prefferedBitsPerPixel);
-    
-    // receive1BitPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
-    buf.writeShortLE(1);
-    
-    // receive4BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
-    buf.writeShortLE(1);
-    
-    // receive8BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
-    buf.writeShortLE(1);
-    
-    // Desktop width and height (LE)
-    buf.writeShortLE(screen.getFramebufferWidth());
-    buf.writeShortLE(screen.getFramebufferHeight());
-    
-    // Padding 2 bytes
-    buf.writeShortLE(0);
-    
-   // desktopResizeFlag (LE)
-    buf.writeShortLE((desktopResize )?1:0);
-    
-    buf.writeBytes(new byte[] {
-        (byte) 0x01, (byte) 0x00, // bitmapCompressionFlag (must be set to TRUE
-                                  // (0x1)): TRUE (0x1) (LE)
-        (byte) 0x00, // highColorFlags (field is ignored and SHOULD be set to
-                     // zero): 0
-        (byte) 0x01, // drawingFlags: 0x1 TODO: padding, why 0x1 ???
-        (byte) 0x01, (byte) 0x00, // multipleRectangleSupport: TRUE (LE)
-        (byte) 0x00, (byte) 0x00, // Padding 2 bytes
-
-    });
-  }
-
-  private void writeOrderCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        //
-        // Order Capability Set (88 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240556.aspx
-        (byte) 0x03,
-        (byte) 0x00, // capability set type: CAPSTYPE_ORDER (3) (LE)
-        (byte) 0x58,
-        (byte) 0x00, // length of capability set: 88 bytes (LE)
-        // terminalDescriptor = "" (16 bytes, UCS2)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // pad4octetsA
-        (byte) 0x01, (byte) 0x00, // desktopSaveXGranularity (ignored): 1 (LE)
-        (byte) 0x14, (byte) 0x00, // desktopSaveYGranularity (ignored): 20 (LE)
-        (byte) 0x00, (byte) 0x00, // pad2octetsA (ignored)
-        (byte) 0x01, (byte) 0x00, // maximumOrderLevel: ORD_LEVEL_1_ORDERS (1)
-        (byte) 0x00, (byte) 0x00, // number of fonts (ignored): 0
-        (byte) 0x4a, (byte) 0x00, // orderFlags = 0x004a (LE),
-                                  // SOLIDPATTERNBRUSHONLY (0x40),
-                                  // ZEROBOUNDSDELTASSUPPORT (0x8, MUST),
-                                  // NEGOTIATEORDERSUPPORT (0x2, MUST)
-        // Order support: 32 bytes (no primary drawing orders are supported, so
-        // this array MUST be initialized to all zeros, use 0x01 for TRUE).
-        (byte) 0x00, // TS_NEG_DSTBLT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_PATBLT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_SCRBLT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_MEMBLT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_MEM3BLT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_ATEXTOUT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_AEXTTEXTOUT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_DRAWNINEGRID_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_LINETO_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_MULTI_DRAWNINEGRID_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_OPAQUERECT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_SAVEBITMAP_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_WTEXTOUT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_MEMBLT_R2_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_MEM3BLT_R2_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_MULTIDSTBLT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_MULTIPATBLT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_MULTISCRBLT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_MULTIOPAQUERECT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_FAST_INDEX_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_POLYGON_SC_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_POLYGON_CB_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_POLYLINE_INDEX: TRUE
-        (byte) 0x00, // Unused: 0
-        (byte) 0x00, // TS_NEG_FAST_GLYPH_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_ELLIPSE_SC_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_ELLIPSE_CB_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_INDEX_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_WEXTTEXTOUT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_WLONGTEXTOUT_INDEX: FALSE
-        (byte) 0x00, // TS_NEG_WLONGEXTTEXTOUT_INDEX: FALSE
-        (byte) 0x00, // Unused: 0
-        (byte) 0x00, (byte) 0x00, // Text flags (ignored): 0 (LE)
-        (byte) 0x00, (byte) 0x00, // Order support extra flags: 0 (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Padding 4 bytes
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Desktop save size
-                                                            // (ignored): 0
-                                                            // (assumed to be
-                                                            // 230400 bytes
-                                                            // (480*480,
-                                                            // 0x38400, LE))
-        (byte) 0x00, (byte) 0x00, // Padding 2 bytes
-        (byte) 0x00, (byte) 0x00, // Padding 2 bytes
-        (byte) 0xe4, (byte) 0x04, // Text ANSI Code Page: 1252, ANSI - Latin I
-                                  // (0x04e4, LE)
-        (byte) 0x00, (byte) 0x00, // Padding 2 bytes
-
-    });
-  }
-
-  private void writeSoundCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        //
-        // Sound Capability Set (8 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240552.aspx
-        (byte) 0x0c, (byte) 0x00, // capability set type: CAPSTYPE_SOUND (12,
-                                  // LE)
-        (byte) 0x08, (byte) 0x00, // length of capability set: 8 bytes (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // soundFlags:
-                                                            // 0x0000 (LE) //
-                                                            // SOUND_FLAG_BEEPS
-                                                            // (0x1)
-
-    });
-  }
-
-  private void writeFontCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        //
-        // Font Capability Set (8 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240571.aspx
-        (byte) 0x0e, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-
-    });
-  }
-
-  private void writeOffscreenBitmapCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        //
-        // Offscreen Bitmap Cache Capability Set (12 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240550.aspx
-        (byte) 0x11, (byte) 0x00, // capability set type:
-                                  // CAPSTYPE_OFFSCREENCACHE (17, LE)
-        (byte) 0x0c, (byte) 0x00, // length of capability set: 12 bytes (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // offscreenSupportLevel:
-                                                            // FALSE (LE)
-        (byte) 0x00, (byte) 0x00, // offscreenCacheSize: 0 (LE)
-        (byte) 0x00, (byte) 0x00, // offscreenCacheEntries: 0 (LE)
-
-    });
-  }
-
-  private void writeGlyphCacheCS(ByteBuffer buf) {
-    numberCapabilities++;
-    buf.writeBytes(new byte[] {
-        //
-        // Glyph Cache Capability Set (52 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240565.aspx
-        (byte) 0x10, (byte) 0x00, // capability set type:
-                                  // CAPSTYPE_OFFSCREENCACHE (16, LE)
-        (byte) 0x34, (byte) 0x00, // length of capability set: 52 bytes (LE)
-        // Glyph Cache (40 bytes)
-        (byte) 0xfe, (byte) 0x00, // CacheEntries: 254 (LE)
-        (byte) 0x04, (byte) 0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte) 0xfe, (byte) 0x00, // CacheEntries: 254 (LE)
-        (byte) 0x04, (byte) 0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte) 0xfe, (byte) 0x00, // CacheEntries: 254 (LE)
-        (byte) 0x08, (byte) 0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte) 0xfe, (byte) 0x00, // CacheEntries: 254 (LE)
-        (byte) 0x08, (byte) 0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte) 0xfe, (byte) 0x00, // CacheEntries: 254 (LE)
-        (byte) 0x10, (byte) 0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte) 0xfe, (byte) 0x00, // CacheEntries: 254 (LE)
-        (byte) 0x20, (byte) 0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte) 0xfe, (byte) 0x00, // CacheEntries: 254 (LE)
-        (byte) 0x40, (byte) 0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte) 0xfe, (byte) 0x00, // CacheEntries: 254 (LE)
-        (byte) 0x80, (byte) 0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte) 0xfe, (byte) 0x00, // CacheEntries: 254 (LE)
-        (byte) 0x00, (byte) 0x01, // CacheMaximumCellSize: 4 (LE)
-        (byte) 0x40, (byte) 0x00, // CacheEntries: 64 (LE)
-        (byte) 0x00, (byte) 0x08, // CacheMaximumCellSize: 2048 (LE)
-        // FragCache
-        (byte) 0x00, (byte) 0x01, // CacheEntries: 256 (LE)
-        (byte) 0x00, (byte) 0x01, // CacheMaximumCellSize: 256 (LE)
-        //
-        (byte) 0x00, (byte) 0x00, // GlyphSupportLevel: GLYPH_SUPPORT_NONE (0x0,
-                                  // LE)
-        (byte) 0x00, (byte) 0x00, // Padding 2 bytes
-    });
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    /* @formatter:off */
-    byte[] packet = new byte[] {
-        // MCS Send Data Request
-        (byte)0x64,  
-        
-        // Initiator: 1004 (1001+3)
-        (byte)0x00, (byte)0x03, 
-        
-        // Channel ID: 1003 (I/O channel)
-        (byte)0x03, (byte)0xeb,
-        
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        (byte)0x70,
-        
-        // User data length: 432 bytes (0x1b0, variable length field)
-        (byte)0x81, (byte)0xb0, 
-        
-        // Total length: 432 bytes (0x1b0, LE)
-        (byte)0xb0, (byte)0x01, 
-        
-        // PDU type: Confirm Active PDU (0x3), TS_PROTOCOL_VERSION (0x10) (LE)
-        (byte)0x13, (byte)0x00, 
-        
-        // PDU source: 1004 (LE)
-        (byte)0xec, (byte)0x03, 
-        
-        // Share ID: 0x000103ea (LE)
-        (byte)0xea, (byte)0x03, (byte)0x01, (byte)0x00,
-        
-        // Originator ID: 1002 (LE)
-        (byte)0xea, (byte)0x03,
-        
-        // Length of source descriptor: 6 bytes (including NULL character) (LE) 
-        (byte)0x06, (byte)0x00, 
-        
-        // Length of combined capabilities: 410 bytes (LE)
-        (byte)0x9a, (byte)0x01,
-        
-        // Source descriptor: "MSTSC" ???
-        (byte)0x4d, (byte)0x53, (byte)0x54, (byte)0x53, (byte)0x43, (byte)0x00,
-        
-        // Number of capabilities: 15 (LE)
-        (byte)0x0f, (byte)0x00,
-        
-        // Padding 2 bytes
-        (byte)0x00, (byte)0x00,
-        
-        // Capabilities, see http://msdn.microsoft.com/en-us/library/cc240486.aspx
-        
-        //
-        // General capability set (24 bytes), see http://msdn.microsoft.com/en-us/library/cc240549.aspx
-        (byte)0x01, (byte)0x00, // capability set type: CAPSTYPE_GENERAL (1) (LE) 
-        (byte)0x18, (byte)0x00, // length of capability set: 24 bytes (LE)
-        (byte)0x01, (byte)0x00, // TS_OSMAJORTYPE_WINDOWS (1) (LE)
-        (byte)0x03, (byte)0x00, // TS_OSMINORTYPE_WINDOWS_NT (3) (LE)
-        (byte)0x00, (byte)0x02, // TS_CAPS_PROTOCOLVERSION (0x0200) (LE)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-        (byte)0x00, (byte)0x00, // generalCompressionTypes: 0 (LE)
-        
-        // Extra flags: 0x040d (LE)
-//        FastPathOutput:             (...............1) Advertiser supports fast-path output
-//        ShadowCompression:          (..............0.) Advertiser NOT supports shadow compression
-//        LongLengthCredentials:      (.............1..) Advertiser supports long-length credentials for the user name, password, or domain name
-//        SessionAutoreconnection:    (............1...) Advertiser supports session auto-reconnection
-//        ImprovedEncryptionChecksum: (...........0....) Client and server NOT support improved encryption checksum
-//        Reserved1:                  (......00000.....)
-//        CompressedBitMapDataFlag:   (.....1..........) No 8-UINT8 header is present for compressed bitmap data
-//        Reserved2:                  (00000...........)
-        (byte)0x0d, (byte)0x04,
-        
-        (byte)0x00, (byte)0x00, // updateCapabilityFlag: 0 (LE)
-        (byte)0x00, (byte)0x00, // remoteUnshareFlag: 0 (LE)
-        (byte)0x00, (byte)0x00, // generalCompressionLevel: 0 (LE)
-        (byte)0x00, // refreshRectSupport: FALSE (0)
-        (byte)0x00, // suppressOutputSupport: FALSE (0)
-        
-        //
-        // Bitmap capability set (28 bytes), see http://msdn.microsoft.com/en-us/library/cc240554.aspx
-        (byte)0x02, (byte)0x00, // capability set type: CAPSTYPE_BITMAP (2) (LE)
-        (byte)0x1c, (byte)0x00, // length of capability set: 28 bytes (LE)
-        (byte)0x10, (byte)0x00, // preferredBitsPerPixel: 16 bpp (LE)
-        (byte)0x01, (byte)0x00, // receive1BitPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
-        (byte)0x01, (byte)0x00, // receive4BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
-        (byte)0x01, (byte)0x00, // receive8BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
-        (byte)0x00, (byte)0x04, // desktopWidth = 1024 pixels (LE)
-        (byte)0x00, (byte)0x03, // desktopHeight = 768 pixels (LE)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-        (byte)0x00, (byte)0x00, // desktopResizeFlag: FALSE (0x0) (LE)
-        (byte)0x01, (byte)0x00, // bitmapCompressionFlag (must be set to TRUE (0x1)): TRUE (0x1) (LE)
-        (byte)0x00, // highColorFlags (field is ignored and SHOULD be set to zero): 0 
-        (byte)0x01, // drawingFlags: 0x1 TODO: padding, why 0x1 ???
-        (byte)0x01, (byte)0x00, // multipleRectangleSupport: TRUE (LE) 
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-        
-        //
-        // Order Capability Set (88 bytes), see http://msdn.microsoft.com/en-us/library/cc240556.aspx
-        (byte)0x03, (byte)0x00, // capability set type: CAPSTYPE_ORDER (3) (LE)
-        (byte)0x58, (byte)0x00, // length of capability set: 88 bytes (LE)
-        // terminalDescriptor = "" (16 bytes, UCS2)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // pad4octetsA 
-        (byte)0x01, (byte)0x00, // desktopSaveXGranularity (ignored): 1 (LE)
-        (byte)0x14, (byte)0x00, // desktopSaveYGranularity (ignored): 20 (LE)
-        (byte)0x00, (byte)0x00, // pad2octetsA (ignored)
-        (byte)0x01, (byte)0x00, // maximumOrderLevel: ORD_LEVEL_1_ORDERS (1) 
-        (byte)0x00, (byte)0x00, // number of fonts (ignored): 0 
-        (byte)0x4a, (byte)0x00, // orderFlags = 0x004a (LE), SOLIDPATTERNBRUSHONLY (0x40), ZEROBOUNDSDELTASSUPPORT (0x8, MUST), NEGOTIATEORDERSUPPORT (0x2, MUST)
-        // Order support: 32 bytes (no primary drawing orders are supported, so this array MUST be initialized to all zeros, use 0x01 for TRUE).
-        (byte)0x00, // TS_NEG_DSTBLT_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_PATBLT_INDEX: FALSE  
-        (byte)0x00, // TS_NEG_SCRBLT_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_MEMBLT_INDEX: FALSE  
-        (byte)0x00, // TS_NEG_MEM3BLT_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_ATEXTOUT_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_AEXTTEXTOUT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_DRAWNINEGRID_INDEX: FALSE
-        (byte)0x00, // TS_NEG_LINETO_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MULTI_DRAWNINEGRID_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_OPAQUERECT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_SAVEBITMAP_INDEX: FALSE
-        (byte)0x00, // TS_NEG_WTEXTOUT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MEMBLT_R2_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MEM3BLT_R2_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MULTIDSTBLT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MULTIPATBLT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MULTISCRBLT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MULTIOPAQUERECT_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_FAST_INDEX_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_POLYGON_SC_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_POLYGON_CB_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_POLYLINE_INDEX: TRUE 
-        (byte)0x00, // Unused: 0 
-        (byte)0x00, // TS_NEG_FAST_GLYPH_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_ELLIPSE_SC_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_ELLIPSE_CB_INDEX: FALSE
-        (byte)0x00, // TS_NEG_INDEX_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_WEXTTEXTOUT_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_WLONGTEXTOUT_INDEX: FALSE 
-        (byte)0x00, // TS_NEG_WLONGEXTTEXTOUT_INDEX: FALSE
-        (byte)0x00, // Unused: 0 
-        (byte)0x00, (byte)0x00, // Text flags (ignored): 0  (LE)
-        (byte)0x00, (byte)0x00, // Order support extra flags: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 4 bytes
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Desktop save size (ignored): 0 (assumed to be 230400 bytes (480*480, 0x38400, LE))  
-        (byte)0x00, (byte)0x00, // Padding 2 bytes 
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-        (byte)0xe4, (byte)0x04, // Text ANSI Code Page: 1252,  ANSI - Latin I (0x04e4, LE) 
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-        
-        //
-        // Bitmap Cache Rev. 2 Capability Set (40 bytes), see http://msdn.microsoft.com/en-us/library/cc240560.aspx
-        (byte)0x13, (byte)0x00, // capability set type: CAPSTYPE_BITMAPCACHE_REV2 (19) (LE) 
-        (byte)0x28, (byte)0x00, // length of capability set: 40 bytes (LE)
-        (byte)0x00, (byte)0x00, // Cache flags: 0 (LE) 
-        (byte)0x00, // Padding 1 byte 
-        (byte)0x00, // Number of cell caches: 0 
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache0 cell info: 0 (LE) 
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache1 cell info: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache2 cell info: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache3 cell info: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache4 cell info: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 12 bytes 
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
-        
-        //
-        // Color Table Cache Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc241564.aspx
-        (byte)0x0a, (byte)0x00, // capability set type: CAPSTYPE_COLORCACHE (10) (LE)
-        (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
-        (byte)0x06, (byte)0x00, // Color table cache size (must be ignored during capability exchange and is assumed to be 0x0006): 6 (LE)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-        
-        //
-        // Window Activation Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240569.aspx
-        (byte)0x07, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION (7) (LE) 
-        (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
-        (byte)0x00, (byte)0x00, // helpKeyFlag (should be set to FALSE (0)): FALSE (0, LE)
-        (byte)0x00, (byte)0x00, // helpKeyIndexFlag (should be set to FALSE (0)): FALSE (0, LE)
-        (byte)0x00, (byte)0x00, // helpExtendedKeyFlag (should be set to FALSE (0)): FALSE (0, LE)
-        (byte)0x00, (byte)0x00, // windowManagerKeyFlag (should be set to FALSE (0)): FALSE (0, LE)
-        
-        //
-        // Control Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240568.aspx
-        (byte)0x05, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION (7)
-        (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
-        (byte)0x00, (byte)0x00, // controlFlags (should be set to 0): 0 (LE)
-        (byte)0x00, (byte)0x00, // remoteDetachFlag (should be set to 0): 0 (LE)
-        (byte)0x02, (byte)0x00, // controlInterest (should be set to CONTROLPRIORITY_NEVER): CONTROLPRIORITY_NEVER (2) (LE)
-        (byte)0x02, (byte)0x00, // detachInterest (should be set to CONTROLPRIORITY_NEVER): CONTROLPRIORITY_NEVER (2) (LE)
-        
-        //
-        // Pointer Capability Set (10 bytes), see http://msdn.microsoft.com/en-us/library/cc240562.aspx
-        (byte)0x08, (byte)0x00, // capability set type: CAPSTYPE_POINTER (8, LE)
-        (byte)0x0a, (byte)0x00, // length of capability set: 10 bytes (LE)
-        (byte)0x00, (byte)0x00, // colorPointerFlag: FALSE (LE)
-        (byte)0x00, (byte)0x00, // colorPointerCacheSize: 0 (LE)
-        (byte)0x14, (byte)0x00, // pointerCacheSize: 20 (LE)
-        
-        //
-        // Share Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240570.aspx
-        (byte)0x09, (byte)0x00, // capability set type: CAPSTYPE_SHARE (9, LE)
-        (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
-        (byte)0x00, (byte)0x00, // nodeID (must be set to 0 by client): 0 (LE)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes (LE)
-        
-        //
-        // Input Capability Set (88 bytes), see http://msdn.microsoft.com/en-us/library/cc240563.aspx
-        (byte)0x0d, (byte)0x00, // capability set type:  CAPSTYPE_INPUT (13, LE)
-        (byte)0x58, (byte)0x00, // length of capability set: 88 bytes (LE)
-        (byte)0x35, (byte)0x00, // inputFlags: 0x0035  (LE),  INPUT_FLAG_FASTPATH_INPUT2 (0x20), INPUT_FLAG_VKPACKET (0x10), INPUT_FLAG_MOUSEX (0x4), INPUT_FLAG_SCANCODES (0x1)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes 
-        (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, // keyboardLayout: "US" keyboard layout (0x000409, LE) 
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardType: unknown (LE) 
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardSubType: unknown (LE) 
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardFunctionKey: unknown (LE)
-        // imeFileName: "", (64 bytes, including trailing NULL characters, UCS2) 
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        
-        //
-        // Brush Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240564.aspx
-        (byte)0x0f, (byte)0x00, // capability set type: CAPSTYPE_BRUSH (15, LE)
-        (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // brushSupportLevel: BRUSH_DEFAULT (0x0, LE)
-        
-        //
-        // Sound Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240552.aspx
-        (byte)0x0c, (byte)0x00, // capability set type: CAPSTYPE_SOUND (12, LE)
-        (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // soundFlags: 0x0000 (LE) // SOUND_FLAG_BEEPS (0x1)   
-        
-        //
-        // Font Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240571.aspx
-        (byte)0x0e, (byte)0x00, 
-        (byte)0x08, (byte)0x00, 
-        (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 
-        
-        //
-        // Offscreen Bitmap Cache Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240550.aspx
-        (byte)0x11, (byte)0x00, // capability set type: CAPSTYPE_OFFSCREENCACHE (17, LE)
-        (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // offscreenSupportLevel: FALSE (LE) 
-        (byte)0x00, (byte)0x00, // offscreenCacheSize: 0 (LE)
-        (byte)0x00, (byte)0x00, // offscreenCacheEntries: 0 (LE)
-        
-        //
-        // Glyph Cache Capability Set (52 bytes), see http://msdn.microsoft.com/en-us/library/cc240565.aspx
-        (byte)0x10, (byte)0x00, // capability set type: CAPSTYPE_OFFSCREENCACHE (16, LE)
-        (byte)0x34, (byte)0x00, // length of capability set: 52 bytes (LE)
-        // Glyph Cache (40 bytes)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) 
-        (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x10, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x20, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x40, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x80, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 4 (LE)
-        (byte)0x40, (byte)0x00, // CacheEntries: 64 (LE)
-        (byte)0x00, (byte)0x08, // CacheMaximumCellSize: 2048 (LE)
-        // FragCache
-        (byte)0x00, (byte)0x01, // CacheEntries: 256 (LE)
-        (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 256 (LE)
-        // 
-        (byte)0x00, (byte)0x00, // GlyphSupportLevel: GLYPH_SUPPORT_NONE (0x0, LE)  
-        (byte)0x00, (byte)0x00, // Padding 2 bytes   
-    };
-    /* @formatter:on */
-
-    RdpState rdpState = new RdpState();
-    ScreenDescription screenDescription = new ScreenDescription();
-    screenDescription.setFramebufferSize(1024, 768);
-    
-    rdpState.serverShareId = 0x000103ea;
-
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {}));
-    Element confirm_active = new ClientConfirmActivePDU("confirm_active", screenDescription, rdpState);
-    Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, confirm_active, sink);
-    pipeline.link("source", "confirm_active", "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientFastPathPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientFastPathPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientFastPathPDU.java
deleted file mode 100644
index 4c7dcfc..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientFastPathPDU.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240589.aspx
- */
-public class ClientFastPathPDU extends BaseElement {
-
-  public ClientFastPathPDU(String id) {
-    super(id);
-  }
-
-  @Override
-  public void handleData(ByteBuffer buf, Link link) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-    if (buf.length > 32767-3)
-      throw new RuntimeException("Packet is too long: " + buf + ".");
-
-    ByteBuffer data = new ByteBuffer(6);
-
-    // FastPath, 1 event, no checksum, not encrypted
-    data.writeByte(0x4);
-
-    // Length of full packet, including length field, in network order.
-    // Topmost bit of first byte indicates that field has 2 bytes
-    data.writeShort((1 + 2 + buf.length) | 0x8000);
-    data.trimAtCursor();
-
-    buf.prepend(data);
-
-    pushDataToAllOuts(buf);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientInfoPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientInfoPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientInfoPDU.java
deleted file mode 100644
index f5efc2c..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientInfoPDU.java
+++ /dev/null
@@ -1,456 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240475.aspx
- */
-public class ClientInfoPDU extends OneTimeSwitch {
-
-  public static final int INFO_MOUSE = 0x1;
-  public static final int INFO_DISABLECTRLALTDEL = 0x2;
-  public static final int INFO_UNICODE = 0x10;
-
-  public static final int INFO_MAXIMIZESHELL = 0x20;
-  public static final int INFO_LOGONNOTIFY = 0x40;
-  public static final int INFO_ENABLEWINDOWSKEY = 0x100;
-  public static final int INFO_MOUSE_HAS_WHEEL = 0x00020000;
-  public static final int INFO_NOAUDIOPLAYBACK = 0x00080000;
-
-  public static final int PERF_DISABLE_WALLPAPER = 0x1;
-  public static final int PERF_DISABLE_FULLWINDOWDRAG = 0x2;
-  public static final int PERF_DISABLE_MENUANIMATIONS = 0x4;
-
-  protected byte[] userName = "".getBytes(RdpConstants.CHARSET_16);
-  protected byte[] password = "".getBytes(RdpConstants.CHARSET_16); // No effect
-  protected byte[] alternateShell = "".getBytes(RdpConstants.CHARSET_16);
-  protected byte[] domain = "".getBytes(RdpConstants.CHARSET_16);
-  protected byte[] workingDir = "".getBytes(RdpConstants.CHARSET_16);
-  protected byte[] clientAddress = "192.168.0.100".getBytes(RdpConstants.CHARSET_16);
-  protected byte[] clientDir = "C:\\Windows\\System32\\mstscax.dll".getBytes(RdpConstants.CHARSET_16);
-
-  protected String standardTimeZoneName = "EET, Standard Time";
-  protected String daylightTimeZoneName = "EET, Summer Time";
-  protected int standardTimeZoneBias = 0; /* in minutes */
-  protected int daylightTimeZoneBias = 60; /* in minutes */
-
-  public ClientInfoPDU(String id, String userName) {
-    super(id);
-    this.userName = userName.getBytes(RdpConstants.CHARSET_16);
-  }
-
-  @Override
-  protected void handleOneTimeData(ByteBuffer buf, Link link) {
-    if (buf == null)
-      return;
-
-    throw new RuntimeException("Unexpected packet: " + buf + ".");
-  }
-
-  @Override
-  protected void onStart() {
-    super.onStart();
-
-    // Length of packet
-    ByteBuffer buf = new ByteBuffer(1024, true);
-
-    // MCS Send Data Request PDU 
-    buf.writeByte(0x64);
-    
-    // Initiator: 0x03 + 1001 = 1004
-    buf.writeShort(3); 
-    
-    // Channel ID: 1003
-    buf.writeShort(1003);
-    
-    // Data priority: high, segmentation: begin | end (0x40 | 0x20 | 0x10 = 0x70)
-    buf.writeByte(0x70);
-    
-    // User data length: (variable length field)
-    int length=224+userName.length + password.length+alternateShell.length+domain.length+workingDir.length+clientAddress.length+clientDir.length;
-    buf.writeShort(length | 0x8000);
-    
-    // Flags: SEC_INFO_PKT (0x4000)
-    buf.writeShort(0x4000);
-     
-    // TS_SECURITY_HEADER::flagsHi - ignored
-    buf.writeShort(0x0000); 
-
-    // Codepage: 0 (UNKNOWN, LE) (use  0x04090409  (1033,1033) for EN_US)  
-    buf.writeIntLE(0x0000);
-     
-    // Flags
-    buf.writeIntLE(INFO_MOUSE | INFO_DISABLECTRLALTDEL | INFO_UNICODE |  
-    INFO_MAXIMIZESHELL | INFO_LOGONNOTIFY  |  INFO_ENABLEWINDOWSKEY |
-    INFO_MOUSE_HAS_WHEEL | INFO_NOAUDIOPLAYBACK );
-    
-    //
-    // Lengths
-    //
-        
-    // cbDomain length: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
-    buf.writeShortLE(domain.length); 
-    
-    // cbUserName length: 16 bytes (0x10, LE) (NOT including size of mandatory NULL terminator)
-    buf.writeShortLE(userName.length);
-     
-    // cbPassword length: (LE) (NOT including size of mandatory NULL terminator)
-    buf.writeShortLE(password.length);
-    
-    // cbAlternateShell:  (LE) (NOT including size of mandatory NULL terminator)
-    buf.writeShortLE(alternateShell.length);
-    
-    // cbWorkingDir: (LE) (NOT including size of mandatory NULL terminator)
-    buf.writeShortLE(workingDir.length);
-    
-    //
-    // Values
-    //
-        
-    // Domain: (UCS2), see cbDomain
-    buf.writeBytes(domain);
-    buf.writeShort(0);
-    
-    // User name: (UCS2), see cbUserName
-    buf.writeBytes(userName);
-    buf.writeShort(0);
-    
-    // Password: (UCS2), see cbPassword
-    buf.writeBytes(password);
-    buf.writeShort(0);
-    
-    // Alternate shell: (UCS2), see cbAlternateShell
-    buf.writeBytes(alternateShell);
-    buf.writeShort(0);
-    
-    // Working directory: (UCS2), see cbWorkingDir
-    buf.writeBytes(workingDir);
-    buf.writeShort(0);
-    
-    // Client address family: 2 (AF_INET, LE)
-    buf.writeShortLE(2);
-    
-    // cbClientAddress: ( LE) (including the size of the mandatory NULL terminator)
-    buf.writeShortLE(clientAddress.length+2);
-    
-    // Client address: (UCS2) 
-    buf.writeBytes(clientAddress);
-    buf.writeShort(0);
-    
-    // cbClientDir: 64 bytes (0x40, LE) (including the size of the mandatory NULL terminator)
-    buf.writeShortLE(clientDir.length+2);
-    
-    // Client directory: (UCS2)
-    buf.writeBytes(clientDir);
-    buf.writeShort(0);
-    
-    //
-    // Client time zone:
-    //
-    
-    // Bias: 0 minutes (LE)
-    buf.writeIntLE(0); 
-    
-    // Standard name: "EET, Standard Time" (fixed string: 64 bytes, UCS2)
-    buf.writeFixedString(62, standardTimeZoneName, RdpConstants.CHARSET_16);
-    buf.writeShort(0);
-    
-    // Standard date
-    buf.writeBytes(new byte[] { 
-        // wYear: 0 (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wMonth: unknown (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wDayOfWeek: Sunday (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wDay: unknown (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wHour: 0 (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wMinute: 0 (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wSecond: 0 (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wMilliseconds: 0
-        (byte) 0x00, (byte) 0x00,
-        
-    });
-    
-    // StandardBias: 0 minutes (LE)
-    buf.writeIntLE(standardTimeZoneBias); 
-    
-    // Daylight name: "EET, Summer Time" (fixed string: 64 bytes, UCS2)
-    buf.writeFixedString(62, daylightTimeZoneName, RdpConstants.CHARSET_16);
-    buf.writeShort(0);
-    
-    // Daylight date
-    buf.writeBytes(new byte[] { 
-        // wYear: 0 (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wMonth: unknown (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wDayOfWeek: Sunday (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wDay: unknown (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wHour: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wMinute: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wSecond: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wMilliseconds: 0
-        (byte) 0x00, (byte) 0x00,
-        
-    });
-    
-    // Daylight bias: 60 minutes (LE)
-    buf.writeIntLE(daylightTimeZoneBias);
-     
-    // Client session ID: 0x00000000 (LE)
-    buf.writeIntLE(0);
-    
-    // Performance flags: 0x7 (LE) = PERF_DISABLE_WALLPAPER (0x1), PERF_DISABLE_FULLWINDOWDRAG (0x2), PERF_DISABLE_MENUANIMATIONS (0x4)
-    buf.writeIntLE(PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS);
-    
-    // cbAutoReconnectCookie: 0 bytes (LE)
-    buf.writeShortLE(0);
-
-    // Trim buffer to actual length of data written
-    buf.length = buf.cursor;
-
-    pushDataToOTOut(buf);
-
-    switchOff();
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-    // System.setProperty("streamer.Link.debug", "true");
-    System.setProperty("streamer.Element.debug", "true");
-    // System.setProperty("streamer.Pipeline.debug", "true");
-
-    /* @formatter:off */
-    byte[] packet = new byte[] {
-        
-        // TPKT
-        (byte) 0x03, (byte) 0x00,
-
-        // TPKT length: 343 bytes
-        (byte) 0x01, (byte) 0x57,
-        
-        // X224 Data PDU
-        (byte) 0x02, (byte) 0xf0, (byte) 0x80,
-        
-        
-        // MCS Send Data Request PDU 
-        (byte) 0x64, 
-        
-        // Initiator: 0x03 + 1001 = 1004
-        (byte) 0x00, (byte) 0x03,
-        
-        // Channel ID: 1003 (IO Channel)
-        (byte) 0x03, (byte) 0xeb,
-        
-        // Data priority: high, segmentation: begin | end (0x40 | 0x20 | 0x10 = 0x70)
-        (byte) 0x70, 
-        
-        // User data length: 328  (0x148) bytes, variable length field 
-        (byte) 0x81, (byte) 0x48, 
-        
-        // Flags: SEC_INFO_PKT (0x4000)
-        (byte) 0x40, (byte) 0x00, 
-
-        // TS_SECURITY_HEADER::flagsHi - ignored
-        (byte) 0x00, (byte) 0x00,
-        
-        // Codepage: 0 (UNKNOWN, LE) (use  0x04090409  (1033,1033) for EN_US)  
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
-        
-        // Flags: 0xa0173 (LE), INFO_MOUSE (0x1), INFO_DISABLECTRLALTDEL (0x2), INFO_UNICODE (0x10), 
-        // INFO_MAXIMIZESHELL (0x20), INFO_LOGONNOTIFY (0x40), INFO_ENABLEWINDOWSKEY (0x100),
-        // INFO_MOUSE_HAS_WHEEL (0x00020000), INFO_NOAUDIOPLAYBACK (0x00080000), 
-        (byte) 0x73, (byte) 0x01, (byte) 0x0a, (byte) 0x00, 
-        
-        // Lengths
-        
-        // cbDomain length: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
-        (byte) 0x00, (byte) 0x00, 
-        
-        // cbUserName length: 16 bytes (0x10, LE) (NOT including size of mandatory NULL terminator)
-        (byte) 0x10, (byte) 0x00,
-        
-        // cbPassword length: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
-        (byte) 0x00, (byte) 0x00,
-        
-        // cbAlternateShell:  0 bytes (LE) (NOT including size of mandatory NULL terminator)
-        (byte) 0x00, (byte) 0x00, 
-        
-        // cbWorkingDir: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
-        (byte) 0x00, (byte) 0x00,
-        
-        // Values
-        
-        // Domain: "" (UCS2), see cbDomain
-        (byte) 0x00, (byte) 0x00, 
-        
-        // User name: "vlisivka" (UCS2), see cbUserName
-        (byte) 0x76, (byte) 0x00, (byte) 0x6c, (byte) 0x00, (byte) 0x69, (byte) 0x00, (byte) 0x73, (byte) 0x00, 
-        (byte) 0x69, (byte) 0x00, (byte) 0x76, (byte) 0x00, (byte) 0x6b, (byte) 0x00, (byte) 0x61, (byte) 0x00, 
-        (byte) 0x00, (byte) 0x00, 
-        
-        // Password: "" (UCS2), see cbPassword
-        (byte) 0x00, (byte) 0x00, 
-        
-        // Alternate shell: "" (UCS2), see cbAlternateShell
-        (byte) 0x00, (byte) 0x00, 
-        
-        // Working directory: "" (UCS2), see cbWorkingDir
-        (byte) 0x00, (byte) 0x00, 
-        
-        // Client address family: 2 (AF_INET, LE)
-        (byte) 0x02, (byte) 0x00, 
-        
-        // cbClientAddress = 28 bytes (0x1c, LE) (including the size of the mandatory NULL terminator)
-        (byte) 0x1c, (byte) 0x00, 
-        
-        // Client address: "192.168.0.100" (UCS2) 
-        (byte) 0x31, (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x32, (byte) 0x00, (byte) 0x2e, (byte) 0x00,
-        (byte) 0x31, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x38, (byte) 0x00, (byte) 0x2e, (byte) 0x00,
-        (byte) 0x30, (byte) 0x00, (byte) 0x2e, (byte) 0x00, (byte) 0x31, (byte) 0x00, (byte) 0x30, (byte) 0x00, 
-        (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        
-        // cbClientDir: 64 bytes (0x40, LE) (including the size of the mandatory NULL terminator)
-        (byte) 0x40, (byte) 0x00,
-        
-        // Client directory: "C:\Windows\System32\mstscax.dll" (UCS2)
-        (byte) 0x43, (byte) 0x00, (byte) 0x3a, (byte) 0x00, (byte) 0x5c, (byte) 0x00, (byte) 0x57, (byte) 0x00, 
-        (byte) 0x69, (byte) 0x00, (byte) 0x6e, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x6f, (byte) 0x00, 
-        (byte) 0x77, (byte) 0x00, (byte) 0x73, (byte) 0x00, (byte) 0x5c, (byte) 0x00, (byte) 0x53, (byte) 0x00, 
-        (byte) 0x79, (byte) 0x00, (byte) 0x73, (byte) 0x00, (byte) 0x74, (byte) 0x00, (byte) 0x65, (byte) 0x00, 
-        (byte) 0x6d, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x32, (byte) 0x00, (byte) 0x5c, (byte) 0x00, 
-        (byte) 0x6d, (byte) 0x00, (byte) 0x73, (byte) 0x00, (byte) 0x74, (byte) 0x00, (byte) 0x73, (byte) 0x00, 
-        (byte) 0x63, (byte) 0x00, (byte) 0x61, (byte) 0x00, (byte) 0x78, (byte) 0x00, (byte) 0x2e, (byte) 0x00, 
-        (byte) 0x64, (byte) 0x00, (byte) 0x6c, (byte) 0x00, (byte) 0x6c, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        
-        //
-        // Client time zone:
-        
-        // Bias: 0 minutes (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        
-        // Standard name: "EET, Standard Time" (fixed string: 64 bytes, UCS2)
-        (byte) 0x45, (byte) 0x00, (byte) 0x45, (byte) 0x00, (byte) 0x54, (byte) 0x00, (byte) 0x2c, (byte) 0x00, 
-        (byte) 0x20, (byte) 0x00, (byte) 0x53, (byte) 0x00, (byte) 0x74, (byte) 0x00, (byte) 0x61, (byte) 0x00, 
-        (byte) 0x6e, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x61, (byte) 0x00, (byte) 0x72, (byte) 0x00, 
-        (byte) 0x64, (byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x54, (byte) 0x00, (byte) 0x69, (byte) 0x00, 
-        (byte) 0x6d, (byte) 0x00, (byte) 0x65, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        
-        //
-        // Standard date
-        // wYear: 0 (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wMonth: unknown (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wDayOfWeek: Sunday (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wDay: unknown (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wHour: 0 (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wMinute: 0 (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wSecond: 0 (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wMilliseconds: 0
-        (byte) 0x00, (byte) 0x00,
-        
-        // StandardBias: 0 minutes (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
-        
-        // Daylight name: "EET, Summer Time" (fixed string: 64 bytes, UCS2)
-        (byte) 0x45, (byte) 0x00, (byte) 0x45, (byte) 0x00, (byte) 0x54, (byte) 0x00, (byte) 0x2c, (byte) 0x00, 
-        (byte) 0x20, (byte) 0x00, (byte) 0x53, (byte) 0x00, (byte) 0x75, (byte) 0x00, (byte) 0x6d, (byte) 0x00, 
-        (byte) 0x6d, (byte) 0x00, (byte) 0x65, (byte) 0x00, (byte) 0x72, (byte) 0x00, (byte) 0x20, (byte) 0x00, 
-        (byte) 0x54, (byte) 0x00, (byte) 0x69, (byte) 0x00, (byte) 0x6d, (byte) 0x00, (byte) 0x65, (byte) 0x00, 
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
-        
-        // Daylight date
-        // wYear: 0 (LE)
-        (byte) 0x00, (byte) 0x00, 
-        // wMonth: unknown (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wDayOfWeek: Sunday (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wDay: unknown (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wHour: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wMinute: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wSecond: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wMilliseconds: 0
-        (byte) 0x00, (byte) 0x00,
-        
-        // Daylight bias: 60 minutes (LE)
-        (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        
-        
-        // Client session ID: 0x00000000 (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
-        
-        // Performance flags: 0x7 (LE) = PERF_DISABLE_WALLPAPER (0x1), PERF_DISABLE_FULLWINDOWDRAG (0x2), PERF_DISABLE_MENUANIMATIONS (0x4)
-        (byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
-        
-        // cbAutoReconnectCookie: 0 bytes (LE)
-        (byte) 0x00, (byte) 0x00, 
-    };
-    /* @formatter:on */
-
-    MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-    Element todo = new ClientInfoPDU("client_info", "vlisivka");
-    Element x224 = new ClientX224DataPdu("x224");
-    Element tpkt = new ClientTpkt("tpkt");
-    Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-    Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] { 1, 2, 3 }));
-
-    Pipeline pipeline = new PipelineImpl("test");
-    pipeline.add(source, todo, x224, tpkt, sink, mainSink);
-    pipeline.link("source", "client_info", "mainSink");
-    pipeline.link("client_info >" + OTOUT, "x224", "tpkt", "sink");
-    pipeline.runMainLoop("source", STDOUT, false, false);
-  }
-
-}


[04/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SyncLink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SyncLink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SyncLink.java
old mode 100644
new mode 100755
index 32c14bb..696402a
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SyncLink.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SyncLink.java
@@ -22,381 +22,393 @@ package streamer;
  */
 public class SyncLink implements Link {
 
-  /**
-   * When null packet is pulled from source element, then make slight delay to
-   * avoid consuming of 100% of CPU in main loop in cases when link is pauses or
-   * source element cannot produce data right now.
-   */
-  protected static final long STANDARD_DELAY_FOR_EMPTY_PACKET = 10; // Milliseconds
-
-  /**
-   * Delay for null packets in poll method when blocking is requested, in
-   * milliseconds.
-   */
-  protected long delay = STANDARD_DELAY_FOR_EMPTY_PACKET;
-
-  /**
-   * Set to true to print debugging messages.
-   */
-  protected boolean verbose = System.getProperty("streamer.Link.debug", "false").equals("true");;
-
-  /**
-   * ID of this link.
-   */
-  protected String id = null;
-
-  /**
-   * Buffer with data to hold because link is paused, or data is pushed back.
-   */
-  protected ByteBuffer cacheBuffer = null;
-
-  /**
-   * Size of expected packet. Data must be hold in link until full packet will
-   * be read.
-   */
-  protected int expectedPacketSize = 0;
-
-  /**
-   * Number of packets and packet header transferred to element.
-   */
-  protected int packetNumber = 0;
-
-  /**
-   * Set to true to hold all data in link until it will be set to false again.
-   */
-  protected boolean paused = false;
-
-  /**
-   * Element to pull data from, when in pull mode.
-   */
-  protected Element source = null;
-
-  /**
-   * Element to send data to in both pull and push modes.
-   */
-  protected Element sink = null;
-
-  /**
-   * When in loop, indicates that loop must be stopped.
-   * 
-   * @see run()
-   */
-  private boolean shutdown = false;
-
-  /**
-   * Indicates that event STREAM_START is passed over this link, so main loop
-   * can be started to pull data from source element.
-   */
-  protected boolean start;
-
-  /**
-   * Operate in pull mode.
-   */
-  protected boolean pullMode;
-
-  public SyncLink() {
-  }
-
-  public SyncLink(String id) {
-    this.id = id;
-  }
-
-  @Override
-  public void pushBack(ByteBuffer buf) {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Buffer pushed back: " + buf + ".");
-
-    if (cacheBuffer != null) {
-      ByteBuffer tmp = cacheBuffer.join(buf);
-      cacheBuffer.unref();
-      cacheBuffer = tmp;
-    } else {
-      cacheBuffer = buf;
-      cacheBuffer.ref();
+    /**
+     * When null packet is pulled from source element, then make slight delay to
+     * avoid consuming of 100% of CPU in main loop in cases when link is pauses or
+     * source element cannot produce data right now.
+     */
+    public static final long STANDARD_DELAY_FOR_EMPTY_PACKET = 10; // Milliseconds
+
+    /**
+     * Delay for null packets in poll method when blocking is requested, in
+     * milliseconds.
+     */
+    protected long delay = STANDARD_DELAY_FOR_EMPTY_PACKET;
+
+    /**
+     * Set to true to print debugging messages.
+     */
+    protected boolean verbose = System.getProperty("streamer.Link.debug", "false").equals("true");;
+
+    /**
+     * ID of this link.
+     */
+    protected String id = null;
+
+    /**
+     * Buffer with data to hold because link is paused, on hold, or data is pushed
+     * back from output element.
+     */
+    protected ByteBuffer cacheBuffer = null;
+
+    /**
+     * Size of expected packet. Data must be hold in link until full packet will
+     * be read.
+     */
+    protected int expectedPacketSize = 0;
+
+    /**
+     * Number of packets and packet header transferred to element.
+     */
+    protected int packetNumber = 0;
+
+    /**
+     * Element to pull data from, when in pull mode.
+     */
+    protected Element source = null;
+
+    /**
+     * Element to send data to in both pull and push modes.
+     */
+    protected Element sink = null;
+
+    /**
+     * When in loop, indicates that loop must be stopped.
+     * 
+     * @see run()
+     */
+    private boolean shutdown = false;
+
+    /**
+     * Indicates that event STREAM_START is passed over this link, so main loop
+     * can be started to pull data from source element.
+     */
+    protected boolean started = false;
+
+    /**
+     * Set to true to hold all data in link until it will be set to false again.
+     */
+    protected boolean paused = false;
+
+    /**
+     * Used by pull() method to hold all data in this link to avoid recursion when
+     * source element is asked to push new data to it outputs.
+     */
+    protected boolean hold = false;
+
+    /**
+     * Operate in pull mode instead of default push mode. In pull mode, link will
+     * ask it source element for new data.
+     */
+    protected boolean pullMode = false;
+
+    public SyncLink() {
     }
 
-    resetCursor();
-  }
-
-  private void resetCursor() {
-    // Reset cursor
-    cacheBuffer.cursor = 0;
-  }
-
-  @Override
-  public void pushBack(ByteBuffer buf, int lengthOfFullPacket) {
-    pushBack(buf);
-    expectedPacketSize = lengthOfFullPacket;
-  }
-
-  @Override
-  public String toString() {
-    return "SyncLink(" + ((id != null) ? id + ", " : "") + source + ":" + sink + ")";
-  }
-
-  /**
-   * Push data to sink. Call with null to push cached data.
-   */
-  @Override
-  public void sendData(ByteBuffer buf) {
-    if (!paused && pullMode)
-      throw new RuntimeException("[" + this + "] ERROR: link is not in push mode.");
-
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Incoming buffer: " + buf + ".");
-
-    if (buf == null && cacheBuffer == null)
-      return;
-
-    if (cacheBuffer != null && buf != null) {
-      // Join old data with fresh data
-      buf = cacheBuffer.join(buf);
-      cacheBuffer.unref();
-      cacheBuffer = buf;
+    public SyncLink(String id) {
+        this.id = id;
     }
 
-    // Store buffer in cache field to simplify following loop
-    if (buf != null)
-      cacheBuffer = buf;
-
-    // When data pushed back and length of data is less than length of full
-    // packet, then feed data to sink element immediately
-    while (cacheBuffer != null) {
-      if (paused) {
+    @Override
+    public void pushBack(ByteBuffer buf) {
         if (verbose)
-          System.out.println("[" + this + "] INFO: Transfer is paused. Data in cache buffer: " + cacheBuffer + ".");
+            System.out.println("[" + this + "] INFO: Buffer pushed back: " + buf + ".");
+
+        if (cacheBuffer != null) {
+            ByteBuffer tmp = cacheBuffer.join(buf);
+            cacheBuffer.unref();
+            cacheBuffer = tmp;
+        } else {
+            cacheBuffer = buf;
+            cacheBuffer.ref();
+        }
+
+        resetCursor();
+    }
+
+    private void resetCursor() {
+        // Reset cursor
+        cacheBuffer.cursor = 0;
+    }
 
-        // Wait until rest of packet will be read
-        return;
-      }
+    @Override
+    public void pushBack(ByteBuffer buf, int lengthOfFullPacket) {
+        pushBack(buf);
+        expectedPacketSize = lengthOfFullPacket;
+    }
+
+    @Override
+    public String toString() {
+        return "SyncLink(" + ((id != null) ? id + ", " : "") + source + ":" + sink + ")";
+    }
+
+    /**
+     * Push data to sink. Call with null to push cached data.
+     */
+    @Override
+    public void sendData(ByteBuffer buf) {
+        if (!hold && pullMode)
+            throw new RuntimeException("[" + this + "] ERROR: link is not in push mode.");
 
-      if (expectedPacketSize > 0 && cacheBuffer.length < expectedPacketSize) {
         if (verbose)
-          System.out.println("[" + this + "] INFO: Transfer is suspended because available data is less than expected packet size. Expected packet size: "
-              + expectedPacketSize + ", data in cache buffer: " + cacheBuffer + ".");
+            System.out.println("[" + this + "] INFO: Incoming buffer: " + buf + ".");
 
-        // Wait until rest of packet will be read
-        return;
-      }
+        if (buf == null && cacheBuffer == null)
+            return;
 
-      // Full packet or packet header is read, feed it to element
-      buf = cacheBuffer;
-      cacheBuffer = null;
-      expectedPacketSize = 0;
-      packetNumber++;
+        if (cacheBuffer != null && buf != null) {
+            // Join old data with fresh data
+            buf = cacheBuffer.join(buf);
+            cacheBuffer.unref();
+            cacheBuffer = buf;
+        }
 
-      if (sink == null)
-        throw new NullPointerException("[" + this + "] ERROR: Cannot send data to sink: sink is null. Data: " + buf + ".");
+        // Store buffer in cache field to simplify following loop
+        if (buf != null)
+            cacheBuffer = buf;
+
+        // When data pushed back and length of data is less than length of full
+        // packet, then feed data to sink element immediately
+        while (cacheBuffer != null) {
+            if (paused || hold) {
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: Transfer is paused. Data in cache buffer: " + cacheBuffer + ".");
+
+                // Wait until rest of packet will be read
+                return;
+            }
+
+            if (expectedPacketSize > 0 && cacheBuffer.length < expectedPacketSize) {
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: Transfer is suspended because available data is less than expected packet size. Expected packet size: "
+                            + expectedPacketSize + ", data in cache buffer: " + cacheBuffer + ".");
+
+                // Wait until rest of packet will be read
+                return;
+            }
+
+            // Full packet or packet header is read, feed it to element
+            buf = cacheBuffer;
+            cacheBuffer = null;
+            expectedPacketSize = 0;
+            packetNumber++;
+
+            if (sink == null)
+                throw new NullPointerException("[" + this + "] ERROR: Cannot send data to sink: sink is null. Data: " + buf + ".");
+
+            sink.handleData(buf, this);
+            // cacheBuffer and expectedPacketSize can be changed at this time
+        }
 
-      sink.handleData(buf, this);
-      // cacheBuffer and expectedPacketSize can be changed at this time
     }
 
-  }
+    @SuppressWarnings("incomplete-switch")
+    @Override
+    public void sendEvent(Event event, Direction direction) {
 
-  @SuppressWarnings("incomplete-switch")
-  @Override
-  public void sendEvent(Event event, Direction direction) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Event " + event + " is received.");
+
+        // Shutdown main loop (if any) when STREAM_CLOSE event is received.
+        switch (event) {
+        case STREAM_START: {
+            if (!started)
+                started = true;
+            else
+                // Event already sent trough this link
+                return;
+            break;
+        }
+        case STREAM_CLOSE: {
+            if (!shutdown)
+                shutdown = true;
+            else
+                // Event already sent trough this link
+                return;
+            break;
+        }
+        case LINK_SWITCH_TO_PULL_MODE: {
+            setPullMode();
+            break;
+        }
 
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Event " + event + " is received.");
+        }
 
-    // Shutdown main loop (if any) when STREAM_CLOSE event is received.
-    switch (event) {
-    case STREAM_START: {
-      if (!start)
-        start = true;
-      else
-        // Event already sent trough this link
-        return;
-      break;
-    }
-    case STREAM_CLOSE: {
-      if (!shutdown)
-        shutdown = true;
-      else
-        // Event already sent trough this link
-        return;
-      break;
-    }
-    case LINK_SWITCH_TO_PULL_MODE: {
-      setPullMode();
-      break;
+        switch (direction) {
+        case IN:
+            source.handleEvent(event, direction);
+            break;
+        case OUT:
+            sink.handleEvent(event, direction);
+            break;
+        }
     }
 
-    }
+    @Override
+    public ByteBuffer pull(boolean block) {
+        if (!pullMode)
+            throw new RuntimeException("[" + this + "] ERROR: This link is not in pull mode.");
+
+        if (hold)
+            throw new RuntimeException("[" + this + "] ERROR: This link is already on hold, waiting for data to be pulled in. Circular reference?");
+
+        if (paused) {
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Cannot pull, link is paused.");
+
+            // Make slight delay in such case, to avoid consuming 100% of CPU
+            if (block) {
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                }
+            }
+            return null;
+        }
+        // If data in cache can be sent immediately,
+        // then return it instead of asking for more data from source
+        if (cacheBuffer != null && (expectedPacketSize == 0 || (expectedPacketSize > 0 && cacheBuffer.length >= expectedPacketSize))) {
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Data pulled from cache buffer: " + cacheBuffer + ".");
+
+            ByteBuffer tmp = cacheBuffer;
+            cacheBuffer = null;
+            return tmp;
+        }
 
-    switch (direction) {
-    case IN:
-      source.handleEvent(event, direction);
-      break;
-    case OUT:
-      sink.handleEvent(event, direction);
-      break;
+        // Pause this link, so incoming data will not be sent to sink
+        // immediately, then ask source element for more data
+        try {
+            hold = true;
+            source.poll(block);
+        } finally {
+            hold = false;
+        }
+
+        // Can return something only when data was stored in buffer
+        if (cacheBuffer != null && (expectedPacketSize == 0 || (expectedPacketSize > 0 && cacheBuffer.length >= expectedPacketSize))) {
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Data pulled from source: " + cacheBuffer + ".");
+
+            ByteBuffer tmp = cacheBuffer;
+            cacheBuffer = null;
+            return tmp;
+        } else {
+            return null;
+        }
     }
-  }
 
-  @Override
-  public ByteBuffer pull(boolean block) {
-    if (!pullMode)
-      throw new RuntimeException("This link is not in pull mode.");
+    @Override
+    public Element setSink(Element sink) {
+        if (sink != null && this.sink != null)
+            throw new RuntimeException("[" + this + "] ERROR: This link sink element is already set. Link: " + this + ", new sink: " + sink + ", existing sink: "
+                    + this.sink + ".");
 
-    if (paused) {
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Cannot pull, link is paused.");
+        if (sink == null && cacheBuffer != null)
+            throw new RuntimeException("[" + this + "] ERROR: Cannot drop link: cache is not empty. Link: " + this + ", cache: " + cacheBuffer);
 
-      // Make slight delay in such case, to avoid consuming 100% of CPU
-      if (block) {
-        try {
-          Thread.sleep(100);
-        } catch (InterruptedException e) {
-        }
-      }
+        this.sink = sink;
 
-      return null;
+        return sink;
     }
 
-    // If data in cache can be sent immediately,
-    // then return it instead of asking for more data from source
-    if (cacheBuffer != null && (expectedPacketSize == 0 || (expectedPacketSize > 0 && cacheBuffer.length >= expectedPacketSize))) {
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Data pulled from cache buffer: " + cacheBuffer + ".");
+    @Override
+    public Element setSource(Element source) {
+        if (this.source != null && source != null)
+            throw new RuntimeException("[" + this + "] ERROR: This link source element is already set. Link: " + this + ", new source: " + source
+                    + ", existing source: " + this.source + ".");
 
-      ByteBuffer tmp = cacheBuffer;
-      cacheBuffer = null;
-      return tmp;
+        this.source = source;
+        return source;
     }
 
-    // Pause this link, so incoming data will not be sent to sink
-    // immediately, then ask source element for more data
-    pause();
-    source.poll(block);
-    resume();
-
-    // Can return something only when data was stored in buffer
-    if (cacheBuffer != null && (expectedPacketSize == 0 || (expectedPacketSize > 0 && cacheBuffer.length >= expectedPacketSize))) {
-      if (verbose)
-        System.out.println("[" + this + "] INFO: Data pulled from source: " + cacheBuffer + ".");
-
-      ByteBuffer tmp = cacheBuffer;
-      cacheBuffer = null;
-      return tmp;
-    } else {
-      return null;
+    @Override
+    public Element getSource() {
+        return source;
     }
-  }
-
-  @Override
-  public Element setSink(Element sink) {
-    if (sink != null && this.sink != null)
-      throw new RuntimeException("This link sink element is already set. Link: " + this + ", new sink: " + sink + ", existing sink: " + this.sink + ".");
-
-    if (sink == null && cacheBuffer != null)
-      throw new RuntimeException("Cannot drop link: cache is not empty. Link: " + this + ", cache: " + cacheBuffer);
-
-    this.sink = sink;
-
-    return sink;
-  }
-
-  @Override
-  public Element setSource(Element source) {
-    if (this.source != null && source != null)
-      throw new RuntimeException("This link source element is already set. Link: " + this + ", new source: " + source + ", existing source: " + this.source
-          + ".");
-
-    this.source = source;
-    return source;
-  }
-
-  @Override
-  public Element getSource() {
-    return source;
-  }
-
-  @Override
-  public Element getSink() {
-    return sink;
-  }
-
-  @Override
-  public void pause() {
-    if (paused)
-      throw new RuntimeException("Link is already paused.");
-
-    paused = true;
-
-  }
-
-  @Override
-  public void resume() {
-    paused = false;
-  }
-
-  /**
-   * Run pull loop to actively pull data from source and push it to sink. It
-   * must be only one pull loop per thread.
-   * 
-   * Pull loop will start after event STREAM_START. This link and source element
-   * incomming links will be switched to pull mode before pull loop will be
-   * started using event LINK_SWITCH_TO_PULL_MODE.
-   */
-  @Override
-  public void run() {
-    // Wait until even STREAM_START will arrive
-    while (!start) {
-      delay();
+
+    @Override
+    public Element getSink() {
+        return sink;
     }
 
-    sendEvent(Event.LINK_SWITCH_TO_PULL_MODE, Direction.IN);
+    @Override
+    public void pause() {
+        if (paused)
+            throw new RuntimeException("[" + this + "] ERROR: Link is already paused.");
 
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Starting pull loop.");
+        paused = true;
 
-    // Pull source in loop
-    while (!shutdown) {
-      // Pull data from source element and send it to sink element
-      ByteBuffer data = pull(true);
-      if (data != null)
-        sink.handleData(data, this);
+    }
 
-      if (!shutdown && data == null) {
-        // Make slight delay to avoid consuming of 100% of CPU
-        delay();
-      }
+    @Override
+    public void resume() {
+        paused = false;
     }
 
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Pull loop finished.");
+    /**
+     * Run pull loop to actively pull data from source and push it to sink. It
+     * must be only one pull loop per thread.
+     * 
+     * Pull loop will start after event STREAM_START. This link and source element
+     * incomming links will be switched to pull mode before pull loop will be
+     * started using event LINK_SWITCH_TO_PULL_MODE.
+     */
+    @Override
+    public void run() {
+        // Wait until even STREAM_START will arrive
+        while (!started) {
+            delay();
+        }
 
-  }
+        sendEvent(Event.LINK_SWITCH_TO_PULL_MODE, Direction.IN);
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Starting pull loop.");
+
+        // Pull source in loop
+        while (!shutdown) {
+            // Pull data from source element and send it to sink element
+            ByteBuffer data = pull(true);
+            if (data != null)
+                sink.handleData(data, this);
+
+            if (!shutdown && data == null) {
+                // Make slight delay to avoid consuming of 100% of CPU
+                delay();
+            }
+        }
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Pull loop finished.");
 
-  protected void delay() {
-    try {
-      Thread.sleep(delay);
-    } catch (InterruptedException e) {
-      e.printStackTrace(System.err);
-      throw new RuntimeException("Interrupted in main loop.", e);
     }
-  }
 
-  @Override
-  public void setPullMode() {
-    if (verbose)
-      System.out.println("[" + this + "] INFO: Switching to PULL mode.");
+    protected void delay() {
+        try {
+            Thread.sleep(delay);
+        } catch (InterruptedException e) {
+            throw new RuntimeException("[" + this + "] ERROR: Interrupted in main loop.", e);
+        }
+    }
 
-    this.pullMode = true;
-  }
+    @Override
+    public void setPullMode() {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Switching to PULL mode.");
 
-  @Override
-  public void drop() {
-    if (pullMode)
-      throw new RuntimeException("Cannot drop link in pull mode.");
+        pullMode = true;
+    }
 
-    if (cacheBuffer != null)
-      throw new RuntimeException("Cannot drop link when cache conatains data: " + cacheBuffer + ".");
+    @Override
+    public void drop() {
+        if (pullMode)
+            throw new RuntimeException("[" + this + "] ERROR: Cannot drop link in pull mode.");
 
-    source.dropLink(this);
-    sink.dropLink(this);
-  }
+        if (cacheBuffer != null)
+            throw new RuntimeException("[" + this + "] ERROR: Cannot drop link when cache conatains data: " + cacheBuffer + ".");
+
+        source.dropLink(this);
+        sink.dropLink(this);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSink.java
new file mode 100755
index 0000000..edfe8db
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSink.java
@@ -0,0 +1,129 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.apr;
+
+import org.apache.tomcat.jni.Socket;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.DataSource;
+import streamer.Direction;
+import streamer.Event;
+import streamer.Link;
+
+public class AprSocketSink extends BaseElement {
+
+    protected AprSocketWrapperImpl socketWrapper;
+    protected Long socket;
+
+    public AprSocketSink(String id) {
+        super(id);
+    }
+
+    public AprSocketSink(String id, AprSocketWrapperImpl socketWrapper) {
+        super(id);
+        this.socketWrapper = socketWrapper;
+    }
+
+    public void setSocket(long socket) {
+        this.socket = socket;
+
+        // Resume links
+        resumeLinks();
+    }
+
+    /**
+     * Send incoming data to stream.
+     */
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (socketWrapper.shutdown)
+            return;
+
+        try {
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Writing data to stream: " + buf + ".");
+
+            // FIXME: If pull is destroyed or socket is closed, segfault will happen here
+            Socket.send(socket, buf.data, buf.offset, buf.length);
+        } catch (Exception e) {
+            System.err.println("[" + this + "] ERROR: " + e.getMessage());
+            closeStream();
+        }
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        switch (event) {
+        case SOCKET_UPGRADE_TO_SSL:
+            socketWrapper.upgradeToSsl();
+            break;
+        case LINK_SWITCH_TO_PULL_MODE:
+            throw new RuntimeException("[" + this + "] ERROR: Unexpected event: sink recived LINK_SWITCH_TO_PULL_MODE event.");
+        default:
+            super.handleEvent(event, direction);
+        }
+    }
+
+    @Override
+    public void setLink(String padName, Link link, Direction direction) {
+        switch (direction) {
+        case IN:
+            super.setLink(padName, link, direction);
+
+            if (socket == null)
+                // Pause links until data stream will be ready
+                link.pause();
+            break;
+        case OUT:
+            throw new RuntimeException("Cannot assign link to output pad in sink element. Element: " + this + ", pad: " + padName + ", link: " + link + ".");
+        }
+    }
+
+    private void resumeLinks() {
+        for (DataSource source : inputPads.values())
+            ((Link)source).resume();
+    }
+
+    @Override
+    protected void onClose() {
+        closeStream();
+    }
+
+    private void closeStream() {
+        if (socketWrapper.shutdown)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Closing stream.");
+
+        try {
+            sendEventToAllPads(Event.STREAM_CLOSE, Direction.IN);
+        } catch (Exception e) {
+        }
+        socketWrapper.shutdown();
+    }
+
+    @Override
+    public String toString() {
+        return "AprSocketSink(" + id + ")";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSource.java
new file mode 100755
index 0000000..178034e
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSource.java
@@ -0,0 +1,171 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.apr;
+
+import org.apache.tomcat.jni.Socket;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.DataSink;
+import streamer.Direction;
+import streamer.Event;
+import streamer.Link;
+
+/**
+ * Source element, which reads data from InputStream.
+ */
+public class AprSocketSource extends BaseElement {
+
+    protected AprSocketWrapperImpl socketWrapper;
+    protected Long socket;
+
+    public AprSocketSource(String id) {
+        super(id);
+    }
+
+    public AprSocketSource(String id, AprSocketWrapperImpl socketWrapper) {
+        super(id);
+        this.socketWrapper = socketWrapper;
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        switch (event) {
+        case SOCKET_UPGRADE_TO_SSL:
+            socketWrapper.upgradeToSsl();
+            break;
+        case LINK_SWITCH_TO_PULL_MODE:
+            // Do nothing - this is the source
+            break;
+        default:
+            super.handleEvent(event, direction);
+        }
+    }
+
+    @Override
+    public void setLink(String padName, Link link, Direction direction) {
+        switch (direction) {
+        case OUT:
+            super.setLink(padName, link, direction);
+
+            if (socket == null) {
+                // Pause links until data stream will be ready
+                link.pause();
+            }
+            break;
+        case IN:
+            throw new RuntimeException("Cannot assign link to input pad in source element. Element: " + this + ", pad: " + padName + ", link: " + link + ".");
+        }
+    }
+
+    public void setSocket(long socket) {
+        this.socket = socket;
+
+        // Resume links
+        resumeLinks();
+    }
+
+    private void resumeLinks() {
+        for (DataSink sink : outputPads.values())
+            ((Link)sink).resume();
+    }
+
+    /**
+     * Read data from input stream.
+     */
+    @Override
+    public void poll(boolean block) {
+        if (socketWrapper.shutdown) {
+            socketWrapper.destroyPull();
+            return;
+        }
+
+        try {
+            // Create buffer of recommended size and with default offset
+            ByteBuffer buf = new ByteBuffer(incommingBufLength);
+
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Reading data from stream.");
+
+            // FIXME: If pull is destroyed or socket is closed, segfault will happen here
+            int actualLength = (block) ? // Blocking read
+            Socket.recv(socket, buf.data, buf.offset, buf.data.length - buf.offset)
+                    : // Non-blocking read
+                    Socket.recvt(socket, buf.data, buf.offset, buf.data.length - buf.offset, 1);
+
+            if (socketWrapper.shutdown) {
+                socketWrapper.destroyPull();
+                return;
+            }
+
+            if (actualLength < 0) {
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: End of stream.");
+
+                buf.unref();
+                closeStream();
+                sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
+                return;
+            }
+
+            if (actualLength == 0) {
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: Empty buffer is read from stream.");
+
+                buf.unref();
+                return;
+            }
+
+            buf.length = actualLength;
+
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Data read from stream: " + buf + ".");
+
+            pushDataToAllOuts(buf);
+
+        } catch (Exception e) {
+            System.err.println("[" + this + "] ERROR: " + e.getMessage());
+            closeStream();
+        }
+    }
+
+    @Override
+    protected void onClose() {
+        closeStream();
+    }
+
+    private void closeStream() {
+
+        if (socketWrapper.shutdown)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Closing stream.");
+
+        try {
+            sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
+        } catch (Exception e) {
+        }
+        socketWrapper.shutdown();
+    }
+
+    @Override
+    public String toString() {
+        return "AprSocketSource(" + id + ")";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketWrapperImpl.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketWrapperImpl.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketWrapperImpl.java
new file mode 100755
index 0000000..2ee426b
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketWrapperImpl.java
@@ -0,0 +1,281 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.apr;
+
+import static streamer.debug.MockServer.Packet.PacketType.CLIENT;
+import static streamer.debug.MockServer.Packet.PacketType.SERVER;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+
+import org.apache.tomcat.jni.Address;
+import org.apache.tomcat.jni.Error;
+import org.apache.tomcat.jni.Library;
+import org.apache.tomcat.jni.Pool;
+import org.apache.tomcat.jni.SSL;
+import org.apache.tomcat.jni.SSLContext;
+import org.apache.tomcat.jni.SSLSocket;
+import org.apache.tomcat.jni.Socket;
+
+import streamer.BaseElement;
+import streamer.Direction;
+import streamer.Element;
+import streamer.Event;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.Queue;
+import streamer.SocketWrapper;
+import streamer.debug.MockServer;
+import streamer.debug.MockServer.Packet;
+import streamer.ssl.SSLState;
+import sun.security.x509.X509CertImpl;
+
+public class AprSocketWrapperImpl extends PipelineImpl implements SocketWrapper {
+
+    static {
+        try {
+            Library.initialize(null);
+            SSL.initialize(null);
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot load Tomcat Native Library (Apache Portable Runtime).", e);
+        }
+    }
+
+    private final SSLState sslState;
+
+    final long pool = Pool.create(0);
+    long inetAddress;
+    long socket;
+    private AprSocketSource source;
+    private AprSocketSink sink;
+
+    boolean shutdown = false;
+
+    private final boolean shutdowned = false;
+
+    public AprSocketWrapperImpl(String id, SSLState sslState) {
+        super(id);
+        this.sslState = sslState;
+    }
+
+    @Override
+    protected HashMap<String, Element> initElementMap(String id) {
+        HashMap<String, Element> map = new HashMap<String, Element>();
+
+        source = new AprSocketSource(id + "." + OUT, this);
+        sink = new AprSocketSink(id + "." + IN, this);
+
+        // Pass requests to read data to socket input stream
+        map.put(OUT, source);
+
+        // All incoming data, which is sent to this socket wrapper, will be sent
+        // to socket remote
+        map.put(IN, sink);
+
+        return map;
+    }
+
+    /**
+     * Connect this socket wrapper to remote server and start main loop on
+     * AprSocketSource stdout link, to watch for incoming data, and
+     * AprSocketSink stdin link, to pull for outgoing data.
+     */
+    @Override
+    public void connect(InetSocketAddress address) throws IOException {
+        try {
+            inetAddress = Address.info(address.getHostName(), Socket.APR_UNSPEC, address.getPort(), 0, pool);
+            socket = Socket.create(Address.getInfo(inetAddress).family, Socket.SOCK_STREAM, Socket.APR_PROTO_TCP, pool);
+        } catch (Exception e) {
+            throw new IOException("[" + this + "] ERROR: Cannot create socket for \"" + address + "\".", e);
+        }
+
+        int ret = Socket.connect(socket, inetAddress);
+        if (ret != 0)
+            throw new IOException("[" + this + "] ERROR: Cannot connect to remote host \"" + address + "\": " + Error.strerror(ret));
+
+        source.setSocket(socket);
+        sink.setSocket(socket);
+
+        // Start polling for data to send to remote sever
+        runMainLoop(IN, STDIN, true, true);
+
+        // Push incoming data from server to handlers
+        runMainLoop(OUT, STDOUT, false, false);
+
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        switch (event) {
+        case SOCKET_UPGRADE_TO_SSL:
+            upgradeToSsl();
+            break;
+        default:
+            super.handleEvent(event, direction);
+            break;
+        }
+    }
+
+    @Override
+    public void validate() {
+
+        if (getPads(Direction.IN).size() == 0)
+            throw new RuntimeException("[ " + this + "] BUG: Input of socket is not connected.");
+
+        if (getPads(Direction.OUT).size() == 0)
+            throw new RuntimeException("[ " + this + "] BUG: Output of socket is not connected.");
+
+    }
+
+    @Override
+    public void upgradeToSsl() {
+
+        try {
+            long sslContext;
+            try {
+                sslContext = SSLContext.make(pool, SSL.SSL_PROTOCOL_TLSV1, SSL.SSL_MODE_CLIENT);
+            } catch (Exception e) {
+                throw new RuntimeException("Cannot create SSL context using Tomcat native library.", e);
+            }
+
+            SSLContext.setOptions(sslContext, SSL.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS | SSL.SSL_OP_TLS_BLOCK_PADDING_BUG | SSL.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
+                    | SSL.SSL_OP_MSIE_SSLV2_RSA_PADDING);
+            // FIXME: verify certificate by default
+            SSLContext.setVerify(sslContext, SSL.SSL_CVERIFY_NONE, 0);
+            int ret;
+            try {
+                ret = SSLSocket.attach(sslContext, socket);
+            } catch (Exception e) {
+                throw new RuntimeException("[" + this + "] ERROR: Cannot attach SSL context to socket: ", e);
+            }
+            if (ret != 0)
+                throw new RuntimeException("[" + this + "] ERROR: Cannot attach SSL context to socket(" + ret + "): " + SSL.getLastError());
+
+            try {
+                ret = SSLSocket.handshake(socket);
+            } catch (Exception e) {
+                throw new RuntimeException("[" + this + "] ERROR: Cannot make SSL handshake with server: ", e);
+            }
+            if (ret != 0 && ret != 20014) // 20014: bad certificate signature FIXME: show prompt for self signed certificate
+                throw new RuntimeException("[" + this + "] ERROR: Cannot make SSL handshake with server(" + ret + "): " + SSL.getLastError());
+
+            try {
+                byte[] key = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT);
+                //*DEBUG*/System.out.println("DEBUG: Server cert:\n"+new ByteBuffer(key).dump());
+                sslState.serverCertificateSubjectPublicKeyInfo = new X509CertImpl(key).getPublicKey().getEncoded();
+            } catch (Exception e) {
+                throw new RuntimeException("[" + this + "] ERROR: Cannot get server public key: ", e);
+            }
+
+        } catch (RuntimeException e) {
+            shutdown();
+            throw e;
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        if (shutdown)
+            return;
+
+        shutdown = true;
+
+        try {
+            handleEvent(Event.STREAM_CLOSE, Direction.IN);
+        } catch (Exception e) {
+        }
+        try {
+            handleEvent(Event.STREAM_CLOSE, Direction.OUT);
+        } catch (Exception e) {
+        }
+    }
+
+    void destroyPull() {
+        if (shutdowned)
+            return;
+
+        // Causes segfault in AprSocketSource.poll() method, so this function must be called from it
+        try {
+            Socket.close(socket);
+            // or
+            // Socket.shutdown(socket, Socket.APR_SHUTDOWN_READWRITE);
+            Pool.destroy(pool);
+        } catch (Exception e) {
+        }
+
+    }
+
+    @Override
+    public String toString() {
+        return "AprSocketWrapper(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        try {
+            System.setProperty("streamer.Link.debug", "true");
+            System.setProperty("streamer.Element.debug", "true");
+            System.setProperty("rdpclient.MockServer.debug", "true");
+
+            Pipeline pipeline = new PipelineImpl("echo client");
+
+            AprSocketWrapperImpl socketWrapper = new AprSocketWrapperImpl("socket", null);
+
+            pipeline.add(socketWrapper);
+            pipeline.add(new BaseElement("echo"));
+            pipeline.add(new Queue("queue")); // To decouple input and output
+
+            pipeline.link("socket", "echo", "queue", "socket");
+
+            final byte[] mockData = new byte[] {0x01, 0x02, 0x03};
+            MockServer server = new MockServer(new Packet[] {new Packet("Server hello") {
+                {
+                    type = SERVER;
+                    data = mockData;
+                }
+            }, new Packet("Client hello") {
+                {
+                    type = CLIENT;
+                    data = mockData;
+                }
+            }, new Packet("Server hello") {
+                {
+                    type = SERVER;
+                    data = mockData;
+                }
+            }, new Packet("Client hello") {
+                {
+                    type = CLIENT;
+                    data = mockData;
+                }
+            }});
+            server.start();
+            InetSocketAddress address = server.getAddress();
+
+            socketWrapper.connect(address);
+
+        } catch (Exception e) {
+            e.printStackTrace(System.err);
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/bco/BcoSocketWrapperImpl.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/bco/BcoSocketWrapperImpl.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/bco/BcoSocketWrapperImpl.java
new file mode 100755
index 0000000..67e2dbd
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/bco/BcoSocketWrapperImpl.java
@@ -0,0 +1,119 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.bco;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.SecureRandom;
+import java.security.Security;
+
+import org.bouncycastle.asn1.x509.X509CertificateStructure;
+import org.bouncycastle.crypto.tls.CertificateVerifyer;
+import org.bouncycastle.crypto.tls.TlsProtocolHandler;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import streamer.Direction;
+import streamer.Event;
+import streamer.SocketWrapperImpl;
+import streamer.ssl.SSLState;
+
+@SuppressWarnings("deprecation")
+public class BcoSocketWrapperImpl extends SocketWrapperImpl {
+
+    static {
+        Security.addProvider(new BouncyCastleProvider());
+    }
+
+    private TlsProtocolHandler bcoSslSocket;
+
+    public BcoSocketWrapperImpl(String id, SSLState sslState) {
+        super(id, sslState);
+    }
+
+    @Override
+    public void upgradeToSsl() {
+
+        if (sslSocket != null)
+            // Already upgraded
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Upgrading socket to SSL.");
+
+        try {
+
+            SecureRandom secureRandom = new SecureRandom();
+            bcoSslSocket = new TlsProtocolHandler(socket.getInputStream(), socket.getOutputStream(), secureRandom);
+
+            CertificateVerifyer client = new CertificateVerifyer() {
+
+                @Override
+                public boolean isValid(X509CertificateStructure[] chain) {
+
+                    try {
+                        if (sslState != null) {
+                            sslState.serverCertificateSubjectPublicKeyInfo = chain[0].getSubjectPublicKeyInfo().getEncoded();
+                        }
+                    } catch (IOException e) {
+                        throw new RuntimeException("Cannot get server public key.", e);
+                    }
+
+                    return true;
+                }
+            };
+            bcoSslSocket.connect(client);
+
+            InputStream sis = bcoSslSocket.getInputStream();
+            source.setInputStream(sis);
+
+            OutputStream sos = bcoSslSocket.getOutputStream();
+            sink.setOutputStream(sos);
+
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot upgrade socket to SSL: " + e.getMessage(), e);
+        }
+
+    }
+
+    @Override
+    public void shutdown() {
+        try {
+            handleEvent(Event.STREAM_CLOSE, Direction.IN);
+        } catch (Exception e) {
+        }
+        try {
+            handleEvent(Event.STREAM_CLOSE, Direction.OUT);
+        } catch (Exception e) {
+        }
+        try {
+            if (bcoSslSocket != null)
+                bcoSslSocket.close();
+        } catch (Exception e) {
+        }
+        try {
+            socket.close();
+        } catch (Exception e) {
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "BcoSocketWrapper(" + id + ")";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java
new file mode 100755
index 0000000..15449c3
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java
@@ -0,0 +1,109 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.debug;
+
+import java.nio.charset.Charset;
+
+import streamer.ByteBuffer;
+
+/**
+ * Assert that writes to this buffer are matching expected data.
+ */
+public class AssertingByteBuffer extends ByteBuffer {
+
+    public AssertingByteBuffer(byte[] expectedData) {
+        super(expectedData);
+    }
+
+    private void assertEquals(int expected, int actual) {
+        if (expected != actual)
+            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ", buf: " + this + ".");
+    }
+
+    @Override
+    public void writeByte(int b) {
+        if (b < 0)
+            throw new RuntimeException();
+        //*DEBUG*/System.out.println("WriteByte: "+b+", cursor:"+cursor+".");
+        assertEquals(readUnsignedByte(), b & 0xff);
+    }
+
+    @Override
+    public void writeShort(int x) {
+        //*DEBUG*/System.out.println("WriteShort: "+x+", cursor:"+cursor+".");
+        assertEquals(readUnsignedShort(), x & 0xFFff);
+    }
+
+    @Override
+    public void writeShortLE(int x) {
+        //*DEBUG*/System.out.println("WriteShortLE: "+x+", cursor:"+cursor+".");
+        assertEquals(readUnsignedShortLE(), x & 0xFFff);
+    }
+
+    @Override
+    public void writeInt(int i) {
+        //*DEBUG*/System.out.println("WriteInt: "+i+", cursor:"+cursor+".");
+        assertEquals(readSignedInt(), i);
+    }
+
+    @Override
+    public void writeIntLE(int i) {
+        //*DEBUG*/System.out.println("WriteIntLE: "+i+", cursor:"+cursor+".");
+        assertEquals(readSignedIntLE(), i);
+    }
+
+    @Override
+    public void writeVariableIntLE(int i) {
+        //*DEBUG*/System.out.println("WriteVariableIntLE: "+i+", cursor:"+cursor+".");
+        assertEquals(readVariableSignedIntLE(), i);
+    }
+
+    @Override
+    public void writeString(String actual, Charset charset) {
+        //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
+        String expected = readString(actual.length(), charset);
+        if (!actual.equals(expected))
+            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
+    }
+
+    @Override
+    public void writeBytes(ByteBuffer actual) {
+        //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
+        ByteBuffer expected = readBytes(actual.length);
+        if (!actual.equals(expected))
+            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
+    }
+
+    @Override
+    public void writeBytes(byte[] actualData) {
+        ByteBuffer actual = new ByteBuffer(actualData);
+        //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
+        ByteBuffer expected = readBytes(actual.length);
+        if (!actual.equals(expected))
+            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
+    }
+
+    @Override
+    public void writeBytes(byte[] actualData, int offset, int length) {
+        ByteBuffer actual = new ByteBuffer(actualData, offset, length);
+        //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
+        ByteBuffer expected = readBytes(actual.length);
+        if (!actual.equals(expected))
+            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/Dumper.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/Dumper.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/Dumper.java
new file mode 100755
index 0000000..c884cfb
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/Dumper.java
@@ -0,0 +1,28 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.debug;
+
+import streamer.ByteBuffer;
+
+public interface Dumper {
+
+    /**
+     * Parse and dump content of buffer.
+     */
+    void dump(ByteBuffer buf);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java
new file mode 100755
index 0000000..9315488
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java
@@ -0,0 +1,77 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.debug;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Direction;
+import streamer.Element;
+import streamer.Event;
+import streamer.Link;
+import streamer.SyncLink;
+
+public class FakeSink extends BaseElement {
+
+    public FakeSink(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Received buf #" + (packetNumber) + " " + buf + ".");
+
+        if (buf == null)
+            return;
+
+        // Use packetNumber variable to count incoming packets
+        packetNumber++;
+
+        buf.unref();
+    }
+
+    @Override
+    public String toString() {
+        return "FakeSink(" + id + ")";
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Event received: " + event + ".");
+
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        Element sink = new FakeSink("sink") {
+            {
+                verbose = true;
+            }
+        };
+
+        byte[] data = new byte[] {1, 2, 3};
+        ByteBuffer buf = new ByteBuffer(data);
+        sink.setLink(STDIN, new SyncLink(), Direction.IN);
+        sink.getLink(STDIN).sendData(buf);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java
new file mode 100755
index 0000000..adfa594
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java
@@ -0,0 +1,138 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.debug;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Direction;
+import streamer.Element;
+import streamer.Event;
+import streamer.Link;
+import streamer.SyncLink;
+
+public class FakeSource extends BaseElement {
+
+    /**
+     * Delay for null packets in poll method when blocking is requested, in
+     * milliseconds.
+     */
+    protected long delay = SyncLink.STANDARD_DELAY_FOR_EMPTY_PACKET;
+
+    public FakeSource(String id) {
+        super(id);
+    }
+
+    @Override
+    public void poll(boolean block) {
+        if (numBuffers > 0 && packetNumber >= numBuffers) {
+            // Close stream when limit of packets is reached
+            sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
+            return;
+        }
+
+        // Prepare new packet
+        ByteBuffer buf = initializeData();
+
+        // Push it to output(s)
+        if (buf != null)
+            pushDataToAllOuts(buf);
+
+        // Make slight delay when blocking input was requested (to avoid
+        // consuming of 100% in parent loop)
+        if (block)
+            delay();
+
+    }
+
+    /**
+     * Make slight delay. Should be used when blocking input is requested in pull
+     * mode, but null packed was returned by input.
+     */
+    protected void delay() {
+        try {
+            Thread.sleep(delay);
+        } catch (InterruptedException e) {
+        }
+    }
+
+    /**
+     * Initialize data.
+     */
+    public ByteBuffer initializeData() {
+        ByteBuffer buf = new ByteBuffer(incommingBufLength);
+
+        // Set first byte of package to it sequance number
+        buf.data[buf.offset] = (byte)(packetNumber % 128);
+
+        // Initialize rest of bytes with sequential values, which are
+        // corresponding with their position in byte buffer
+        for (int i = buf.offset + 1; i < buf.length; i++)
+            buf.data[i] = (byte)(i % 128);
+
+        buf.putMetadata(ByteBuffer.SEQUENCE_NUMBER, packetNumber);
+        buf.putMetadata("src", id);
+
+        return buf;
+    }
+
+    @Override
+    public String toString() {
+        return "FakeSource(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        Element fakeSource = new FakeSource("source 3/10/100") {
+            {
+                verbose = true;
+                this.incommingBufLength = 3;
+                this.numBuffers = 10;
+                this.delay = 100;
+            }
+        };
+
+        Element fakeSink = new FakeSink("sink") {
+            {
+                this.verbose = true;
+            }
+        };
+
+        Element fakeSink2 = new FakeSink("sink2") {
+            {
+                this.verbose = true;
+            }
+        };
+
+        Link link = new SyncLink();
+
+        fakeSource.setLink(STDOUT, link, Direction.OUT);
+        fakeSink.setLink(STDIN, link, Direction.IN);
+
+        Link link2 = new SyncLink();
+
+        fakeSource.setLink("out2", link2, Direction.OUT);
+        fakeSink2.setLink(STDIN, link2, Direction.IN);
+
+        link.sendEvent(Event.STREAM_START, Direction.IN);
+        link.run();
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java
new file mode 100755
index 0000000..3f313b8
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java
@@ -0,0 +1,202 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.debug;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Arrays;
+
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+public class MockServer implements Runnable {
+
+    private boolean shutdown = false;
+    private ServerSocket serverSocket;
+    private Packet[] packets;
+    private Throwable exception;
+    private boolean shutdowned;
+
+    /**
+     * Set to true to enable debugging messages.
+     */
+    protected boolean verbose = System.getProperty("rdpclient.MockServer.debug", "false").equals("true");
+
+    public MockServer(Packet packets[]) {
+        this.packets = packets;
+    }
+
+    public void start() throws IOException {
+        serverSocket = new ServerSocket(0);
+
+        shutdown = false;
+        exception = null;
+        shutdowned = false;
+
+        Thread thread = new Thread(this);
+        thread.setDaemon(true);
+        thread.start();
+    }
+
+    public void run() {
+
+        try {
+            Socket socket = serverSocket.accept();
+
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Clien connected: " + socket.getRemoteSocketAddress() + ".");
+
+            InputStream is = socket.getInputStream();
+            OutputStream os = socket.getOutputStream();
+
+            try {
+                for (int i = 0; i < packets.length && !shutdown; i++) {
+
+                    Packet packet = packets[i];
+                    switch (packet.type) {
+                    case CLIENT: {
+                        // Read client data and compare it with mock data
+                        // (unless "ignore" option is set)
+                        byte actualData[] = new byte[packet.data.length];
+                        int actualDataLength = is.read(actualData);
+
+                        if (verbose)
+                            System.out.println("[" + this + "] INFO: Data is read: {" + Arrays.toString(Arrays.copyOf(actualData, actualDataLength)) + "}.");
+
+                        if (!packet.ignore) {
+                            // Compare actual data with expected data
+                            if (actualDataLength != packet.data.length) {
+                                throw new AssertionError("Actual length of client request for packet #" + (i + 1) + " (\"" + packet.id + "\")"
+                                        + " does not match length of expected client request. Actual length: " + actualDataLength + ", expected legnth: " + packet.data.length
+                                        + ".");
+                            }
+
+                            for (int j = 0; j < packet.data.length; j++) {
+
+                                if (packet.data[j] != actualData[j]) {
+                                    throw new AssertionError("Actual byte #" + (j + 1) + " of client request for packet #" + (i + 1) + " (\"" + packet.id + "\")"
+                                            + " does not match corresponding byte of expected client request. Actual byte: " + actualData[j] + ", expected byte: " + packet.data[j]
+                                            + ".");
+                                }
+                            }
+                        }
+                        break;
+                    }
+                    case SERVER: {
+                        // Send mock data to client
+                        os.write(packet.data);
+
+                        if (verbose)
+                            System.out.println("[" + this + "] INFO: Data is written: {" + Arrays.toString(packet.data) + "}.");
+
+                        break;
+                    }
+                    case UPGRADE_TO_SSL: {
+                        // Attach SSL context to socket
+
+                        final SSLSocketFactory sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
+                        SSLSocket sslSocket = (SSLSocket)sslSocketFactory.createSocket(socket, null, serverSocket.getLocalPort(), true);
+                        sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
+                        sslSocket.setUseClientMode(false);
+                        sslSocket.startHandshake();
+                        is = sslSocket.getInputStream();
+                        os = sslSocket.getOutputStream();
+
+                        break;
+                    }
+                    default:
+                        throw new RuntimeException("Unknown packet type: " + packet.type);
+                    }
+
+                }
+            } finally {
+                try {
+                    is.close();
+                } catch (Throwable e) {
+                }
+                try {
+                    os.close();
+                } catch (Throwable e) {
+                }
+                try {
+                    socket.close();
+                } catch (Throwable e) {
+                }
+                try {
+                    serverSocket.close();
+                } catch (Throwable e) {
+                }
+            }
+        } catch (Throwable e) {
+            System.err.println("Error in mock server: " + e.getMessage());
+            e.printStackTrace(System.err);
+            exception = e;
+        }
+        shutdowned = true;
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Mock server shutdowned.");
+
+    }
+
+    public void shutdown() {
+        shutdown = true;
+    }
+
+    public InetSocketAddress getAddress() {
+        return (InetSocketAddress)serverSocket.getLocalSocketAddress();
+    }
+
+    public Throwable getException() {
+        return exception;
+    }
+
+    public static class Packet {
+        public static enum PacketType {
+            SERVER, CLIENT, UPGRADE_TO_SSL;
+        }
+
+        public String id = "";
+
+        public Packet() {
+        }
+
+        public Packet(String id) {
+            this.id = id;
+        }
+
+        public PacketType type;
+
+        public boolean ignore = false;
+
+        public byte data[];
+    }
+
+    public boolean isShutdowned() {
+        return shutdowned;
+    }
+
+    public void waitUntilShutdowned(long timeToWaitMiliseconds) throws InterruptedException {
+        long deadline = System.currentTimeMillis() + timeToWaitMiliseconds;
+        while (!shutdowned && System.currentTimeMillis() < deadline) {
+            Thread.sleep(10);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSink.java
new file mode 100755
index 0000000..3c1ce7c
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSink.java
@@ -0,0 +1,154 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.debug;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Direction;
+import streamer.Element;
+import streamer.Link;
+import streamer.SyncLink;
+
+/**
+ * Compare incoming packets with expected packets.
+ */
+public class MockSink extends BaseElement {
+
+    protected ByteBuffer bufs[];
+    protected Dumper dumper;
+
+    public MockSink(String id) {
+        super(id);
+    }
+
+    public MockSink(String id, ByteBuffer bufs[]) {
+        super(id);
+        this.bufs = bufs;
+    }
+
+    public MockSink(String id, ByteBuffer bufs[], Dumper dumper) {
+        super(id);
+        this.bufs = bufs;
+        this.dumper = dumper;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Received buf #" + (packetNumber) + " " + buf + ".");
+
+        if (buf == null)
+            return;
+
+        if (packetNumber >= bufs.length)
+            throw new AssertionError("[" + this + "] Incoming buffer #" + packetNumber + " is not expected. Number of expected buffers: " + bufs.length
+                    + ", unexpected buffer: " + buf + ".");
+
+        // Compare incoming buffer with expected buffer
+        ByteBuffer expectedBuf = bufs[packetNumber];
+        if (!Arrays.equals(expectedBuf.toByteArray(), buf.toByteArray())) {
+            dump(buf, expectedBuf);
+            throw new AssertionError("[" + this + "] Incoming buffer #" + packetNumber + " is not equal to expected buffer.\n  Actual bufer: " + buf
+                    + ",\n  expected buffer: " + expectedBuf + ".");
+        }
+
+        // If expected buffer has metadata, then compare it too
+        Set<String> metadataKeys = expectedBuf.getMetadataKeys();
+        if (metadataKeys.size() > 0) {
+            for (String key : metadataKeys) {
+                Object expectedValue = expectedBuf.getMetadata(key);
+                Object actualValue = buf.getMetadata(key);
+                if (actualValue == null)
+                    throw new AssertionError("[" + this + "] Incoming buffer #" + packetNumber + " is not equal to expected buffer in metadata for key \"" + key
+                            + "\".\n  Actual metadata value: " + actualValue + ",\n  expected value: \"" + expectedValue + "\".");
+
+                if (!expectedValue.equals(actualValue))
+                    throw new AssertionError("[" + this + "] Incoming buffer #" + packetNumber + " is not equal to expected buffer in metadata for key \"" + key
+                            + "\".\n  Actual metadata value: \"" + actualValue + "\",\n  expected value: \"" + expectedValue + "\".");
+            }
+        }
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: buffers are equal.");
+
+        // Use packetNumber variable to count incoming packets
+        packetNumber++;
+
+        buf.unref();
+    }
+
+    private void dump(ByteBuffer actualData, ByteBuffer expectedData) {
+        if (dumper != null) {
+            System.out.println("[" + this + "] INFO: Actual data:");
+            dumper.dump(actualData);
+            System.out.println("[" + this + "] INFO: Expected data:");
+            dumper.dump(expectedData);
+        }
+    }
+
+    @Override
+    protected void onClose() {
+        super.onClose();
+
+        if (packetNumber != bufs.length)
+            throw new AssertionError("[" + this + "] Number of expected buffers: " + bufs.length + ", number of actual buffers: " + packetNumber + ".");
+    }
+
+    @Override
+    public String toString() {
+        return "MockSink(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        Element mockSource = new MockSource("source") {
+            {
+                this.bufs = new ByteBuffer[] {new ByteBuffer(new byte[] {1, 1, 2, 3, 4, 5}), new ByteBuffer(new byte[] {2, 1, 2, 3, 4}),
+                        new ByteBuffer(new byte[] {3, 1, 2, 3}), new ByteBuffer(new byte[] {4, 1, 2}), new ByteBuffer(new byte[] {5, 1})};
+                this.verbose = true;
+                this.delay = 100;
+                this.numBuffers = this.bufs.length;
+            }
+        };
+
+        Element mockSink = new MockSink("sink") {
+            {
+                this.bufs = new ByteBuffer[] {new ByteBuffer(new byte[] {1, 1, 2, 3, 4, 5}), new ByteBuffer(new byte[] {2, 1, 2, 3, 4}),
+                        new ByteBuffer(new byte[] {3, 1, 2, 3}), new ByteBuffer(new byte[] {4, 1, 2}), new ByteBuffer(new byte[] {5, 1})};
+                this.verbose = true;
+            }
+        };
+
+        Link link = new SyncLink() {
+            {
+                this.verbose = true;
+            }
+        };
+
+        mockSource.setLink(STDOUT, link, Direction.OUT);
+        mockSink.setLink(STDIN, link, Direction.IN);
+
+        link.run();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java
new file mode 100755
index 0000000..2a70829
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java
@@ -0,0 +1,95 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.debug;
+
+import streamer.ByteBuffer;
+import streamer.Direction;
+import streamer.Element;
+import streamer.Event;
+import streamer.Link;
+import streamer.SyncLink;
+
+public class MockSource extends FakeSource {
+
+    protected ByteBuffer bufs[] = null;
+
+    public MockSource(String id) {
+        super(id);
+    }
+
+    public MockSource(String id, ByteBuffer bufs[]) {
+        super(id);
+        this.bufs = bufs;
+    }
+
+    /**
+     * Initialize data.
+     */
+    @Override
+    public ByteBuffer initializeData() {
+        if (packetNumber >= bufs.length) {
+            sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
+            return null;
+        }
+
+        ByteBuffer buf = bufs[packetNumber];
+
+        buf.putMetadata(ByteBuffer.SEQUENCE_NUMBER, packetNumber);
+        return buf;
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Event received: " + event + ".");
+
+    }
+
+    @Override
+    public String toString() {
+        return "MockSource(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        Element mockSource = new MockSource("source") {
+            {
+                this.bufs = new ByteBuffer[] {new ByteBuffer(new byte[] {1, 1, 2, 3, 4, 5}), new ByteBuffer(new byte[] {2, 1, 2, 3, 4}),
+                        new ByteBuffer(new byte[] {3, 1, 2, 3}), new ByteBuffer(new byte[] {4, 1, 2}), new ByteBuffer(new byte[] {5, 1})};
+                this.verbose = true;
+                this.delay = 100;
+                // this.numBuffers = this.bufs.length;
+            }
+        };
+
+        Element fakeSink = new FakeSink("sink") {
+            {
+                this.verbose = true;
+            }
+        };
+
+        Link link = new SyncLink();
+
+        mockSource.setLink(STDOUT, link, Direction.OUT);
+        fakeSink.setLink(STDIN, link, Direction.IN);
+
+        link.run();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/SSLState.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/SSLState.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/SSLState.java
new file mode 100755
index 0000000..f405088
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/SSLState.java
@@ -0,0 +1,26 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.ssl;
+
+public class SSLState {
+
+    /**
+     * Server public certificate in ASN.1 BER format.
+     */
+    public byte[] serverCertificateSubjectPublicKeyInfo;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java
new file mode 100755
index 0000000..4d9eac2
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java
@@ -0,0 +1,52 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.ssl;
+
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.X509TrustManager;
+
+public class TrustAllX509TrustManager implements X509TrustManager {
+    private SSLState sslState;
+
+    public TrustAllX509TrustManager(SSLState sslState) {
+        this.sslState = sslState;
+    }
+
+    @Override
+    public void checkClientTrusted(final X509Certificate[] chain, final String authType) {
+        // TODO: ask user to confirm self-signed certificates
+        // Trust all (insecure)
+    }
+
+    @Override
+    public void checkServerTrusted(final X509Certificate[] chain, final String authType) {
+        // TODO: ask user to confirm self-signed certificates
+        // Trust all (insecure)
+
+        // Store public certificates to use for NTLMSSP negotiation
+        if (sslState != null)
+            sslState.serverCertificateSubjectPublicKeyInfo = chain[0].getPublicKey().getEncoded();
+    }
+
+    @Override
+    public X509Certificate[] getAcceptedIssuers() {
+        // TODO: use system CA certificates here
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java
new file mode 100755
index 0000000..9d7c708
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 streamer.ssl;
+
+import streamer.ByteBuffer;
+import streamer.Direction;
+import streamer.Event;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class UpgradeSocketToSSL extends OneTimeSwitch {
+
+    public UpgradeSocketToSSL(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void onStart() {
+
+        sendEventToAllPads(Event.SOCKET_UPGRADE_TO_SSL, Direction.IN);
+        switchOff();
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        throw new RuntimeException("Unexpected data: " + buf + ".");
+
+    }
+
+}


[10/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSConnectInitial.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSConnectInitial.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSConnectInitial.java
new file mode 100755
index 0000000..36ed8ae
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSConnectInitial.java
@@ -0,0 +1,696 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class ClientMCSConnectInitial extends OneTimeSwitch {
+
+    public ClientMCSConnectInitial(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        int length = 1024; // Large enough
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        /* @formatter:off */
+    buf.writeBytes(new byte[] {
+        (byte)0x7f, (byte)0x65, (byte)0x82, (byte)0x01, (byte)0x6d, (byte)0x04, (byte)0x01, (byte)0x01, (byte)0x04, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0xff, (byte)0x30, (byte)0x1a,
+        (byte)0x02, (byte)0x01, (byte)0x22, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02,
+        (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x30, (byte)0x19, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02,
+        (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x02,
+        (byte)0x04, (byte)0x20, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x30, (byte)0x20, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xfc,
+        (byte)0x17, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02,
+        (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x82, (byte)0x01, (byte)0x07, (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x14, (byte)0x7c,
+        (byte)0x00, (byte)0x01, (byte)0x80, (byte)0xfe, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x01, (byte)0xc0, (byte)0x00, (byte)0x44, (byte)0x75, (byte)0x63, (byte)0x61,
+        (byte)0x80, (byte)0xf0, (byte)0x01, (byte)0xc0, (byte)0xd8, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x03, (byte)0x01, (byte)0xca,
+        (byte)0x03, (byte)0xaa, (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x28, (byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x6f, (byte)0x00,
+        (byte)0x6c, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x76, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x73, (byte)0x00,
+        (byte)0x69, (byte)0x00, (byte)0x76, (byte)0x00, (byte)0x6b, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0xca, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00,
+        (byte)0x07, (byte)0x00, (byte)0x21, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0xc0, (byte)0x0c, (byte)0x00, (byte)0x0d, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0xc0, (byte)0x0c, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, 
+    });
+//    
+//    buf.writeBytes(new byte[] {
+////        - T125: MCSConnect Initial
+////        - MCSConnectInitial: Identifier=Generic Conference Control (0.0.20.124.0.1), ConnectPDULength=254
+////         - ConnectInitialHeader: 
+//      (byte)0x7F, (byte)0x65, 
+////          - AsnId: Application Constructed Tag (101)
+////           - HighTag: 
+////              Class:     (01......) Application (1)
+////              Type:      (..1.....) Constructed
+////              TagNumber: (...11111)
+////              TagValueEnd: 101 (0x65)
+//      (byte)0x82, (byte)0x01, (byte)0x6C, 
+////          - AsnLen: Length = 364, LengthOfLength = 2
+////             LengthType: LengthOfLength = 2
+////             Length: 364 bytes
+//      (byte)0x04, (byte)0x01, (byte)0x01, 
+////         - CallingDomainSelector: 0x1
+////          - AsnOctetStringHeader: 
+////           - AsnId: OctetString type (Universal 4)
+////            - LowTag: 
+////               Class:    (00......) Universal (0)
+////               Type:     (..0.....) Primitive
+////               TagValue: (...00100) 4
+////           - AsnLen: Length = 1, LengthOfLength = 0
+////              Length: 1 bytes, LengthOfLength = 0
+////            OctetStream: 0x1
+//      (byte)0x04, (byte)0x01, (byte)0x01,
+////         - CalledDomainSelector: 0x1
+////          - AsnOctetStringHeader: 
+////           - AsnId: OctetString type (Universal 4)
+////            - LowTag: 
+////               Class:    (00......) Universal (0)
+////               Type:     (..0.....) Primitive
+////               TagValue: (...00100) 4
+////           - AsnLen: Length = 1, LengthOfLength = 0
+////              Length: 1 bytes, LengthOfLength = 0
+////            OctetStream: 0x1
+//      (byte)0x01, (byte)0x01, (byte)0xFF,
+////         - UpwardFlag: True
+////          - AsnBooleanHeader: 
+////           - AsnId: Boolean type (Universal 1)
+////            - LowTag: 
+////               Class:    (00......) Universal (0)
+////               Type:     (..0.....) Primitive
+////               TagValue: (...00001) 1
+////           - AsnLen: Length = 1, LengthOfLength = 0
+////              Length: 1 bytes, LengthOfLength = 0
+////            Tf: 255 (0xFF)
+//
+////
+////         - TargetParameters: Length = 26, LengthOfLength = 0
+//      (byte)0x30, (byte)0x1A, 
+////          - DomainParametersHeader: 0x1
+////           - AsnId: Sequence and SequenceOf types (Universal 16)
+////            - LowTag: 
+////               Class:    (00......) Universal (0)
+////               Type:     (..1.....) Constructed
+////               TagValue: (...10000) 16
+////           - AsnLen: Length = 26, LengthOfLength = 0
+////              Length: 26 bytes, LengthOfLength = 0
+//      (byte)0x02, (byte)0x01, (byte)0x22, 
+////          - ChannelIds: 34
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 34 (0x22)
+//      (byte)0x02, (byte)0x01, (byte)0x02,
+////          - UserIDs: 2
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 2 (0x2)
+//      (byte)0x02, (byte)0x01, (byte)0x00,
+////          - TokenIds: 0
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 0 (0x0)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - NumPriorities: 1
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x01, (byte)0x00,
+////          - MinThroughput: 0
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 0 (0x0)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - Height: 1
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF,
+////          - MCSPDUsize: 65535
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 3, LengthOfLength = 0
+////               Length: 3 bytes, LengthOfLength = 0
+////             AsnInt: 65535 (0xFFFF)
+//      (byte)0x02, (byte)0x01, (byte)0x02, 
+////          - protocolVersion: 2
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 2 (0x2)
+//
+////      
+////         - MinimumParameters: Length = 25, LengthOfLength = 0
+//      (byte)0x30, (byte)0x19, 
+////          - DomainParametersHeader: 0x1
+////           - AsnId: Sequence and SequenceOf types (Universal 16)
+////            - LowTag: 
+////               Class:    (00......) Universal (0)
+////               Type:     (..1.....) Constructed
+////               TagValue: (...10000) 16
+////           - AsnLen: Length = 25, LengthOfLength = 0
+////              Length: 25 bytes, LengthOfLength = 0
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - ChannelIds: 1
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - UserIDs: 1
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - TokenIds: 1
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - NumPriorities: 1
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x01, (byte)0x00,
+////          - MinThroughput: 0
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 0 (0x0)
+//      (byte)0x02, (byte)0x01, (byte)0x01, 
+////          - Height: 1
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x02, (byte)0x04, (byte)0x20, 
+////          - MCSPDUsize: 1056
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 2, LengthOfLength = 0
+////               Length: 2 bytes, LengthOfLength = 0
+////             AsnInt: 1056 (0x420)
+//      (byte)0x02, (byte)0x01, (byte)0x02, 
+////          - protocolVersion: 2
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 2 (0x2)
+////         - MaximumParameters: Length = 31, LengthOfLength = 0
+////          - DomainParametersHeader: 0x1
+//      (byte)0x30, (byte)0x1F,
+////           - AsnId: Sequence and SequenceOf types (Universal 16)
+////            - LowTag: 
+////               Class:    (00......) Universal (0)
+////               Type:     (..1.....) Constructed
+////               TagValue: (...10000) 16
+////           - AsnLen: Length = 31, LengthOfLength = 0
+////              Length: 31 bytes, LengthOfLength = 0
+//      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF, 
+////          - ChannelIds: 65535
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 3, LengthOfLength = 0
+////               Length: 3 bytes, LengthOfLength = 0
+////             AsnInt: 65535 (0xFFFF)
+//      (byte)0x02, (byte)0x02, (byte)0xFC, (byte)0x17, 
+////          - UserIDs: 64535
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 2, LengthOfLength = 0
+////               Length: 2 bytes, LengthOfLength = 0
+////             AsnInt: 64535 (0xFC17)
+//      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF,
+////          - TokenIds: 65535
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 3, LengthOfLength = 0
+////               Length: 3 bytes, LengthOfLength = 0
+////             AsnInt: 65535 (0xFFFF)
+//      (byte)0x02, (byte)0x01, (byte)0x01, 
+////          - NumPriorities: 1
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x01, (byte)0x00, 
+////          - MinThroughput: 0
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 0 (0x0)
+//      (byte)0x02, (byte)0x01, (byte)0x01, 
+////          - Height: 1
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF, 
+////          - MCSPDUsize: 65535
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 3, LengthOfLength = 0
+////               Length: 3 bytes, LengthOfLength = 0
+////             AsnInt: 65535 (0xFFFF)
+//      (byte)0x02, (byte)0x01, (byte)0x02, 
+////          - protocolVersion: 2
+////           - AsnIntegerHeader: 
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 2 (0x2)
+////         - UserData: Identifier=Generic Conference Control (0.0.20.124.0.1), ConnectPDULength=254
+////          - UserDataHeader: 
+//      (byte)0x04, (byte)0x82, (byte)0x01, (byte)0x07, 
+////           - AsnId: OctetString type (Universal 4)
+////            - LowTag: 
+////               Class:    (00......) Universal (0)
+////               Type:     (..0.....) Primitive
+////               TagValue: (...00100) 4
+////           - AsnLen: Length = 263, LengthOfLength = 2
+////              LengthType: LengthOfLength = 2
+////              Length: 263 bytes
+//      (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x14, (byte)0x7C, (byte)0x00, (byte)0x01, 
+////          - AsnBerObjectIdentifier: Generic Conference Contro (0.0.20.124.0.1)
+////           - AsnObjectIdentifierHeader: 
+////            - AsnId: Reserved for use by the encoding rules (Universal 0)
+////             - LowTag: 
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00000) 0
+////            - AsnLen: Length = 5, LengthOfLength = 0
+////               Length: 5 bytes, LengthOfLength = 0
+////             First: 0 (0x0)
+////             Final: 20 (0x14)
+////             Final: 124 (0x7C)
+////             Final: 0 (0x0)
+////             Final: 1 (0x1)
+//      (byte)0x80, (byte)0xFE, 
+////          - ConnectPDULength: 254
+////             Align: No Padding
+////             Length: 254
+//      (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x10,
+////          - ConnectGCCPDU: conferenceCreateRequest
+////             ExtensionBit: 0 (0x0)
+////           - ChoiceValue: conferenceCreateRequest
+////              Value: (000.....) 0x0
+////           - conferenceCreateRequest: 
+////              ExtensionBit: 0 (0x0)
+////              convenerPasswordPresent: 0 (0x0)
+////              passwordPresent: 0 (0x0)
+////              conductorPrivilegesPresent: 0 (0x0)
+////              conductedPrivilegesPresent: 0 (0x0)
+////              nonConductedPrivilegesPresent: 0 (0x0)
+////              conferenceDescriptionPresent: 0 (0x0)
+////              callerIdentifierPresent: 0 (0x0)
+////              userDataPresent: 1 (0x1)
+////            - conferenceName: 
+////               ExtensionBit: 0 (0x0)
+////               textPresent: 0 (0x0)
+////             - numeric: 1
+////              - SimpleNumericString: 1
+////               - NumericString: 1
+////                - Align: No Padding
+////                   Padding1: (0.......) 0x0
+////                - Length: 1
+////                   Value: (00000000) 0x0
+////                - Restrictedstr: 1
+////                   FourBits: (0001....) 0x1
+////            - lockedConference: False
+////               Value: False 0.......
+////            - listedConference: False
+////               Value: False 0.......
+////            - conductibleConference: False
+////               Value: False 0.......
+////            - TerminationMethod: automatic
+////               ExtensionBit: 0 (0x0)
+////             - RootIndex: 0
+////                Value: (0.......) 0x0
+////            - userData: 
+//      (byte)0x00, (byte)0x01, 
+////             - Size: 1
+////              - Align: No Padding
+////                 Padding7: (0000000.) 0x0
+////                Length: 1
+////             - UserData: 0x44756361
+//      (byte)0xC0, (byte)0x00, (byte)0x44, (byte)0x75, (byte)0x63, (byte)0x61, 
+////                valuePresent: 1 (0x1)
+////              - key: h221NonStandard "Duca"
+////               - ChoiceValue: h221NonStandard
+////                  Value: (1.......) 0x1
+////               - h221NonStandard: 
+////                - H221NonStandardIdentifier: length: 4
+////                 - ConstrainedLength: 4
+////                    Value: (00000000) 0x0
+////                 - Align: No Padding
+////                    Padding6: (000000..) 0x0
+////                   Value: Binary Large Object (4 Bytes) "Duca"
+////              - ClientMcsConnectInitialPdu: 
+//      (byte)0x80, (byte)0xF0, 
+////               - RDPGCCUserDataRequestLength: 240
+////                  Align: No Padding
+////                  Length: 240
+////               - TsUd: CS_CORE
+//      (byte)0x01, (byte)0xC0, (byte)0xD8, (byte)0x00, 
+////                - TsUdHeader: Type = CS_CORE, Length = 216
+////                   Type: CS_CORE
+////                   Length: 216 (0xD8)
+////                - TsUdCsCore: 
+//      (byte)0x04, (byte)0x00, (byte)0x08, (byte)0x00, 
+////                   Version: RDP 5.0, 5.1, 5.2, 6.0, 6.1, and 7.0 
+//      (byte)0x00, (byte)0x04, 
+////                   DesktopWidth: 1024 (0x400)
+//      (byte)0x00, (byte)0x03, 
+////                   DesktopHeight: 768 (0x300)
+//      (byte)0x01, (byte)0xCA, 
+////                   ColorDepth: 8 bpp
+//      (byte)0x03, (byte)0xAA, 
+////                   SASSequence: 0xaa03, SHOULD be set to RNS_UD_SAS_DEL(0xAA03)
+//      (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, 
+////                   KeyboardLayout: Language: English, Location: United States
+//      (byte)0x28, (byte)0x0A, (byte)0x00, (byte)0x00, 
+////                   ClientBuild: 2600 (0xA28)
+//      (byte)0x61, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x6C, (byte)0x00, (byte)0x6C, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x33, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+////                   ClientName: apollo3
+//      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+////                   KeyboardType: Undefined value: 0
+//      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+////                   KeyboardSubType: 0 (0x0)
+//      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+////                   KeyboardFunctionKey: 0 (0x0)
+//      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+////                   ImeFileName: 
+//      (byte)0x01, (byte)0xCA, 
+////                   PostBeta2ColorDepth: 8 bpp
+//      (byte)0x01, (byte)0x00, 
+////                   ClientProductId: 0x1, SHOULD be set to initialized to 1
+//      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+////                   SerialNumber: 0x0, SHOULD be set to 0
+//      (byte)0x10, (byte)0x00, 
+////                   HighColorDepth: 16-bit 565 RGB
+//      (byte)0x07, (byte)0x00, 
+////                 - SupportedColorDepth: 7 (0x7)
+////                    Support24BPP: (...............1) Support 24BPP
+////                    Support16BPP: (..............1.) Support 16BPP
+////                    Support15BPP: (.............1..) Support 15BPP
+////                    Support32BPP: (............0...) Not Support 32BPP
+////                    Reserved:     (000000000000....)
+//      (byte)0x01, (byte)0x00, 
+////                 - EarlyCapabilityFlags: 1 (0x1)
+////                    SupportSetErrorPdu:      (...............1) Indicates that the client supports the Set Error Info PDU
+////                    Want32BppSession:        (..............0.) Client is not requesting 32BPP session
+////                    SupportStatusInfoPdu:    (.............0..) Client not supports the Server Status Info PDU
+////                    StrongAsymmetricKeys:    (............0...) Not support asymmetric keys larger than 512-bits
+////                    Unused:                  (...........0....)
+////                    ValidConnection:         (..........0.....) Not Indicates ConnectionType field contains valid data
+////                    SupportMonitorLayoutPdu: (.........0......) Not Indicates that the client supports the Monitor Layout PDU
+////                    Unused2:                 (000000000.......)
+//      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+////      ClientDigProductId: 
+//(byte)0x00, 
+////      connectionType: invalid connection type
+//(byte)0x00, 
+////      pad1octet: 0 (0x0)
+//(byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 
+////      ServerSelectedProtocols: TLS 1.0
+////
+////  - TsUd: CS_CLUSTER
+////   - TsUdHeader: Type = CS_CLUSTER, Length = 12
+//(byte)0x04, (byte)0xC0, 
+////      Type: CS_CLUSTER
+//(byte)0x0C, (byte)0x00, 
+////      Length: 12 (0xC)
+//(byte)0x0D, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+////   - TsUdCsCluster: 
+////    - Flags: 13 (0xD)
+////       RedirectedSupported: (...............................1) Support Redirected
+////       SessionIDFieldValid: (..............................0.) SessionID Field not Valid
+////       SupportedVersion:    (..........................0011..) REDIRECTION_VERSION4
+////       RedirectedSmartcard: (.........................0......) Not Logon with Smartcard
+////       Unused:           (0000000000000000000000000.......)
+////      RedirectedSessionID: 0 (0x0)
+////
+////  - TsUd: CS_SECURITY
+////   - TsUdHeader: Type = CS_SECURITY, Length = 12
+//(byte)0x02, (byte)0xC0, 
+////      Type: CS_SECURITY
+//(byte)0x0C, (byte)0x00, 
+////      Length: 12 (0xC)
+////      
+////   - TsUdCsSec: 
+//(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+////    - EncryptionMethod: 
+////       Support40Bit:  (...............................0) Not Support 
+////       Support128Bit: (..............................0.) Not Support 128-bit
+////       Reserved1:     (.............................0..)
+////       Support56Bit:  (............................0...) Not Support 56-bit
+////       SupportFIPS:   (...........................0....) Not Support FIPS Compliant
+////       Reserved2:     (000000000000000000000000000.....)
+//(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+////    - ExtEncryptionMethod: 
+////       Support40Bit:  (...............................0) Not Support 
+////       Support128Bit: (..............................0.) Not Support 128-bit
+////       Reserved1:     (.............................0..)
+////       Support56Bit:  (............................0...) Not Support 56-bit
+////       SupportFIPS:   (...........................0....) Not Support FIPS Compliant
+////       Reserved2:     (000000000000000000000000000.....)
+//    });
+    /* @formatter:on */
+
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * Example.
+     * 
+     * @see http://msdn.microsoft.com/en-us/library/cc240836.aspx
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        // TPKT: TPKT version = 3
+        (byte) 0x03,  (byte) 0x00,  
+        // TPKT: Packet length: 378 bytes
+        (byte) 0x01,  (byte) 0x78, 
+        
+        // X.224: Length indicator = 2
+        (byte) 0x02,  
+        // X.224: Type: Data TPDU
+        (byte) 0xf0,  
+        // X.224: EOT
+        (byte) 0x80,  
+        
+        // Captured packet
+        (byte)0x7f, (byte)0x65, (byte)0x82, (byte)0x01, (byte)0x6c, (byte)0x04, (byte)0x01, (byte)0x01, (byte)0x04,
+        (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0xff, (byte)0x30, (byte)0x1a, (byte)0x02, (byte)0x01, (byte)0x22, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x02, (byte)0x01, (byte)0x00,
+        (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01,
+        (byte)0x02, (byte)0x30, (byte)0x19, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02,
+        (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x02, (byte)0x04, (byte)0x20, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x30, (byte)0x1f, (byte)0x02, (byte)0x03,
+        (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x02, (byte)0xfc, (byte)0x17, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02,
+        (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x82, (byte)0x01,
+        (byte)0x07, (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x14, (byte)0x7c, (byte)0x00, (byte)0x01, (byte)0x80, (byte)0xfe, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x01,
+        (byte)0xc0, (byte)0x00, (byte)0x44, (byte)0x75, (byte)0x63, (byte)0x61, (byte)0x80, (byte)0xf0, (byte)0x01, (byte)0xc0, (byte)0xd8, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x08, (byte)0x00,
+        (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x03, (byte)0x01, (byte)0xca, (byte)0x03, (byte)0xaa, (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x28, (byte)0x0a, (byte)0x00, (byte)0x00,
+        (byte)0x61, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x33, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0xca, (byte)0x01, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x04, (byte)0xc0, (byte)0x0c, (byte)0x00, (byte)0x0d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0xc0, (byte)0x0c, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+    };
+    /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element todo = new ClientMCSConnectInitial("ClientMCSConnectInitial");
+        Element x224 = new ClientX224DataPDU("x224");
+        Element tpkt = new ClientTpkt("tpkt");
+
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
+        pipeline.link("source", "ClientMCSConnectInitial", "mainSink");
+        pipeline.link("ClientMCSConnectInitial >" + OTOUT, "x224", "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSErectDomainRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSErectDomainRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSErectDomainRequest.java
new file mode 100755
index 0000000..f4c9937
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSErectDomainRequest.java
@@ -0,0 +1,189 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240683.aspx
+ */
+public class ClientMCSErectDomainRequest extends OneTimeSwitch {
+
+    public ClientMCSErectDomainRequest(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        int length = 5;
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        buf.writeByte(0x04); // Erect Domain Request
+
+        // Client SHOULD initialize both the subHeight and subinterval fields of the MCS Erect Domain Request PDU to zero.
+
+        buf.writeByte(1); // ErectDomainRequest::subHeight length = 1 byte
+        buf.writeByte(0); // ErectDomainRequest::subHeight
+
+        buf.writeByte(1); // ErectDomainRequest::subInterval length = 1 byte
+        buf.writeByte(0); // ErectDomainRequest::subInterval
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * Example.
+     * @see http://msdn.microsoft.com/en-us/library/cc240837.aspx
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+
+        0x03, 0x00, 0x00, 0x0c,  //  TPKT Header (length = 12 bytes)
+        0x02, (byte) 0xf0, (byte) 0x80,  //  X.224 Data TPDU
+        
+        // PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
+        0x04, 0x01, 0x00, 0x01, 0x00,
+         
+        // 0x04:
+        // 0 - --\
+        // 0 -   |
+        // 0 -   | CHOICE: From DomainMCSPDU select erectDomainRequest (1) 
+        // 0 -   | of type ErectDomainRequest
+        // 0 -   |
+        // 1 - --/
+        // 0 - padding
+        // 0 - padding
+        
+        // 0x01:
+        // 0 - --\
+        // 0 -   |
+        // 0 -   |
+        // 0 -   | ErectDomainRequest::subHeight length = 1 byte
+        // 0 -   |
+        // 0 -   |
+        // 0 -   |
+        // 1 - --/
+        
+        // 0x00:
+        // 0 - --\
+        // 0 -   |
+        // 0 -   |
+        // 0 -   | ErectDomainRequest::subHeight = 0
+        // 0 -   |
+        // 0 -   |
+        // 0 -   |
+        // 0 - --/
+        
+        // 0x01:
+        // 0 - --\
+        // 0 -   |
+        // 0 -   |
+        // 0 -   | ErectDomainRequest::subInterval length = 1 byte
+        // 0 -   |
+        // 0 -   |
+        // 0 -   |
+        // 1 - --/
+        
+        // 0x00:
+        // 0 - --\
+        // 0 -   |
+        // 0 -   |
+        // 0 -   | ErectDomainRequest::subInterval = 0
+        // 0 -   |
+        // 0 -   |
+        // 0 -   |
+        // 0 - --/
+
+        
+    };
+    /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element todo = new ClientMCSErectDomainRequest("TODO");
+        Element x224 = new ClientX224DataPDU("x224");
+        Element tpkt = new ClientTpkt("tpkt");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
+        pipeline.link("source", "TODO", "mainSink");
+        pipeline.link("TODO >" + OTOUT, "x224", "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}
+
+/*
+ * 03 00 00 0C 02 F0 80 04 01 00 01 00
+
+  Frame: Number = 14, Captured Frame Length = 69, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 12
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 12 (0xC)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: Erect Domain Request, SubHeight = 0, SubInterval = 0
+  - MCSHeader: Type=Erect Domain Request
+   - Type: Erect Domain Request
+    - RootIndex: 1
+       Value: (000001..) 0x1
+  - MCSErectDomainRequest: SubHeight = 0, SubInterval = 0
+   - SubHeight: 0x0
+    - Length: 1
+     - Align: No Padding
+        Padding2: (00......) 0x0
+       Length: 1
+      Value: 0 (0x0)
+   - SubInterval: 0x0
+    - Length: 1
+       Align: No Padding
+       Length: 1
+      Value: 0 (0x0)
+
+ */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientSynchronizePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientSynchronizePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientSynchronizePDU.java
new file mode 100755
index 0000000..82860cd
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientSynchronizePDU.java
@@ -0,0 +1,248 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240489.aspx
+ */
+public class ClientSynchronizePDU extends OneTimeSwitch {
+
+    public ClientSynchronizePDU(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        int length = 1024; // Large enough
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        /* @formatter:off */
+    buf.writeBytes(new byte[] {
+        // MCS send data request
+        (byte)0x64,
+        // Initiator: 1004 (1001+3)
+        (byte)0x00, (byte)0x03,
+        // Channel ID: 1003 (I/O Channel)
+        (byte)0x03, (byte)0xeb,
+        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+        (byte)0x70, 
+        // Data length:  22 bytes (0x16, variable length field)
+        (byte)0x80,  (byte)0x16, 
+        
+        // RDP: total length: 22 bytes (LE)
+        (byte)0x16, (byte)0x00, 
+        
+        // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE)
+        (byte)0x17, (byte)0x00,
+        
+        // PDU source: 1007 (LE)
+        (byte)0xec, (byte)0x03,
+        // Share ID: 0x000103ea (LE)
+        (byte)0xea, (byte)0x03, (byte)0x01,  (byte)0x00,
+        // Padding: 1 byte
+        (byte)0x00,
+        // Stream ID: STREAM_LOW (1)
+        (byte)0x01, 
+        // uncompressedLength : 8 bytes (LE)
+        (byte)0x08, (byte)0x00,
+        // pduType2 = PDUTYPE2_SYNCHRONIZE (31)
+        (byte)0x1f, 
+        // generalCompressedType: 0
+        (byte)0x00,
+        // generalCompressedLength: 0 (LE?)
+        (byte)0x00, (byte)0x00,
+        //  messageType: SYNCMSGTYPE_SYNC (1) (LE)
+        (byte)0x01, (byte)0x00, 
+        // targetUser: 0x03ea
+        (byte)0xea, (byte)0x03,
+    });
+    /* @formatter:on */
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * Example.
+     * 
+     * @see http://msdn.microsoft.com/en-us/library/cc240841.aspx
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        // TPKT
+        (byte)0x03, (byte)0x00,
+        // TPKT length: 37 bytes
+        (byte)0x00, (byte)0x25,
+        // X224 Data PDU 
+        (byte)0x02, (byte)0xf0, (byte)0x80,
+        
+        // MCS send data request
+        (byte)0x64,
+        // Initiator: 1004 (1001+3)
+        (byte)0x00, (byte)0x03,
+        // Channel ID: 1003 (I/O Channel)
+        (byte)0x03, (byte)0xeb,
+        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+        (byte)0x70, 
+        // Data length:  22 bytes (0x16, variable length field)
+        (byte)0x80,  (byte)0x16, 
+        
+        // RDP: total length: 22 bytes (LE)
+        (byte)0x16, (byte)0x00, 
+        // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE)
+        (byte)0x17, (byte)0x00,
+        // PDU source: 1007 (LE)
+        (byte)0xec, (byte)0x03,
+        // Share ID: 0x000103ea (LE)
+        (byte)0xea, (byte)0x03, (byte)0x01,  (byte)0x00,
+        // Padding: 1 byte
+        (byte)0x00,
+        // Stream ID: STREAM_LOW (1)
+        (byte)0x01, 
+        // uncompressedLength : 8 bytes (LE)
+        (byte)0x08, (byte)0x00,
+        // pduType2 = PDUTYPE2_SYNCHRONIZE (31)
+        (byte)0x1f, 
+        // generalCompressedType: 0
+        (byte)0x00,
+        // generalCompressedLength: 0 (LE?)
+        (byte)0x00, (byte)0x00,
+        //  messageType: SYNCMSGTYPE_SYNC (1) (LE)
+        (byte)0x01, (byte)0x00, 
+        // targetUser: 0x03ea
+        (byte)0xea, (byte)0x03,
+        
+    };
+    /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element todo = new ClientSynchronizePDU("TODO");
+        Element x224 = new ClientX224DataPDU("x224");
+        Element tpkt = new ClientTpkt("tpkt");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
+        pipeline.link("source", "TODO", "mainSink");
+        pipeline.link("TODO >" + OTOUT, "x224", "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}
+
+/*
+ * @formatting:off
+
+ * 03 00 00 25 02 F0 80 64 00 03 03 EB 70 80 16 16 00 17 00 EC 03 EA 03 01 00 00 01 08 00 1F 00 00 00 01 00 EA 03 
+
+  Frame: Number = 40, Captured Frame Length = 94, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 37
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 37 (0x25)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: Data Packet
+  - MCSHeader: Type=Send Data Request, UserID=1004, ChannelID=1003
+   - Type: Send Data Request
+    - RootIndex: 25
+       Value: (011001..) 0x19
+   - UserID: 0x3ec
+    - UserID: 0x3ec
+     - ChannelId: 1004
+      - Align: No Padding
+         Padding2: (00......) 0x0
+        Value: 3 (0x3)
+   - Channel: 0x3eb
+    - ChannelId: 1003
+       Align: No Padding
+       Value: 1003 (0x3EB)
+   - DataPriority: high
+    - DataPriority: high
+     - RootIndex: 1
+        Value: (01......) 0x1
+   - Segmentation: Begin End
+      Begin: (1.......) Begin
+      End:   (.1......) End
+   - Length: 22
+    - Align: No Padding
+       Padding4: (0000....) 0x0
+      Length: 22
+    RDP: RDPBCGR
+- RDPBCGR: SynchronizePDU
+  - SlowPathPacket: SynchronizePDU 
+   - SlowPath: Type = TS_PDUTYPE_DATAPDU
+    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
+       TotalLength: 22 (0x16)
+     - PDUType: 23 (0x17)
+        Type:            (............0111) TS_PDUTYPE_DATAPDU
+        ProtocolVersion: (000000000001....) 1
+       PDUSource: 1004 (0x3EC)
+    - SlowPathIoPacket: 0x0
+     - ShareDataHeader: TS_PDUTYPE2_SYNCHRONIZE
+        ShareID: 66538 (0x103EA)
+        Pad1: 0 (0x0)
+        StreamID: TS_STREAM_LOW
+        UncompressedLength: 8 (0x8)
+        PDUType2: TS_PDUTYPE2_SYNCHRONIZE
+      - CompressedType: Not Compressed
+         MPPC:       (....0000) MPPC 8K
+         Reserved:   (...0....)
+         Compressed: (..0.....) Not Compressed
+         Front:      (.0......) Not At Front
+         Flush:      (0.......) Not Flushed
+        CompressedLength: 0 (0x0)
+     - TsSynchronizePDU: 0x1
+        MessageType: 0x1, MUST be set to SYNCMSGTYPE_SYNC (1)
+        TargetUser: 1002 (0x3EA)
+ */
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientTpkt.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientTpkt.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientTpkt.java
new file mode 100755
index 0000000..926c807
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientTpkt.java
@@ -0,0 +1,54 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class ClientTpkt extends BaseElement {
+
+    public ClientTpkt(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        if (buf.length + 4 > 65535)
+            throw new RuntimeException("Packet is too long for TPKT (max length 65535-4): " + buf + ".");
+
+        ByteBuffer data = new ByteBuffer(4);
+        // TPKT version
+        data.writeByte(3);
+        // Reserved
+        data.writeByte(0);
+        // Packet length, including length of the header
+        data.writeShort(buf.length + 4);
+
+        buf.prepend(data);
+        data.unref();
+
+        pushDataToPad(STDOUT, buf);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224ConnectionRequestPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224ConnectionRequestPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224ConnectionRequestPDU.java
new file mode 100755
index 0000000..1de392b
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224ConnectionRequestPDU.java
@@ -0,0 +1,162 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240470.aspx
+ * @see http://msdn.microsoft.com/en-us/library/cc240663.aspx
+ */
+public class ClientX224ConnectionRequestPDU extends OneTimeSwitch {
+
+    public static final int X224_TPDU_CONNECTION_REQUEST = 0xe0;
+    public static final int X224_TPDU_CONNECTION_CONFIRM = 0xd0;
+    public static final int X224_TPDU_DISCONNECTION_REQUEST = 0x80;
+    public static final int X224_TPDU_DISCONNECTION_CONFIRM = 0xc0;
+    public static final int X224_TPDU_EXPEDITED_DATA = 0x10;
+    public static final int X224_TPDU_DATA_ACKNOWLEDGE = 0x61;
+    public static final int X224_TPDU_EXPEDITET_ACKNOWLEDGE = 0x40;
+    public static final int X224_TPDU_REJECT = 0x51;
+    public static final int X224_TPDU_ERROR = 0x70;
+    public static final int X224_TPDU_PROTOCOL_IDENTIFIER = 0x01;
+
+    /**
+     * Reconnection cookie.
+     */
+    protected String userName;
+
+    /**
+     * Protocol to use:  RDP_NEG_REQ_PROTOCOL_SSL or RDP_NEG_REQ_PROTOCOL_HYBRID. 
+     */
+    protected int protocol;
+
+    public ClientX224ConnectionRequestPDU(String id, String userName, int protocol) {
+        super(id);
+        this.userName = userName;
+        this.protocol = protocol;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        // Length of packet without length field
+        int length = 33 + userName.length();
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        // Type (high nibble) = 0xe = CR TPDU; credit (low nibble) = 0
+        buf.writeByte(X224_TPDU_CONNECTION_REQUEST);
+
+        buf.writeShort(0); // Destination reference = 0
+        buf.writeShort(0); // Source reference = 0
+        buf.writeByte(0); // Class and options = 0
+        buf.writeString("Cookie: mstshash=" + userName + "\r\n", RdpConstants.CHARSET_8); // Cookie
+
+        // RDP_NEG_REQ::type
+        buf.writeByte(RdpConstants.RDP_NEG_REQ_TYPE_NEG_REQ);
+        // RDP_NEG_REQ::flags (0)
+        buf.writeByte(RdpConstants.RDP_NEG_REQ_FLAGS);
+        // RDP_NEG_REQ::length (constant: 8) short int in LE format
+        buf.writeByte(0x08);
+        buf.writeByte(0x00);
+
+        // RDP_NEG_REQ: Requested protocols: PROTOCOL_SSL
+        buf.writeIntLE(protocol);
+
+        // Calculate length of packet and prepend it to buffer
+        ByteBuffer data = new ByteBuffer(5);
+
+        // Write length
+        data.writeVariableIntLE(buf.length);
+
+        // Reset length of buffer to actual length of data written
+        data.length = data.cursor;
+
+        buf.prepend(data);
+        data.unref();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * Example.
+     * 
+     * @see http://msdn.microsoft.com/en-us/library/cc240842.aspx
+     * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        String cookie = "eltons";
+
+        byte[] packet = new byte[] {
+
+                0x03, // TPKT Header: version = 3
+                0x00, // TPKT Header: Reserved = 0
+                0x00, // TPKT Header: Packet length - high part
+                0x2c, // TPKT Header: Packet length - low part (total = 44 bytes)
+                0x27, // X.224: Length indicator (39 bytes)
+                (byte)0xe0, // X.224: Type (high nibble) = 0xe = CR TPDU;
+                            // credit (low nibble) = 0
+                0x00, 0x00, // X.224: Destination reference = 0
+                0x00, 0x00, // X.224: Source reference = 0
+                0x00, // X.224: Class and options = 0
+
+                'C', 'o', 'o', 'k', 'i', 'e', ':', ' ', 'm', 's', 't', 's', 'h', 'a', 's', 'h', '=', 'e', 'l', 't', 'o', 'n', 's', // "Cookie: mstshash=eltons"
+                '\r', '\n', // -Cookie terminator sequence
+
+                0x01, // RDP_NEG_REQ::type (TYPE_RDP_NEG_REQ)
+                0x00, // RDP_NEG_REQ::flags (0)
+                0x08, 0x00, // RDP_NEG_REQ::length (8 bytes)
+                0x01, 0x00, 0x00, 0x00 // RDP_NEG_REQ: Requested protocols
+                                       // (PROTOCOL_SSL in little endian format)
+        };
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element cr = new ClientX224ConnectionRequestPDU("cr", cookie, RdpConstants.RDP_NEG_REQ_PROTOCOL_SSL);
+        Element tpkt = new ClientTpkt("tpkt");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, cr, tpkt, sink, mainSink);
+        pipeline.link("source", "cr", "mainSink");
+        pipeline.link("cr >" + OTOUT, "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224DataPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224DataPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224DataPDU.java
new file mode 100755
index 0000000..b0373ad
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224DataPDU.java
@@ -0,0 +1,52 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class ClientX224DataPDU extends BaseElement {
+
+    public static final int X224_TPDU_DATA = 0xF0;
+    public static final int X224_TPDU_LAST_DATA_UNIT = 0x80;
+
+    public ClientX224DataPDU(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        ByteBuffer data = new ByteBuffer(3);
+        // X224 header
+        data.writeByte(2); // Header length indicator
+        data.writeByte(X224_TPDU_DATA);
+        data.writeByte(X224_TPDU_LAST_DATA_UNIT);
+
+        buf.prepend(data);
+        data.unref();
+
+        pushDataToPad(STDOUT, buf);
+    }
+
+}


[09/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RLEBitmapDecompression.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RLEBitmapDecompression.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RLEBitmapDecompression.java
new file mode 100755
index 0000000..602cce7
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RLEBitmapDecompression.java
@@ -0,0 +1,1014 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.debug.AssertingByteBuffer;
+
+/**
+ * Based on code example from MSDN, @see
+ * http://msdn.microsoft.com/en-us/library/dd240593.aspx .
+ */
+public class RLEBitmapDecompression {
+
+    public static final int g_MaskRegularRunLength = 0x1F;
+    public static final int g_MaskLiteRunLength = 0x0F;
+
+    public static final int g_MaskSpecialFgBg1 = 0x03;
+    public static final int g_MaskSpecialFgBg2 = 0x05;
+
+    public static final int REGULAR_BG_RUN = 0x00;
+    public static final int REGULAR_FG_RUN = 0x01;
+    public static final int REGULAR_FGBG_IMAGE = 0x02;
+    public static final int REGULAR_COLOR_RUN = 0x03;
+    public static final int REGULAR_COLOR_IMAGE = 0x04;
+
+    public static final int LITE_SET_FG_FG_RUN = 0x0C;
+    public static final int LITE_SET_FG_FGBG_IMAGE = 0x0D;
+    public static final int LITE_DITHERED_RUN = 0x0E;
+
+    public static final int MEGA_MEGA_BG_RUN = 0xF0;
+    public static final int MEGA_MEGA_FG_RUN = 0xF1;
+    public static final int MEGA_MEGA_FGBG_IMAGE = 0xF2;
+    public static final int MEGA_MEGA_COLOR_RUN = 0xF3;
+    public static final int MEGA_MEGA_COLOR_IMAGE = 0xF4;
+    public static final int MEGA_MEGA_SET_FG_RUN = 0xF6;
+    public static final int MEGA_MEGA_SET_FGBG_IMAGE = 0xF7;
+    public static final int MEGA_MEGA_DITHERED_RUN = 0xF8;
+
+    public static final int SPECIAL_FGBG_1 = 0xF9;
+    public static final int SPECIAL_FGBG_2 = 0xFA;
+
+    public static final int SPECIAL_WHITE = 0xFD;
+    public static final int SPECIAL_BLACK = 0xFE;
+
+    /**
+     * Writes a pixel to the specified buffer and advance cursor by bpp.
+     * 
+     * @param bpp
+     *          bytes per pixel
+     */
+    private static void writePixel(int bpp, ByteBuffer destBuf, int pixel) {
+        switch (bpp) {
+        case 1:
+            destBuf.writeByte(pixel);
+            break;
+        case 2:
+            destBuf.writeShortLE(pixel);
+            break;
+        case 3:
+            destBuf.writeByte(pixel);
+            destBuf.writeShortLE(pixel >> 8);
+            break;
+        case 4:
+            destBuf.writeIntLE(pixel);
+            break;
+        default:
+            throw new RuntimeException("Unsupported color depth.");
+        }
+    }
+
+    /**
+     * Reads a pixel from the specified buffer at given offset without changing of
+     * cursor.
+     * 
+     * @param bpp
+     *          bytes per pixel
+     * @param offset
+     *          -rowDelta (i.e. (-width*bpp))
+     */
+    private static int peekPixel(int bpp, ByteBuffer destBuf, int offset) {
+        if (offset >= 0 || (-offset) > destBuf.cursor)
+            throw new RuntimeException("Incorrect value for offset: offset in destination buffer must point to pixel in previous row.");
+
+        // Adjust cursor to point to pixel in previous row
+        int oldCursor = destBuf.cursor;
+        destBuf.cursor += offset;
+
+        int pixel;
+        switch (bpp) {
+        case 1:
+            pixel = destBuf.readUnsignedByte();
+            break;
+        case 2:
+            pixel = destBuf.readUnsignedShortLE();
+            break;
+        case 3:
+            pixel = destBuf.readUnsignedByte() | (destBuf.readUnsignedShortLE() >> 8);
+            break;
+        case 4:
+            pixel = destBuf.readSignedIntLE();
+            break;
+        default:
+            throw new RuntimeException("Unsupported color depth.");
+        }
+        destBuf.cursor = oldCursor;
+
+        return pixel;
+    }
+
+    /**
+     * Reads a pixel from the specified buffer and advance cursor by bpp value.
+     * 
+     * @param bpp
+     *          bytes per pixel
+     */
+    private static int readPixel(int bpp, ByteBuffer srcBuf) {
+        int pixel;
+        switch (bpp) {
+        case 1:
+            pixel = srcBuf.readUnsignedByte();
+            break;
+        case 2:
+            pixel = srcBuf.readUnsignedShortLE();
+            break;
+        case 3:
+            pixel = srcBuf.readUnsignedByte() | (srcBuf.readUnsignedShortLE() >> 8);
+            break;
+        case 4:
+            pixel = srcBuf.readSignedIntLE();
+            break;
+        default:
+            throw new RuntimeException("Unsupported color depth.");
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Returns the size of a pixel in bytes.
+     */
+    private static int getPixelSize(int colorDepth) {
+        switch (colorDepth) {
+        case 8:
+            return 1;
+        case 15:
+        case 16:
+            return 2;
+        case 24:
+            return 3;
+        default:
+            throw new RuntimeException("Unsupported pixel color depth: " + colorDepth + " bpp.");
+        }
+    }
+
+    /**
+     * Reads the supplied order header & extracts the compression order code ID.
+     */
+    private static int extractCodeId(int orderHeader) {
+        // Taken from FreeRDP code, bitmap.c
+        switch (orderHeader) {
+        case MEGA_MEGA_BG_RUN:
+        case MEGA_MEGA_FG_RUN:
+        case MEGA_MEGA_SET_FG_RUN:
+        case MEGA_MEGA_DITHERED_RUN:
+        case MEGA_MEGA_COLOR_RUN:
+        case MEGA_MEGA_FGBG_IMAGE:
+        case MEGA_MEGA_SET_FGBG_IMAGE:
+        case MEGA_MEGA_COLOR_IMAGE:
+        case SPECIAL_FGBG_1:
+        case SPECIAL_FGBG_2:
+        case SPECIAL_WHITE:
+        case SPECIAL_BLACK:
+            return orderHeader;
+        }
+
+        int code = orderHeader >> 5;
+        switch (code) {
+        case REGULAR_BG_RUN:
+        case REGULAR_FG_RUN:
+        case REGULAR_COLOR_RUN:
+        case REGULAR_FGBG_IMAGE:
+        case REGULAR_COLOR_IMAGE:
+            return code;
+        }
+
+        return orderHeader >> 4;
+    }
+
+    /**
+     * Returns a black pixel.
+     */
+    private static int getColorBlack() {
+        return 0x000000;
+    }
+
+    /**
+     * Returns a white pixel.
+     */
+    private static int getColorWhite(int colorDepth) {
+        if (colorDepth == 8) {
+            //
+            // Palette entry #255 holds white.
+            //
+            return 0xFF;
+        } else if (colorDepth == 15) {
+            //
+            // 5 bits per RGB component:
+            // 0111 1111 1111 1111 (binary)
+            //
+            return 0x7FFF;
+        } else if (colorDepth == 16) {
+            //
+            // 5 bits for red, 6 bits for green, 5 bits for green:
+            // 1111 1111 1111 1111 (binary)
+            //
+            return 0xFFFF;
+        } else if (colorDepth == 24) {
+            //
+            // 8 bits per RGB component:
+            // 1111 1111 1111 1111 1111 1111 (binary)
+            //
+            return 0xFFFFFF;
+        } else
+            throw new RuntimeException("Unsupported color depth.");
+    }
+
+    /**
+     * Extract the run length of a compression order.
+     */
+    private static int extractRunLength(int code, int orderHeader, ByteBuffer srcBuf) {
+        switch (code) {
+        case REGULAR_FGBG_IMAGE: {
+            int runLength = orderHeader & g_MaskRegularRunLength;
+            if (runLength == 0)
+                runLength = srcBuf.readUnsignedByte() + 1;
+            else
+                runLength = runLength * 8;
+            return runLength;
+        }
+        case LITE_SET_FG_FGBG_IMAGE: {
+            int runLength = orderHeader & g_MaskLiteRunLength;
+            if (runLength == 0)
+                runLength = srcBuf.readUnsignedByte() + 1;
+            else
+                runLength = runLength * 8;
+            return runLength;
+        }
+        case REGULAR_BG_RUN:
+        case REGULAR_COLOR_IMAGE:
+        case REGULAR_COLOR_RUN:
+        case REGULAR_FG_RUN: {
+            int runLength = orderHeader & g_MaskRegularRunLength;
+            if (runLength == 0)
+                // An extended (MEGA) run.
+                runLength = srcBuf.readUnsignedByte() + 32;
+            return runLength;
+        }
+        case LITE_DITHERED_RUN:
+        case LITE_SET_FG_FG_RUN: {
+            int runLength = orderHeader & g_MaskLiteRunLength;
+            if (runLength == 0)
+                // An extended (MEGA) run.
+                runLength = srcBuf.readUnsignedByte() + 16;
+            return runLength;
+        }
+        case MEGA_MEGA_BG_RUN:
+        case MEGA_MEGA_COLOR_IMAGE:
+        case MEGA_MEGA_COLOR_RUN:
+        case MEGA_MEGA_DITHERED_RUN:
+        case MEGA_MEGA_FG_RUN:
+        case MEGA_MEGA_FGBG_IMAGE:
+        case MEGA_MEGA_SET_FG_RUN:
+        case MEGA_MEGA_SET_FGBG_IMAGE: {
+            return srcBuf.readUnsignedShortLE();
+        }
+        default:
+            return 0;
+        }
+
+    }
+
+    /**
+     * Write a foreground/background image to a destination buffer.
+     */
+    private static void writeFgBgImage(int bpp, ByteBuffer destBuf, int rowDelta, int bitmask, int fgPel, int cBits) {
+        for (; cBits > 0; cBits--, bitmask >>= 1) {
+            int xorPixel = peekPixel(bpp, destBuf, -rowDelta);
+            writePixel(bpp, destBuf, ((bitmask & 0x1) > 0) ? xorPixel ^ fgPel : xorPixel);
+        }
+    }
+
+    /**
+     * Write a foreground/background image to a destination buffer for the first
+     * line of compressed data.
+     */
+    private static void writeFirstLineFgBgImage(int bpp, ByteBuffer destBuf, int bitmask, int fgPel, int cBits) {
+        for (; cBits > 0; cBits--, bitmask >>= 1) {
+            writePixel(bpp, destBuf, ((bitmask & 0x1) > 0) ? fgPel : getColorBlack());
+        }
+    }
+
+    /**
+     * Decompress a RLE compressed bitmap and flip decompressed image.
+     * 
+     * @param srcBuf
+     *          source buffer containing compressed bitmap
+     * @param imageWidth
+     *          width of destination image in pixels
+     * @param imageHeight
+     *          height of destination image in pixels
+     * @param colorDepth
+     *          bits per pixel
+     * @return destination image buffer
+     */
+    public static ByteBuffer rleDecompress(ByteBuffer srcBuf, int imageWidth, int imageHeight, int colorDepth) {
+        int bpp = getPixelSize(colorDepth);
+
+        // Decompress image
+        ByteBuffer destBuf = new ByteBuffer(new byte[imageWidth * imageHeight * bpp]);
+        rleDecompress(srcBuf, destBuf, imageWidth, imageHeight, colorDepth);
+
+        // Flip image
+        return flipRawImage(destBuf, imageWidth, imageHeight, bpp);
+    }
+
+    /**
+     * Decompress a RLE compressed bitmap.
+     * 
+     * @param srcBuf
+     *          source buffer containing compressed bitmap
+     * @param destBuf
+     *          destination buffer
+     * @param imageWidth
+     *          width of destination image in pixels
+     * @param imageHeight
+     *          height of destination image in pixels
+     * @param colorDepth
+     *          bits per pixel
+     */
+    protected static void rleDecompress(final ByteBuffer srcBuf, final ByteBuffer destBuf, final int imageWidth, final int imageHeight, final int colorDepth) {
+        final int bpp = getPixelSize(colorDepth);
+        final int rowDelta = imageWidth * bpp;
+        final int whitePixel = getColorWhite(colorDepth);
+        final int blackPixel = getColorBlack();
+
+        int fgPel = whitePixel;
+        boolean insertFgPel = false;
+        boolean firstLine = true;
+
+        if (destBuf.length != imageWidth * imageHeight * bpp)
+            throw new RuntimeException("Incorrect size of destination buffer. Expected size (imageWidth*imageHeight*bpp): " + (imageWidth * imageHeight * bpp)
+                    + ", actual size: " + destBuf.length + ".");
+
+        while (srcBuf.cursor < srcBuf.length) {
+            // Watch out for the end of the first scanline in destination buffer.
+            if (firstLine) {
+                if (destBuf.cursor >= rowDelta) {
+                    firstLine = false;
+                    insertFgPel = false;
+                }
+            }
+
+            // Extract the compression order code ID from the compression
+            // order header.
+            int orderHeader = srcBuf.readUnsignedByte();
+            int code = extractCodeId(orderHeader);
+
+            // Handle Background Run Orders.
+            if (code == REGULAR_BG_RUN | code == MEGA_MEGA_BG_RUN) {
+                int runLength = extractRunLength(code, orderHeader, srcBuf);
+
+                if (firstLine) {
+                    if (insertFgPel) {
+                        writePixel(bpp, destBuf, fgPel);
+                        runLength--;
+                    }
+
+                    for (; runLength > 0; runLength--)
+                        writePixel(bpp, destBuf, blackPixel);
+
+                } else {
+                    if (insertFgPel) {
+                        writePixel(bpp, destBuf, peekPixel(bpp, destBuf, -rowDelta) ^ fgPel);
+                        runLength--;
+                    }
+
+                    // Copy pixels from previous row of destination image
+                    for (; runLength > 0; runLength--)
+                        writePixel(bpp, destBuf, peekPixel(bpp, destBuf, -rowDelta));
+                }
+
+                //
+                // A follow-on background run order will need a
+                // foreground pel inserted.
+                //
+                insertFgPel = true;
+                continue;
+            }
+
+            //
+            // For any of the other run-types a follow-on background run
+            // order does not need a foreground pel inserted.
+            //
+            insertFgPel = false;
+
+            //
+            // Handle Foreground Run Orders.
+            //
+            if (code == REGULAR_FG_RUN | code == MEGA_MEGA_FG_RUN | code == LITE_SET_FG_FG_RUN | code == MEGA_MEGA_SET_FG_RUN) {
+                int runLength = extractRunLength(code, orderHeader, srcBuf);
+
+                if (code == LITE_SET_FG_FG_RUN | code == MEGA_MEGA_SET_FG_RUN)
+                    fgPel = readPixel(bpp, srcBuf);
+
+                if (firstLine) {
+                    for (; runLength > 0; runLength--) {
+                        writePixel(bpp, destBuf, fgPel);
+                    }
+                } else {
+                    for (; runLength > 0; runLength--) {
+                        writePixel(bpp, destBuf, peekPixel(bpp, destBuf, -rowDelta) ^ fgPel);
+                    }
+                }
+
+                continue;
+            }
+
+            //
+            // Handle Dithered Run Orders.
+            //
+            if (code == LITE_DITHERED_RUN | code == MEGA_MEGA_DITHERED_RUN) {
+                int runLength = extractRunLength(code, orderHeader, srcBuf);
+
+                int pixelA = readPixel(bpp, srcBuf);
+                int pixelB = readPixel(bpp, srcBuf);
+
+                for (; runLength > 0; runLength--) {
+                    writePixel(bpp, destBuf, pixelA);
+                    writePixel(bpp, destBuf, pixelB);
+                }
+
+                continue;
+            }
+
+            //
+            // Handle Color Run Orders.
+            //
+            if (code == REGULAR_COLOR_RUN | code == MEGA_MEGA_COLOR_RUN) {
+                int runLength = extractRunLength(code, orderHeader, srcBuf);
+
+                int pixelA = readPixel(bpp, srcBuf);
+
+                for (; runLength > 0; runLength--)
+                    writePixel(bpp, destBuf, pixelA);
+
+                continue;
+            }
+
+            //
+            // Handle Foreground/Background Image Orders.
+            //
+            if (code == REGULAR_FGBG_IMAGE | code == MEGA_MEGA_FGBG_IMAGE | code == LITE_SET_FG_FGBG_IMAGE | code == MEGA_MEGA_SET_FGBG_IMAGE) {
+                int runLength = extractRunLength(code, orderHeader, srcBuf);
+
+                if (code == LITE_SET_FG_FGBG_IMAGE | code == MEGA_MEGA_SET_FGBG_IMAGE) {
+                    fgPel = readPixel(bpp, srcBuf);
+                }
+
+                for (; runLength > 8; runLength -= 8) {
+                    int bitmask = srcBuf.readUnsignedByte();
+
+                    if (firstLine)
+                        writeFirstLineFgBgImage(bpp, destBuf, bitmask, fgPel, 8);
+                    else
+                        writeFgBgImage(bpp, destBuf, rowDelta, bitmask, fgPel, 8);
+                }
+
+                if (runLength > 0) {
+                    int bitmask = srcBuf.readUnsignedByte();
+
+                    if (firstLine)
+                        writeFirstLineFgBgImage(bpp, destBuf, bitmask, fgPel, runLength);
+                    else
+                        writeFgBgImage(bpp, destBuf, rowDelta, bitmask, fgPel, runLength);
+                }
+
+                continue;
+            }
+
+            //
+            // Handle Color Image Orders.
+            //
+            if (code == REGULAR_COLOR_IMAGE | code == MEGA_MEGA_COLOR_IMAGE) {
+                int runLength = extractRunLength(code, orderHeader, srcBuf);
+
+                //* DEBUG */
+                // Copy bytes from source to destination using writeByte(readByte())
+                // for (int byteCount = runLength * bpp; byteCount > 0; byteCount--) {
+                // destBuf.writeByte(srcBuf.readUnsignedByte());
+                // }
+                //* DEBUG */
+
+                // Copy bytes from source to destination directly using arraycopy()
+                int lengthInBytes = runLength * bpp;
+                System.arraycopy(srcBuf.data, srcBuf.offset + srcBuf.cursor, destBuf.data, destBuf.offset + destBuf.cursor, lengthInBytes);
+                srcBuf.cursor += lengthInBytes;
+                destBuf.cursor += lengthInBytes;
+
+                continue;
+            }
+
+            //
+            // Handle Special Order 1.
+            //
+            if (code == SPECIAL_FGBG_1) {
+                if (firstLine)
+                    writeFirstLineFgBgImage(bpp, destBuf, g_MaskSpecialFgBg1, fgPel, 8);
+                else
+                    writeFgBgImage(bpp, destBuf, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
+
+                continue;
+            }
+
+            //
+            // Handle Special Order 2.
+            //
+            if (code == SPECIAL_FGBG_2) {
+                if (firstLine)
+                    writeFirstLineFgBgImage(bpp, destBuf, g_MaskSpecialFgBg2, fgPel, 8);
+                else
+                    writeFgBgImage(bpp, destBuf, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
+
+                continue;
+            }
+
+            //
+            // Handle White Order.
+            //
+            if (code == SPECIAL_WHITE) {
+                writePixel(bpp, destBuf, whitePixel);
+
+                continue;
+            }
+
+            //
+            // Handle Black Order.
+            //
+            if (code == SPECIAL_BLACK) {
+                writePixel(bpp, destBuf, blackPixel);
+
+                continue;
+            }
+
+            throw new RuntimeException("Unknown code: " + code + ".");
+        }
+    }
+
+    /**
+     * Flip image in vertical direction.
+     */
+    public static ByteBuffer flipRawImage(ByteBuffer src, int width, int height, int bpp) {
+        if (width * height * bpp != src.length)
+            throw new RuntimeException("Incorrect size of buffer. Expected size (imageWidth*imageHeight*bpp): " + (width * height * bpp) + ", actual size: "
+                    + src.length + ".");
+        ByteBuffer dest = new ByteBuffer(new byte[src.length]);
+
+        int scanLine = width * bpp;
+
+        for (int i = 0; i < height; i++) {
+            // Copy one row
+            System.arraycopy(src.data, (height - i - 1) * scanLine, dest.data, i * scanLine, scanLine);
+        }
+
+        return dest;
+
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        if (true) {
+            // 16x1@8bpp, all black
+            int width = 16, height = 1, depth = 8, bpp = depth / 8;
+            ByteBuffer src = new ByteBuffer(new byte[] {0x10});
+            ByteBuffer dest = new AssertingByteBuffer(new byte[width * height * bpp]);
+            rleDecompress(src, dest, width, height, depth);
+        }
+
+        if (true) {
+            // 16x1@16bpp, all black
+            int width = 16, height = 1, depth = 16, bpp = depth / 8;
+            ByteBuffer src = new ByteBuffer(new byte[] {0x0c, (byte)0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
+            ByteBuffer dest = new AssertingByteBuffer(new byte[width * height * bpp]);
+            rleDecompress(src, dest, width, height, depth);
+        }
+
+        if (true) {
+            // 32x32@8
+            int width = 32, height = 32, depth = 8, bpp = depth / 8;
+
+            ByteBuffer src = new ByteBuffer(new byte[] {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0x06, (byte)0x06,
+                    (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xec, (byte)0x6c, (byte)0x0e,
+                    (byte)0x0e, (byte)0x44, (byte)0x0e, (byte)0x0e, (byte)0x0e, (byte)0x13, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06,
+                    (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xe4, (byte)0x04, (byte)0x06,
+                    (byte)0x8e, (byte)0x60, (byte)0x0e, (byte)0x60, (byte)0x8c, (byte)0xb4, (byte)0xb5, (byte)0xdc, (byte)0xdc, (byte)0xbb, (byte)0xb4,
+                    (byte)0x8c, (byte)0x66, (byte)0x0b, (byte)0x6c, (byte)0xe4, (byte)0x04, (byte)0x06, (byte)0x02, (byte)0x8b, (byte)0x06, (byte)0x06,
+                    (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xf8, (byte)0x0e, (byte)0x66, (byte)0xb4, (byte)0xdc, (byte)0x68, (byte)0xe2,
+                    (byte)0x97, (byte)0xdd, (byte)0xb4, (byte)0xa7, (byte)0x16, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed,
+                    (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x0b, (byte)0xae,
+                    (byte)0xdc, (byte)0xe9, (byte)0x6a, (byte)0xdc, (byte)0x96, (byte)0xe9, (byte)0xe9, (byte)0xb4, (byte)0x0e, (byte)0x00, (byte)0x06,
+                    (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06,
+                    (byte)0x0e, (byte)0xae, (byte)0xdc, (byte)0xdb, (byte)0xdb, (byte)0xd0, (byte)0x09, (byte)0x07, (byte)0xcf, (byte)0x03, (byte)0x95,
+                    (byte)0xdb, (byte)0xdb, (byte)0xdc, (byte)0xb4, (byte)0x66, (byte)0x6c, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00,
+                    (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x0b, (byte)0xae, (byte)0xdb, (byte)0xd4, (byte)0xd5, (byte)0x6c,
+                    (byte)0xdb, (byte)0x80, (byte)0xaf, (byte)0xd5, (byte)0xd4, (byte)0xdb, (byte)0xb4, (byte)0x66, (byte)0x04, (byte)0x06, (byte)0x04,
+                    (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x66, (byte)0xae, (byte)0xd5, (byte)0xad, (byte)0xd4,
+                    (byte)0xd4, (byte)0xd5, (byte)0xd5, (byte)0xd5, (byte)0xdb, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xd5,
+                    (byte)0xd5, (byte)0xd5, (byte)0xd4, (byte)0xd4, (byte)0xad, (byte)0xd5, (byte)0xb4, (byte)0x0e, (byte)0x06, (byte)0x06, (byte)0x06,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x60, (byte)0xa7, (byte)0xb4, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb3,
+                    (byte)0xb3, (byte)0xd4, (byte)0xd4, (byte)0xb3, (byte)0x8c, (byte)0xb6, (byte)0x07, (byte)0xb6, (byte)0x8c, (byte)0xb3, (byte)0xd4,
+                    (byte)0xb3, (byte)0xb3, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb4, (byte)0xad, (byte)0x66, (byte)0x00, (byte)0x06, (byte)0x00,
+                    (byte)0x00, (byte)0x06, (byte)0x06, (byte)0x66, (byte)0xae, (byte)0xad, (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad,
+                    (byte)0xad, (byte)0xb3, (byte)0xad, (byte)0xb5, (byte)0x07, (byte)0x07, (byte)0x07, (byte)0xf0, (byte)0x8b, (byte)0xad, (byte)0xad,
+                    (byte)0xad, (byte)0xad, (byte)0xad, (byte)0x8b, (byte)0xa7, (byte)0xae, (byte)0xa7, (byte)0x6c, (byte)0x06, (byte)0x00, (byte)0x00,
+                    (byte)0x04, (byte)0x6c, (byte)0xa7, (byte)0xad, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad,
+                    (byte)0xad, (byte)0xad, (byte)0xb5, (byte)0xbd, (byte)0xbd, (byte)0xbd, (byte)0xbd, (byte)0xf0, (byte)0x8b, (byte)0x8b, (byte)0xad,
+                    (byte)0x8b, (byte)0x8b, (byte)0xa7, (byte)0xa7, (byte)0xc8, (byte)0xc8, (byte)0x60, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06,
+                    (byte)0x66, (byte)0xc8, (byte)0xa7, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0xad,
+                    (byte)0x8b, (byte)0x92, (byte)0xf1, (byte)0xf1, (byte)0xf1, (byte)0xf1, (byte)0xf2, (byte)0x07, (byte)0xa7, (byte)0xa7, (byte)0x8b,
+                    (byte)0xa7, (byte)0xa7, (byte)0x66, (byte)0x66, (byte)0xc8, (byte)0x66, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x60,
+                    (byte)0xa7, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0x8b, (byte)0x8b,
+                    (byte)0xa7, (byte)0xb6, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0x07, (byte)0x66, (byte)0xa7, (byte)0xa7,
+                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x6c, (byte)0x04, (byte)0xa7,
+                    (byte)0x60, (byte)0x6b, (byte)0x66, (byte)0x99, (byte)0xb6, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xef,
+                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x60,
+                    (byte)0xa7, (byte)0x66, (byte)0x60, (byte)0x66, (byte)0x66, (byte)0x8c, (byte)0xf1, (byte)0x6e, (byte)0xff, (byte)0x85, (byte)0xbd,
+                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x60, (byte)0x05, (byte)0x87, (byte)0x13, (byte)0x04, (byte)0x66, (byte)0x66, (byte)0x66,
+                    (byte)0x66, (byte)0xf4, (byte)0x70, (byte)0xff, (byte)0x84, (byte)0xbd, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x05, (byte)0x85,
+                    (byte)0x0b, (byte)0xa7, (byte)0xb5, (byte)0xae, (byte)0x8c, (byte)0xd0, (byte)0x13, (byte)0xc1, (byte)0x01, (byte)0x00, (byte)0x08,
+                    (byte)0x8e, (byte)0x8c, (byte)0xae, (byte)0xb5, (byte)0xae, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x6c, (byte)0xae, (byte)0xbc,
+                    (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xb5, (byte)0xd0, (byte)0x0e, (byte)0x0c, (byte)0x01, (byte)0x00, (byte)0x90, (byte)0xf2,
+                    (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xbc, (byte)0xb5, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0xae,
+                    (byte)0x0a, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x68, (byte)0xae, (byte)0x82, (byte)0x8c, (byte)0x0a, (byte)0x05, (byte)0x8c,
+                    (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xbc, (byte)0xb5, (byte)0x6c, (byte)0x00, (byte)0x00,
+                    (byte)0x06, (byte)0x05, (byte)0x81, (byte)0xd0, (byte)0x06, (byte)0x9a, (byte)0x8c, (byte)0x0a, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x0a, (byte)0xb5,
+                    (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x8b, (byte)0x0a, (byte)0xbc, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x06,
+                    (byte)0x9b, (byte)0xb6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xae,
+                    (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0x0a, (byte)0x8c, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x6c,
+                    (byte)0xb5, (byte)0x0a, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x05, (byte)0x80, (byte)0x7d, (byte)0xbc, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6,
+                    (byte)0x0a, (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x87, (byte)0x0a, (byte)0xbc,
+                    (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb6, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xf2, (byte)0xd0, (byte)0xae, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xbc, (byte)0x1a,
+                    (byte)0xb5, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xed, (byte)0x06, (byte)0x6e, (byte)0xb5, (byte)0x0a, (byte)0xbc,
+                    (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xd0, (byte)0xd0, (byte)0xb5, (byte)0xf4, (byte)0xff, (byte)0xf2,
+                    (byte)0xd0, (byte)0xd0, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xbc, (byte)0x0a, (byte)0x0a, (byte)0x8b,
+                    (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x8b, (byte)0xbc, (byte)0x1a, (byte)0x0a,
+                    (byte)0xb6, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5,
+                    (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xb6, (byte)0x0a, (byte)0xde, (byte)0x0a, (byte)0xa7, (byte)0x06, (byte)0x00,
+                    (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x8b, (byte)0xbc, (byte)0xf2, (byte)0x0a,
+                    (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6,
+                    (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0x0a, (byte)0xf2, (byte)0x1a, (byte)0x8c, (byte)0xec, (byte)0x06, (byte)0x06, (byte)0x06,
+                    (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0xa7, (byte)0xbc, (byte)0x1a, (byte)0x0a,
+                    (byte)0x0a, (byte)0x6a, (byte)0xb6, (byte)0x96, (byte)0x0a, (byte)0x0a, (byte)0xf2, (byte)0x0a, (byte)0x87, (byte)0x06, (byte)0x04,
+                    (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06,
+                    (byte)0x8c, (byte)0xb6, (byte)0xf4, (byte)0xf2, (byte)0xd0, (byte)0x09, (byte)0xbc, (byte)0x87, (byte)0x03, (byte)0x80, (byte)0x2c,
+                    (byte)0xde, (byte)0xf4, (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x6c, (byte)0x87, (byte)0x0a,
+                    (byte)0xf4, (byte)0xf4, (byte)0xf2, (byte)0xde, (byte)0xbd, (byte)0xbd, (byte)0xde, (byte)0xf2, (byte)0xf4, (byte)0xf4, (byte)0x0a,
+                    (byte)0xd0, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00,
+                    (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x6c, (byte)0x8c,
+                    (byte)0xb5, (byte)0xbc, (byte)0x0a, (byte)0xde, (byte)0xf2, (byte)0xbd, (byte)0x0a, (byte)0xb5, (byte)0x8c, (byte)0x6c, (byte)0x06,
+                    (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xe6,
+                    (byte)0x04, (byte)0x06, (byte)0x86, (byte)0x04, (byte)0x6c, (byte)0x04, (byte)0x8b, (byte)0x04, (byte)0x6c, (byte)0xe6, (byte)0x04,
+                    (byte)0x06, (byte)0x82, (byte)0x00, (byte)0x00
+
+            });
+
+            ByteBuffer flippedImage = new ByteBuffer(new byte[] {(byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04,
+                    (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x6c, (byte)0x04, (byte)0x8b, (byte)0x04, (byte)0x6c,
+                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04,
+                    (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06,
+                    (byte)0x06, (byte)0x6c, (byte)0x8c, (byte)0xb5, (byte)0xbc, (byte)0x0a, (byte)0xde, (byte)0xf2, (byte)0xbd, (byte)0x0a, (byte)0xb5,
+                    (byte)0x8c, (byte)0x6c, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x6c, (byte)0x87,
+                    (byte)0x0a, (byte)0xf4, (byte)0xf4, (byte)0xf2, (byte)0xde, (byte)0xbd, (byte)0xbd, (byte)0xde, (byte)0xf2, (byte)0xf4, (byte)0xf4,
+                    (byte)0x0a, (byte)0xd0, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00,
+                    (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x8c, (byte)0xb6, (byte)0xf4, (byte)0xf2,
+                    (byte)0x0a, (byte)0x0a, (byte)0x0a, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0x0a, (byte)0x0a, (byte)0x0a, (byte)0xde,
+                    (byte)0xf4, (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x00, (byte)0x00,
+                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0xa7, (byte)0xbc, (byte)0x1a, (byte)0x0a, (byte)0x0a, (byte)0xb6,
+                    (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0x0a, (byte)0x0a,
+                    (byte)0xf2, (byte)0x0a, (byte)0x87, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06,
+                    (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x8b, (byte)0xbc, (byte)0xf2, (byte)0x0a, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6,
+                    (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0x0a,
+                    (byte)0xf2, (byte)0x1a, (byte)0x8c, (byte)0xec, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06,
+                    (byte)0x04, (byte)0x8b, (byte)0xbc, (byte)0x1a, (byte)0x0a, (byte)0xb6, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5,
+                    (byte)0xb5, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xb6, (byte)0x0a,
+                    (byte)0xde, (byte)0x0a, (byte)0xa7, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xed, (byte)0x06, (byte)0x6e,
+                    (byte)0xb5, (byte)0x0a, (byte)0xbc, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xd0, (byte)0xd0, (byte)0xb5,
+                    (byte)0xf4, (byte)0xff, (byte)0xf2, (byte)0xd0, (byte)0xd0, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xbc,
+                    (byte)0x0a, (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x87, (byte)0x0a,
+                    (byte)0xbc, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb6, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xd0, (byte)0xae, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xbc,
+                    (byte)0x1a, (byte)0xb5, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x6c, (byte)0xb5, (byte)0x0a, (byte)0xb6,
+                    (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xbc, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0x0a,
+                    (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x8b, (byte)0x0a, (byte)0xbc, (byte)0xb5, (byte)0xb5,
+                    (byte)0xb5, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb6, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0x0a,
+                    (byte)0x8c, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0xae, (byte)0x0a, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0,
+                    (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0x8c, (byte)0x0a, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x0a, (byte)0xb5,
+                    (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0xae, (byte)0x0a, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xae,
+                    (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0x8c, (byte)0x0a, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xbc, (byte)0xb5, (byte)0x6c,
+                    (byte)0x00, (byte)0x00, (byte)0x6c, (byte)0xae, (byte)0xbc, (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xb5, (byte)0xf3, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xbc, (byte)0xb5, (byte)0x66, (byte)0x00,
+                    (byte)0x00, (byte)0x0b, (byte)0xa7, (byte)0xb5, (byte)0xae, (byte)0x8c, (byte)0xa7, (byte)0xf4, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xbd, (byte)0xa7, (byte)0x8c, (byte)0xae, (byte)0xb5, (byte)0xae, (byte)0x66, (byte)0x00, (byte)0x00,
+                    (byte)0x13, (byte)0x04, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xf4, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xbd, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x60,
+                    (byte)0xa7, (byte)0x66, (byte)0x60, (byte)0x66, (byte)0x66, (byte)0x8c, (byte)0xf1, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xbd,
+                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x60, (byte)0x66, (byte)0xa7, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x6c, (byte)0x04,
+                    (byte)0xa7, (byte)0x60, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66,
+                    (byte)0x66, (byte)0x66, (byte)0xb6, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xef, (byte)0x66, (byte)0x66,
+                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x60, (byte)0xa7,
+                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0xa7,
+                    (byte)0xb6, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0x07, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x66,
+                    (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x66, (byte)0xc8, (byte)0xa7,
+                    (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0xad, (byte)0x8b, (byte)0x92, (byte)0xf1,
+                    (byte)0xf1, (byte)0xf1, (byte)0xf1, (byte)0xf2, (byte)0x07, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0xa7, (byte)0xa7, (byte)0x66,
+                    (byte)0x66, (byte)0xc8, (byte)0x66, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x6c, (byte)0xa7, (byte)0xad, (byte)0xa7,
+                    (byte)0xa7, (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb5, (byte)0xbd, (byte)0xbd,
+                    (byte)0xbd, (byte)0xbd, (byte)0xf0, (byte)0x8b, (byte)0x8b, (byte)0xad, (byte)0x8b, (byte)0x8b, (byte)0xa7, (byte)0xa7, (byte)0xc8,
+                    (byte)0xc8, (byte)0x60, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0x66, (byte)0xae, (byte)0xad, (byte)0x8b,
+                    (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb3, (byte)0xad, (byte)0xb5, (byte)0x07, (byte)0x07, (byte)0x07,
+                    (byte)0xf0, (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0x8b, (byte)0xa7, (byte)0xae, (byte)0xa7,
+                    (byte)0x6c, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x60, (byte)0xa7, (byte)0xb4, (byte)0xad, (byte)0xad,
+                    (byte)0xad, (byte)0xb3, (byte)0xb3, (byte)0xd4, (byte)0xd4, (byte)0xb3, (byte)0x8c, (byte)0xb6, (byte)0x07, (byte)0xb6, (byte)0x8c,
+                    (byte)0xb3, (byte)0xd4, (byte)0xb3, (byte)0xb3, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb4, (byte)0xad, (byte)0x66, (byte)0x00,
+                    (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x66, (byte)0xae, (byte)0xd5, (byte)0xad, (byte)0xd4,
+                    (byte)0xd4, (byte)0xd5, (byte)0xd5, (byte)0xd5, (byte)0xdb, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xd5,
+                    (byte)0xd5, (byte)0xd5, (byte)0xd4, (byte)0xd4, (byte)0xad, (byte)0xd5, (byte)0xb4, (byte)0x0e, (byte)0x06, (byte)0x06, (byte)0x06,
+                    (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x0b, (byte)0xae, (byte)0xdb, (byte)0xd4, (byte)0xd5,
+                    (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb,
+                    (byte)0xdb, (byte)0xd5, (byte)0xd4, (byte)0xdb, (byte)0xb4, (byte)0x66, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00,
+                    (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x0e, (byte)0xae, (byte)0xdc, (byte)0xdb, (byte)0xdb,
+                    (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdc, (byte)0xdc, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb,
+                    (byte)0xdb, (byte)0xdc, (byte)0xb4, (byte)0x66, (byte)0x6c, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x0b, (byte)0xae, (byte)0xdc, (byte)0xe9, (byte)0xdc,
+                    (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xe9, (byte)0xe9,
+                    (byte)0xb4, (byte)0x0e, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06,
+                    (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xf8, (byte)0x0e, (byte)0x66, (byte)0xb4, (byte)0xdc, (byte)0xe2,
+                    (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xdd, (byte)0xb4, (byte)0xa7, (byte)0x16,
+                    (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06,
+                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x60, (byte)0x0e, (byte)0x60, (byte)0x8c, (byte)0xb4,
+                    (byte)0xb5, (byte)0xdc, (byte)0xdc, (byte)0xbb, (byte)0xb4, (byte)0x8c, (byte)0x66, (byte)0x0b, (byte)0x6c, (byte)0x04, (byte)0x06,
+                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed,
+                    (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xec, (byte)0x6c, (byte)0x0e, (byte)0x0e,
+                    (byte)0x44, (byte)0x0e, (byte)0x0e, (byte)0x0e, (byte)0x13, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06,
+                    (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00});
+            ByteBuffer dest = new AssertingByteBuffer(flipRawImage(flippedImage, width, height, bpp).data);
+
+            rleDecompress(src, dest, width, height, depth);
+
+        }
+
+        if (true) {
+            // 32x32@16
+            int width = 32, height = 32, depth = 16;
+
+            ByteBuffer src = new ByteBuffer(new byte[] {(byte)0x85, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x06, (byte)0x8b, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x06, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0x16, (byte)0x69, (byte)0x99, (byte)0xd6, (byte)0x06, (byte)0x69, (byte)0x99,
+                    (byte)0xd6, (byte)0x04, (byte)0xcc, (byte)0x89, (byte)0x52, (byte)0x03, (byte)0x6e, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x6e,
+                    (byte)0x08, (byte)0x42, (byte)0x01, (byte)0x70, (byte)0x08, (byte)0x42, (byte)0x71, (byte)0xff, (byte)0xff, (byte)0xce, (byte)0x18,
+                    (byte)0xc6, (byte)0x01, (byte)0x81, (byte)0x08, (byte)0x42, (byte)0xce, (byte)0x66, (byte)0x29, (byte)0x02, (byte)0xcd, (byte)0x89,
+                    (byte)0x52, (byte)0x03, (byte)0x88, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xd8, (byte)0x99, (byte)0xd6,
+                    (byte)0x03, (byte)0xf8, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xf0, (byte)0x66, (byte)0x99, (byte)0xd6,
+                    (byte)0x05, (byte)0x6a, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0xc4, (byte)0xcc, (byte)0x89, (byte)0x52, (byte)0x03, (byte)0x6e,
+                    (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x6e, (byte)0x08, (byte)0x42, (byte)0x01, (byte)0x70, (byte)0x08, (byte)0x42, (byte)0x71,
+                    (byte)0xff, (byte)0xff, (byte)0xce, (byte)0x18, (byte)0xc6, (byte)0x01, (byte)0x81, (byte)0x08, (byte)0x42, (byte)0xce, (byte)0x66,
+                    (byte)0x29, (byte)0x02, (byte)0xcd, (byte)0x89, (byte)0x52, (byte)0x03, (byte)0x00, (byte)0x04, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0xc3, (byte)0x80, (byte)0x61, (byte)0x00, (byte)0xa5, (byte)0x80, (byte)0x40, (byte)0xec, (byte)0x52, (byte)0x00, (byte)0x5a,
+                    (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x24, (byte)0x00, (byte)0x12, (byte)0x00, (byte)0x24, (byte)0x00, (byte)0x12, (byte)0x00,
+                    (byte)0x5a, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0xa5, (byte)0x80, (byte)0x52, (byte)0x00, (byte)0xc3, (byte)0x80, (byte)0x61,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xcc, (byte)0x89, (byte)0x52, (byte)0x03, (byte)0x6e, (byte)0xff,
+                    (byte)0xff, (byte)0x02, (byte)0xcb, (byte)0x18, (byte)0xc6, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0xff, (byte)0xff,});
+
+            ByteBuffer dest = new AssertingByteBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
+                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84,
+                    (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
+                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff, (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84,
+                    (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
+                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84,
+                    (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
+                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10,
+                    (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
+                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84,
+                    (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x99,
+                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff,
+                    (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84,
+                    (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
+                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
+                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10,
+                    (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
+                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84,
+                    (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff, (byte)0xff,});
+
+            rleDecompress(src, dest, width, height, depth);
+
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpConstants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpConstants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpConstants.java
new file mode 100755
index 0000000..3fc5df8
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpConstants.java
@@ -0,0 +1,91 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import java.nio.charset.Charset;
+
+public interface RdpConstants {
+
+    /**
+     * Default charset to use when communicating with server using 8 bit strings.
+     */
+    public static final Charset CHARSET_8 = Charset.availableCharsets().get("US-ASCII");
+
+    /**
+     * Default charset to use when communicating with server using 16 bit strings.
+     */
+    public static final Charset CHARSET_16 = Charset.availableCharsets().get("UTF-16LE");
+
+    /**
+     * Negotiate SSL protocol to use to protect RDP connection.
+     * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx 
+     */
+    public static final int RDP_NEG_REQ_PROTOCOL_SSL = 1;
+
+    /**
+     * Negotiate CredSSP protocol to use to protect RDP connection.
+     * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx 
+     * When used, client must set @see RDP_NEG_REQ_PROTOCOL_SSL too.
+     */
+    public static final int RDP_NEG_REQ_PROTOCOL_HYBRID = 2;
+
+    /**
+     * RDP negotiation: flags (not used, always 0).
+     */
+    public static final int RDP_NEG_REQ_FLAGS = 0;
+
+    /**
+     * RDP Negotiation: request.
+     */
+    public static final int RDP_NEG_REQ_TYPE_NEG_REQ = 1;
+
+    /**
+     * RDP Negotiation: response.
+     */
+    public static final int RDP_NEG_REQ_TYPE_NEG_RSP = 2;
+
+    /**
+     * RDP Negotiation: failure.
+     */
+    public static final int RDP_NEG_REQ_TYPE_NEG_FAILURE = 3;
+
+    /**
+     * I/O Channel.
+     */
+    public static final int CHANNEL_IO = 1003;
+
+    /**
+     * RDP channel.
+     */
+    public static final int CHANNEL_RDPRDR = 1004;
+
+    /**
+     * Clipboard channel.
+     */
+    public static final int CHANNEL_CLIPRDR = 1005;
+
+    /**
+     * RDP sound channel.
+     */
+    public static final int CHANNEL_RDPSND = 1006;
+
+    /**
+     * User channel.
+     */
+    public static final int CHANNEL_USER = 1007;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpState.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpState.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpState.java
new file mode 100755
index 0000000..1113d14
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpState.java
@@ -0,0 +1,33 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class RdpState {
+
+    public long serverShareId;
+    public int serverUserChannelId;
+
+    public Set<Integer> channels = new HashSet<Integer>();
+
+    public void channelJoined(int actualChannel) {
+        channels.add(actualChannel);
+    }
+
+}


[18/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RLEBitmapDecompression.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RLEBitmapDecompression.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RLEBitmapDecompression.java
deleted file mode 100644
index 53e6d2f..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RLEBitmapDecompression.java
+++ /dev/null
@@ -1,1014 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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 rdpclient;
-
-import streamer.AssertingByteBuffer;
-import streamer.ByteBuffer;
-
-/**
- * Based on code example from MSDN, @see
- * http://msdn.microsoft.com/en-us/library/dd240593.aspx .
- */
-public class RLEBitmapDecompression {
-
-  public static final int g_MaskRegularRunLength = 0x1F;
-  public static final int g_MaskLiteRunLength = 0x0F;
-
-  public static final int g_MaskSpecialFgBg1 = 0x03;
-  public static final int g_MaskSpecialFgBg2 = 0x05;
-
-  public static final int REGULAR_BG_RUN = 0x00;
-  public static final int REGULAR_FG_RUN = 0x01;
-  public static final int REGULAR_FGBG_IMAGE = 0x02;
-  public static final int REGULAR_COLOR_RUN = 0x03;
-  public static final int REGULAR_COLOR_IMAGE = 0x04;
-
-  public static final int LITE_SET_FG_FG_RUN = 0x0C;
-  public static final int LITE_SET_FG_FGBG_IMAGE = 0x0D;
-  public static final int LITE_DITHERED_RUN = 0x0E;
-
-  public static final int MEGA_MEGA_BG_RUN = 0xF0;
-  public static final int MEGA_MEGA_FG_RUN = 0xF1;
-  public static final int MEGA_MEGA_FGBG_IMAGE = 0xF2;
-  public static final int MEGA_MEGA_COLOR_RUN = 0xF3;
-  public static final int MEGA_MEGA_COLOR_IMAGE = 0xF4;
-  public static final int MEGA_MEGA_SET_FG_RUN = 0xF6;
-  public static final int MEGA_MEGA_SET_FGBG_IMAGE = 0xF7;
-  public static final int MEGA_MEGA_DITHERED_RUN = 0xF8;
-
-  public static final int SPECIAL_FGBG_1 = 0xF9;
-  public static final int SPECIAL_FGBG_2 = 0xFA;
-
-  public static final int SPECIAL_WHITE = 0xFD;
-  public static final int SPECIAL_BLACK = 0xFE;
-
-  /**
-   * Writes a pixel to the specified buffer and advance cursor by bpp.
-   * 
-   * @param bpp
-   *          bytes per pixel
-   */
-  private static void writePixel(int bpp, ByteBuffer destBuf, int pixel) {
-    switch (bpp) {
-    case 1:
-      destBuf.writeByte(pixel);
-      break;
-    case 2:
-      destBuf.writeShortLE(pixel);
-      break;
-    case 3:
-      destBuf.writeByte(pixel);
-      destBuf.writeShortLE(pixel >> 8);
-      break;
-    case 4:
-      destBuf.writeIntLE(pixel);
-      break;
-    default:
-      throw new RuntimeException("Unsupported color depth.");
-    }
-  }
-
-  /**
-   * Reads a pixel from the specified buffer at given offset without changing of
-   * cursor.
-   * 
-   * @param bpp
-   *          bytes per pixel
-   * @param offset
-   *          -rowDelta (i.e. (-width*bpp))
-   */
-  private static int peekPixel(int bpp, ByteBuffer destBuf, int offset) {
-    if (offset >= 0 || (-offset) > destBuf.cursor)
-      throw new RuntimeException("Incorrect value for offset: offset in destination buffer must point to pixel in previous row.");
-
-    // Adjust cursor to point to pixel in previous row
-    int oldCursor = destBuf.cursor;
-    destBuf.cursor += offset;
-
-    int pixel;
-    switch (bpp) {
-    case 1:
-      pixel = destBuf.readUnsignedByte();
-      break;
-    case 2:
-      pixel = destBuf.readUnsignedShortLE();
-      break;
-    case 3:
-      pixel = destBuf.readUnsignedByte() | (destBuf.readUnsignedShortLE() >> 8);
-      break;
-    case 4:
-      pixel = destBuf.readSignedIntLE();
-      break;
-    default:
-      throw new RuntimeException("Unsupported color depth.");
-    }
-    destBuf.cursor = oldCursor;
-
-    return pixel;
-  }
-
-  /**
-   * Reads a pixel from the specified buffer and advance cursor by bpp value.
-   * 
-   * @param bpp
-   *          bytes per pixel
-   */
-  private static int readPixel(int bpp, ByteBuffer srcBuf) {
-    int pixel;
-    switch (bpp) {
-    case 1:
-      pixel = srcBuf.readUnsignedByte();
-      break;
-    case 2:
-      pixel = srcBuf.readUnsignedShortLE();
-      break;
-    case 3:
-      pixel = srcBuf.readUnsignedByte() | (srcBuf.readUnsignedShortLE() >> 8);
-      break;
-    case 4:
-      pixel = srcBuf.readSignedIntLE();
-      break;
-    default:
-      throw new RuntimeException("Unsupported color depth.");
-    }
-
-    return pixel;
-  }
-
-  /**
-   * Returns the size of a pixel in bytes.
-   */
-  private static int getPixelSize(int colorDepth) {
-    switch (colorDepth) {
-    case 8:
-      return 1;
-    case 15:
-    case 16:
-      return 2;
-    case 24:
-      return 3;
-    default:
-      throw new RuntimeException("Unsupported pixel color depth: " + colorDepth + " bpp.");
-    }
-  }
-
-  /**
-   * Reads the supplied order header & extracts the compression order code ID.
-   */
-  private static int extractCodeId(int orderHeader) {
-    // Taken from FreeRDP code, bitmap.c
-    switch (orderHeader) {
-    case MEGA_MEGA_BG_RUN:
-    case MEGA_MEGA_FG_RUN:
-    case MEGA_MEGA_SET_FG_RUN:
-    case MEGA_MEGA_DITHERED_RUN:
-    case MEGA_MEGA_COLOR_RUN:
-    case MEGA_MEGA_FGBG_IMAGE:
-    case MEGA_MEGA_SET_FGBG_IMAGE:
-    case MEGA_MEGA_COLOR_IMAGE:
-    case SPECIAL_FGBG_1:
-    case SPECIAL_FGBG_2:
-    case SPECIAL_WHITE:
-    case SPECIAL_BLACK:
-      return orderHeader;
-    }
-
-    int code = orderHeader >> 5;
-    switch (code) {
-    case REGULAR_BG_RUN:
-    case REGULAR_FG_RUN:
-    case REGULAR_COLOR_RUN:
-    case REGULAR_FGBG_IMAGE:
-    case REGULAR_COLOR_IMAGE:
-      return code;
-    }
-
-    return orderHeader >> 4;
-  }
-
-  /**
-   * Returns a black pixel.
-   */
-  private static int getColorBlack() {
-    return 0x000000;
-  }
-
-  /**
-   * Returns a white pixel.
-   */
-  private static int getColorWhite(int colorDepth) {
-    if (colorDepth == 8) {
-      //
-      // Palette entry #255 holds white.
-      //
-      return 0xFF;
-    } else if (colorDepth == 15) {
-      //
-      // 5 bits per RGB component:
-      // 0111 1111 1111 1111 (binary)
-      //
-      return 0x7FFF;
-    } else if (colorDepth == 16) {
-      //
-      // 5 bits for red, 6 bits for green, 5 bits for green:
-      // 1111 1111 1111 1111 (binary)
-      //
-      return 0xFFFF;
-    } else if (colorDepth == 24) {
-      //
-      // 8 bits per RGB component:
-      // 1111 1111 1111 1111 1111 1111 (binary)
-      //
-      return 0xFFFFFF;
-    } else
-      throw new RuntimeException("Unsupported color depth.");
-  }
-
-  /**
-   * Extract the run length of a compression order.
-   */
-  private static int extractRunLength(int code, int orderHeader, ByteBuffer srcBuf) {
-    switch (code) {
-    case REGULAR_FGBG_IMAGE: {
-      int runLength = orderHeader & g_MaskRegularRunLength;
-      if (runLength == 0)
-        runLength = srcBuf.readUnsignedByte() + 1;
-      else
-        runLength = runLength * 8;
-      return runLength;
-    }
-    case LITE_SET_FG_FGBG_IMAGE: {
-      int runLength = orderHeader & g_MaskLiteRunLength;
-      if (runLength == 0)
-        runLength = srcBuf.readUnsignedByte() + 1;
-      else
-        runLength = runLength * 8;
-      return runLength;
-    }
-    case REGULAR_BG_RUN:
-    case REGULAR_COLOR_IMAGE:
-    case REGULAR_COLOR_RUN:
-    case REGULAR_FG_RUN: {
-      int runLength = orderHeader & g_MaskRegularRunLength;
-      if (runLength == 0)
-        // An extended (MEGA) run.
-        runLength = srcBuf.readUnsignedByte() + 32;
-      return runLength;
-    }
-    case LITE_DITHERED_RUN:
-    case LITE_SET_FG_FG_RUN: {
-      int runLength = orderHeader & g_MaskLiteRunLength;
-      if (runLength == 0)
-        // An extended (MEGA) run.
-        runLength = srcBuf.readUnsignedByte() + 16;
-      return runLength;
-    }
-    case MEGA_MEGA_BG_RUN:
-    case MEGA_MEGA_COLOR_IMAGE:
-    case MEGA_MEGA_COLOR_RUN:
-    case MEGA_MEGA_DITHERED_RUN:
-    case MEGA_MEGA_FG_RUN:
-    case MEGA_MEGA_FGBG_IMAGE:
-    case MEGA_MEGA_SET_FG_RUN:
-    case MEGA_MEGA_SET_FGBG_IMAGE: {
-      return srcBuf.readUnsignedShortLE();
-    }
-    default:
-      return 0;
-    }
-
-  }
-
-  /**
-   * Write a foreground/background image to a destination buffer.
-   */
-  private static void writeFgBgImage(int bpp, ByteBuffer destBuf, int rowDelta, int bitmask, int fgPel, int cBits) {
-    for (; cBits > 0; cBits--, bitmask >>= 1) {
-      int xorPixel = peekPixel(bpp, destBuf, -rowDelta);
-      writePixel(bpp, destBuf, ((bitmask & 0x1) > 0) ? xorPixel ^ fgPel : xorPixel);
-    }
-  }
-
-  /**
-   * Write a foreground/background image to a destination buffer for the first
-   * line of compressed data.
-   */
-  private static void writeFirstLineFgBgImage(int bpp, ByteBuffer destBuf, int bitmask, int fgPel, int cBits) {
-    for (; cBits > 0; cBits--, bitmask >>= 1) {
-      writePixel(bpp, destBuf, ((bitmask & 0x1) > 0) ? fgPel : getColorBlack());
-    }
-  }
-
-  /**
-   * Decompress a RLE compressed bitmap and flip decompressed image.
-   * 
-   * @param srcBuf
-   *          source buffer containing compressed bitmap
-   * @param imageWidth
-   *          width of destination image in pixels
-   * @param imageHeight
-   *          height of destination image in pixels
-   * @param colorDepth
-   *          bits per pixel
-   * @return destination image buffer
-   */
-  public static ByteBuffer rleDecompress(ByteBuffer srcBuf, int imageWidth, int imageHeight, int colorDepth) {
-    int bpp = getPixelSize(colorDepth);
-
-    // Decompress image
-    ByteBuffer destBuf = new ByteBuffer(new byte[imageWidth * imageHeight * bpp]);
-    rleDecompress(srcBuf, destBuf, imageWidth, imageHeight, colorDepth);
-
-    // Flip image
-    return flipRawImage(destBuf, imageWidth, imageHeight, bpp);
-  }
-
-  /**
-   * Decompress a RLE compressed bitmap.
-   * 
-   * @param srcBuf
-   *          source buffer containing compressed bitmap
-   * @param destBuf
-   *          destination buffer
-   * @param imageWidth
-   *          width of destination image in pixels
-   * @param imageHeight
-   *          height of destination image in pixels
-   * @param colorDepth
-   *          bits per pixel
-   */
-  protected static void rleDecompress(final ByteBuffer srcBuf, final ByteBuffer destBuf, final int imageWidth, final int imageHeight, final int colorDepth) {
-    final int bpp = getPixelSize(colorDepth);
-    final int rowDelta = imageWidth * bpp;
-    final int whitePixel = getColorWhite(colorDepth);
-    final int blackPixel = getColorBlack();
-
-    int fgPel = whitePixel;
-    boolean insertFgPel = false;
-    boolean firstLine = true;
-
-    if (destBuf.length != imageWidth * imageHeight * bpp)
-      throw new RuntimeException("Incorrect size of destination buffer. Expected size (imageWidth*imageHeight*bpp): " + (imageWidth * imageHeight * bpp)
-          + ", actual size: " + destBuf.length + ".");
-
-    while (srcBuf.cursor < srcBuf.length) {
-      // Watch out for the end of the first scanline in destination buffer.
-      if (firstLine) {
-        if (destBuf.cursor >= rowDelta) {
-          firstLine = false;
-          insertFgPel = false;
-        }
-      }
-
-      // Extract the compression order code ID from the compression
-      // order header.
-      int orderHeader = srcBuf.readUnsignedByte();
-      int code = extractCodeId(orderHeader);
-
-      // Handle Background Run Orders.
-      if (code == REGULAR_BG_RUN | code == MEGA_MEGA_BG_RUN) {
-        int runLength = extractRunLength(code, orderHeader, srcBuf);
-
-        if (firstLine) {
-          if (insertFgPel) {
-            writePixel(bpp, destBuf, fgPel);
-            runLength--;
-          }
-
-          for (; runLength > 0; runLength--)
-            writePixel(bpp, destBuf, blackPixel);
-
-        } else {
-          if (insertFgPel) {
-            writePixel(bpp, destBuf, peekPixel(bpp, destBuf, -rowDelta) ^ fgPel);
-            runLength--;
-          }
-
-          // Copy pixels from previous row of destination image
-          for (; runLength > 0; runLength--)
-            writePixel(bpp, destBuf, peekPixel(bpp, destBuf, -rowDelta));
-        }
-
-        //
-        // A follow-on background run order will need a
-        // foreground pel inserted.
-        //
-        insertFgPel = true;
-        continue;
-      }
-
-      //
-      // For any of the other run-types a follow-on background run
-      // order does not need a foreground pel inserted.
-      //
-      insertFgPel = false;
-
-      //
-      // Handle Foreground Run Orders.
-      //
-      if (code == REGULAR_FG_RUN | code == MEGA_MEGA_FG_RUN | code == LITE_SET_FG_FG_RUN | code == MEGA_MEGA_SET_FG_RUN) {
-        int runLength = extractRunLength(code, orderHeader, srcBuf);
-
-        if (code == LITE_SET_FG_FG_RUN | code == MEGA_MEGA_SET_FG_RUN)
-          fgPel = readPixel(bpp, srcBuf);
-
-        if (firstLine) {
-          for (; runLength > 0; runLength--) {
-            writePixel(bpp, destBuf, fgPel);
-          }
-        } else {
-          for (; runLength > 0; runLength--) {
-            writePixel(bpp, destBuf, peekPixel(bpp, destBuf, -rowDelta) ^ fgPel);
-          }
-        }
-
-        continue;
-      }
-
-      //
-      // Handle Dithered Run Orders.
-      //
-      if (code == LITE_DITHERED_RUN | code == MEGA_MEGA_DITHERED_RUN) {
-        int runLength = extractRunLength(code, orderHeader, srcBuf);
-
-        int pixelA = readPixel(bpp, srcBuf);
-        int pixelB = readPixel(bpp, srcBuf);
-
-        for (; runLength > 0; runLength--) {
-          writePixel(bpp, destBuf, pixelA);
-          writePixel(bpp, destBuf, pixelB);
-        }
-
-        continue;
-      }
-
-      //
-      // Handle Color Run Orders.
-      //
-      if (code == REGULAR_COLOR_RUN | code == MEGA_MEGA_COLOR_RUN) {
-        int runLength = extractRunLength(code, orderHeader, srcBuf);
-
-        int pixelA = readPixel(bpp, srcBuf);
-
-        for (; runLength > 0; runLength--)
-          writePixel(bpp, destBuf, pixelA);
-
-        continue;
-      }
-
-      //
-      // Handle Foreground/Background Image Orders.
-      //
-      if (code == REGULAR_FGBG_IMAGE | code == MEGA_MEGA_FGBG_IMAGE | code == LITE_SET_FG_FGBG_IMAGE | code == MEGA_MEGA_SET_FGBG_IMAGE) {
-        int runLength = extractRunLength(code, orderHeader, srcBuf);
-
-        if (code == LITE_SET_FG_FGBG_IMAGE | code == MEGA_MEGA_SET_FGBG_IMAGE) {
-          fgPel = readPixel(bpp, srcBuf);
-        }
-
-        for (; runLength > 8; runLength -= 8) {
-          int bitmask = srcBuf.readUnsignedByte();
-
-          if (firstLine)
-            writeFirstLineFgBgImage(bpp, destBuf, bitmask, fgPel, 8);
-          else
-            writeFgBgImage(bpp, destBuf, rowDelta, bitmask, fgPel, 8);
-        }
-
-        if (runLength > 0) {
-          int bitmask = srcBuf.readUnsignedByte();
-
-          if (firstLine)
-            writeFirstLineFgBgImage(bpp, destBuf, bitmask, fgPel, runLength);
-          else
-            writeFgBgImage(bpp, destBuf, rowDelta, bitmask, fgPel, runLength);
-        }
-
-        continue;
-      }
-
-      //
-      // Handle Color Image Orders.
-      //
-      if (code == REGULAR_COLOR_IMAGE | code == MEGA_MEGA_COLOR_IMAGE) {
-        int runLength = extractRunLength(code, orderHeader, srcBuf);
-
-        /* DEBUG */
-        // Copy bytes from source to destination using writeByte(readByte())
-        // for (int byteCount = runLength * bpp; byteCount > 0; byteCount--) {
-        // destBuf.writeByte(srcBuf.readUnsignedByte());
-        // }
-        /* DEBUG */
-
-        // Copy bytes from source to destination directly using arraycopy()
-        int lengthInBytes = runLength * bpp;
-        System.arraycopy(srcBuf.data, srcBuf.offset + srcBuf.cursor, destBuf.data, destBuf.offset + destBuf.cursor, lengthInBytes);
-        srcBuf.cursor += lengthInBytes;
-        destBuf.cursor += lengthInBytes;
-
-        continue;
-      }
-
-      //
-      // Handle Special Order 1.
-      //
-      if (code == SPECIAL_FGBG_1) {
-        if (firstLine)
-          writeFirstLineFgBgImage(bpp, destBuf, g_MaskSpecialFgBg1, fgPel, 8);
-        else
-          writeFgBgImage(bpp, destBuf, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
-
-        continue;
-      }
-
-      //
-      // Handle Special Order 2.
-      //
-      if (code == SPECIAL_FGBG_2) {
-        if (firstLine)
-          writeFirstLineFgBgImage(bpp, destBuf, g_MaskSpecialFgBg2, fgPel, 8);
-        else
-          writeFgBgImage(bpp, destBuf, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
-
-        continue;
-      }
-
-      //
-      // Handle White Order.
-      //
-      if (code == SPECIAL_WHITE) {
-        writePixel(bpp, destBuf, whitePixel);
-
-        continue;
-      }
-
-      //
-      // Handle Black Order.
-      //
-      if (code == SPECIAL_BLACK) {
-        writePixel(bpp, destBuf, blackPixel);
-
-        continue;
-      }
-
-      throw new RuntimeException("Unknown code: " + code + ".");
-    }
-  }
-
-  /**
-   * Flip image in vertical direction.
-   */
-  public static ByteBuffer flipRawImage(ByteBuffer src, int width, int height, int bpp) {
-    if (width * height * bpp != src.length)
-      throw new RuntimeException("Incorrect size of buffer. Expected size (imageWidth*imageHeight*bpp): " + (width * height * bpp) + ", actual size: "
-          + src.length + ".");
-    ByteBuffer dest = new ByteBuffer(new byte[src.length]);
-
-    int scanLine = width * bpp;
-
-    for (int i = 0; i < height; i++) {
-      // Copy one row
-      System.arraycopy(src.data, (height - i - 1) * scanLine, dest.data, i * scanLine, scanLine);
-    }
-
-    return dest;
-
-  }
-
-  /**
-   * Example.
-   */
-  public static void main(String args[]) {
-
-    if (true) {
-      // 16x1@8bpp, all black
-      int width = 16, height = 1, depth = 8, bpp = depth / 8;
-      ByteBuffer src = new ByteBuffer(new byte[] { 0x10 });
-      ByteBuffer dest = new AssertingByteBuffer(new byte[width * height * bpp]);
-      rleDecompress(src, dest, width, height, depth);
-    }
-
-    if (true) {
-      // 16x1@16bpp, all black
-      int width = 16, height = 1, depth = 16, bpp = depth / 8;
-      ByteBuffer src = new ByteBuffer(new byte[] { 0x0c, (byte) 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
-      ByteBuffer dest = new AssertingByteBuffer(new byte[width * height * bpp]);
-      rleDecompress(src, dest, width, height, depth);
-    }
-
-    if (true) {
-      // 32x32@8
-      int width = 32, height = 32, depth = 8, bpp = depth / 8;
-
-      ByteBuffer src = new ByteBuffer(new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x00, (byte) 0x06, (byte) 0x06,
-          (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0xec, (byte) 0x6c, (byte) 0x0e,
-          (byte) 0x0e, (byte) 0x44, (byte) 0x0e, (byte) 0x0e, (byte) 0x0e, (byte) 0x13, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06,
-          (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0xe4, (byte) 0x04, (byte) 0x06,
-          (byte) 0x8e, (byte) 0x60, (byte) 0x0e, (byte) 0x60, (byte) 0x8c, (byte) 0xb4, (byte) 0xb5, (byte) 0xdc, (byte) 0xdc, (byte) 0xbb, (byte) 0xb4,
-          (byte) 0x8c, (byte) 0x66, (byte) 0x0b, (byte) 0x6c, (byte) 0xe4, (byte) 0x04, (byte) 0x06, (byte) 0x02, (byte) 0x8b, (byte) 0x06, (byte) 0x06,
-          (byte) 0xed, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0xf8, (byte) 0x0e, (byte) 0x66, (byte) 0xb4, (byte) 0xdc, (byte) 0x68, (byte) 0xe2,
-          (byte) 0x97, (byte) 0xdd, (byte) 0xb4, (byte) 0xa7, (byte) 0x16, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0xed,
-          (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x0b, (byte) 0xae,
-          (byte) 0xdc, (byte) 0xe9, (byte) 0x6a, (byte) 0xdc, (byte) 0x96, (byte) 0xe9, (byte) 0xe9, (byte) 0xb4, (byte) 0x0e, (byte) 0x00, (byte) 0x06,
-          (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06,
-          (byte) 0x0e, (byte) 0xae, (byte) 0xdc, (byte) 0xdb, (byte) 0xdb, (byte) 0xd0, (byte) 0x09, (byte) 0x07, (byte) 0xcf, (byte) 0x03, (byte) 0x95,
-          (byte) 0xdb, (byte) 0xdb, (byte) 0xdc, (byte) 0xb4, (byte) 0x66, (byte) 0x6c, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0x00,
-          (byte) 0x00, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x0b, (byte) 0xae, (byte) 0xdb, (byte) 0xd4, (byte) 0xd5, (byte) 0x6c,
-          (byte) 0xdb, (byte) 0x80, (byte) 0xaf, (byte) 0xd5, (byte) 0xd4, (byte) 0xdb, (byte) 0xb4, (byte) 0x66, (byte) 0x04, (byte) 0x06, (byte) 0x04,
-          (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0xed, (byte) 0x06, (byte) 0xed, (byte) 0x66, (byte) 0xae, (byte) 0xd5, (byte) 0xad, (byte) 0xd4,
-          (byte) 0xd4, (byte) 0xd5, (byte) 0xd5, (byte) 0xd5, (byte) 0xdb, (byte) 0xb4, (byte) 0xb4, (byte) 0xb4, (byte) 0xb4, (byte) 0xb4, (byte) 0xd5,
-          (byte) 0xd5, (byte) 0xd5, (byte) 0xd4, (byte) 0xd4, (byte) 0xad, (byte) 0xd5, (byte) 0xb4, (byte) 0x0e, (byte) 0x06, (byte) 0x06, (byte) 0x06,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x60, (byte) 0xa7, (byte) 0xb4, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xb3,
-          (byte) 0xb3, (byte) 0xd4, (byte) 0xd4, (byte) 0xb3, (byte) 0x8c, (byte) 0xb6, (byte) 0x07, (byte) 0xb6, (byte) 0x8c, (byte) 0xb3, (byte) 0xd4,
-          (byte) 0xb3, (byte) 0xb3, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xb4, (byte) 0xad, (byte) 0x66, (byte) 0x00, (byte) 0x06, (byte) 0x00,
-          (byte) 0x00, (byte) 0x06, (byte) 0x06, (byte) 0x66, (byte) 0xae, (byte) 0xad, (byte) 0x8b, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xad,
-          (byte) 0xad, (byte) 0xb3, (byte) 0xad, (byte) 0xb5, (byte) 0x07, (byte) 0x07, (byte) 0x07, (byte) 0xf0, (byte) 0x8b, (byte) 0xad, (byte) 0xad,
-          (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0x8b, (byte) 0xa7, (byte) 0xae, (byte) 0xa7, (byte) 0x6c, (byte) 0x06, (byte) 0x00, (byte) 0x00,
-          (byte) 0x04, (byte) 0x6c, (byte) 0xa7, (byte) 0xad, (byte) 0xa7, (byte) 0xa7, (byte) 0x8b, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xad,
-          (byte) 0xad, (byte) 0xad, (byte) 0xb5, (byte) 0xbd, (byte) 0xbd, (byte) 0xbd, (byte) 0xbd, (byte) 0xf0, (byte) 0x8b, (byte) 0x8b, (byte) 0xad,
-          (byte) 0x8b, (byte) 0x8b, (byte) 0xa7, (byte) 0xa7, (byte) 0xc8, (byte) 0xc8, (byte) 0x60, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x06,
-          (byte) 0x66, (byte) 0xc8, (byte) 0xa7, (byte) 0x66, (byte) 0xa7, (byte) 0xa7, (byte) 0x8b, (byte) 0x8b, (byte) 0x8b, (byte) 0x8b, (byte) 0xad,
-          (byte) 0x8b, (byte) 0x92, (byte) 0xf1, (byte) 0xf1, (byte) 0xf1, (byte) 0xf1, (byte) 0xf2, (byte) 0x07, (byte) 0xa7, (byte) 0xa7, (byte) 0x8b,
-          (byte) 0xa7, (byte) 0xa7, (byte) 0x66, (byte) 0x66, (byte) 0xc8, (byte) 0x66, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x60,
-          (byte) 0xa7, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0xa7, (byte) 0xa7, (byte) 0xa7, (byte) 0xa7, (byte) 0x8b, (byte) 0x8b, (byte) 0x8b,
-          (byte) 0xa7, (byte) 0xb6, (byte) 0xf3, (byte) 0xf3, (byte) 0xf3, (byte) 0xf3, (byte) 0xf3, (byte) 0x07, (byte) 0x66, (byte) 0xa7, (byte) 0xa7,
-          (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0xa7, (byte) 0xa7, (byte) 0x6c, (byte) 0x00, (byte) 0x00, (byte) 0x6c, (byte) 0x04, (byte) 0xa7,
-          (byte) 0x60, (byte) 0x6b, (byte) 0x66, (byte) 0x99, (byte) 0xb6, (byte) 0xf5, (byte) 0xf5, (byte) 0xf5, (byte) 0xf5, (byte) 0xf5, (byte) 0xef,
-          (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0xa7, (byte) 0x66, (byte) 0x00, (byte) 0x00, (byte) 0x60,
-          (byte) 0xa7, (byte) 0x66, (byte) 0x60, (byte) 0x66, (byte) 0x66, (byte) 0x8c, (byte) 0xf1, (byte) 0x6e, (byte) 0xff, (byte) 0x85, (byte) 0xbd,
-          (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x60, (byte) 0x05, (byte) 0x87, (byte) 0x13, (byte) 0x04, (byte) 0x66, (byte) 0x66, (byte) 0x66,
-          (byte) 0x66, (byte) 0xf4, (byte) 0x70, (byte) 0xff, (byte) 0x84, (byte) 0xbd, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x05, (byte) 0x85,
-          (byte) 0x0b, (byte) 0xa7, (byte) 0xb5, (byte) 0xae, (byte) 0x8c, (byte) 0xd0, (byte) 0x13, (byte) 0xc1, (byte) 0x01, (byte) 0x00, (byte) 0x08,
-          (byte) 0x8e, (byte) 0x8c, (byte) 0xae, (byte) 0xb5, (byte) 0xae, (byte) 0x66, (byte) 0x00, (byte) 0x00, (byte) 0x6c, (byte) 0xae, (byte) 0xbc,
-          (byte) 0xb5, (byte) 0xb5, (byte) 0xae, (byte) 0xb5, (byte) 0xd0, (byte) 0x0e, (byte) 0x0c, (byte) 0x01, (byte) 0x00, (byte) 0x90, (byte) 0xf2,
-          (byte) 0xae, (byte) 0xae, (byte) 0xb5, (byte) 0xb5, (byte) 0xbc, (byte) 0xb5, (byte) 0x66, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0xae,
-          (byte) 0x0a, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0x68, (byte) 0xae, (byte) 0x82, (byte) 0x8c, (byte) 0x0a, (byte) 0x05, (byte) 0x8c,
-          (byte) 0xf2, (byte) 0xae, (byte) 0xae, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xbc, (byte) 0xb5, (byte) 0x6c, (byte) 0x00, (byte) 0x00,
-          (byte) 0x06, (byte) 0x05, (byte) 0x81, (byte) 0xd0, (byte) 0x06, (byte) 0x9a, (byte) 0x8c, (byte) 0x0a, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xf2, (byte) 0xae, (byte) 0xae, (byte) 0xd0, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0x0a, (byte) 0xb5,
-          (byte) 0x6c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x8b, (byte) 0x0a, (byte) 0xbc, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0x06,
-          (byte) 0x9b, (byte) 0xb6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xf2, (byte) 0xae, (byte) 0xae, (byte) 0xae,
-          (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb6, (byte) 0x0a, (byte) 0x8c, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x6c,
-          (byte) 0xb5, (byte) 0x0a, (byte) 0xb6, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0x05, (byte) 0x80, (byte) 0x7d, (byte) 0xbc, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xf2, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb6,
-          (byte) 0x0a, (byte) 0x0a, (byte) 0x8b, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x06, (byte) 0x87, (byte) 0x0a, (byte) 0xbc,
-          (byte) 0xb6, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xd0, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xb6, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xf2, (byte) 0xd0, (byte) 0xae, (byte) 0xd0, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb6, (byte) 0xbc, (byte) 0x1a,
-          (byte) 0xb5, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0xed, (byte) 0x06, (byte) 0x6e, (byte) 0xb5, (byte) 0x0a, (byte) 0xbc,
-          (byte) 0xb6, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xd0, (byte) 0xd0, (byte) 0xd0, (byte) 0xb5, (byte) 0xf4, (byte) 0xff, (byte) 0xf2,
-          (byte) 0xd0, (byte) 0xd0, (byte) 0xd0, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb6, (byte) 0xbc, (byte) 0x0a, (byte) 0x0a, (byte) 0x8b,
-          (byte) 0x06, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x04, (byte) 0x8b, (byte) 0xbc, (byte) 0x1a, (byte) 0x0a,
-          (byte) 0xb6, (byte) 0xb6, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xd0, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5,
-          (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb6, (byte) 0xb6, (byte) 0x0a, (byte) 0xde, (byte) 0x0a, (byte) 0xa7, (byte) 0x06, (byte) 0x00,
-          (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x8b, (byte) 0xbc, (byte) 0xf2, (byte) 0x0a,
-          (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb6,
-          (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0x0a, (byte) 0xf2, (byte) 0x1a, (byte) 0x8c, (byte) 0xec, (byte) 0x06, (byte) 0x06, (byte) 0x06,
-          (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0xa7, (byte) 0xbc, (byte) 0x1a, (byte) 0x0a,
-          (byte) 0x0a, (byte) 0x6a, (byte) 0xb6, (byte) 0x96, (byte) 0x0a, (byte) 0x0a, (byte) 0xf2, (byte) 0x0a, (byte) 0x87, (byte) 0x06, (byte) 0x04,
-          (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0xed, (byte) 0x06,
-          (byte) 0x8c, (byte) 0xb6, (byte) 0xf4, (byte) 0xf2, (byte) 0xd0, (byte) 0x09, (byte) 0xbc, (byte) 0x87, (byte) 0x03, (byte) 0x80, (byte) 0x2c,
-          (byte) 0xde, (byte) 0xf4, (byte) 0x0a, (byte) 0x8b, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x04, (byte) 0x6c, (byte) 0x87, (byte) 0x0a,
-          (byte) 0xf4, (byte) 0xf4, (byte) 0xf2, (byte) 0xde, (byte) 0xbd, (byte) 0xbd, (byte) 0xde, (byte) 0xf2, (byte) 0xf4, (byte) 0xf4, (byte) 0x0a,
-          (byte) 0xd0, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00,
-          (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x6c, (byte) 0x8c,
-          (byte) 0xb5, (byte) 0xbc, (byte) 0x0a, (byte) 0xde, (byte) 0xf2, (byte) 0xbd, (byte) 0x0a, (byte) 0xb5, (byte) 0x8c, (byte) 0x6c, (byte) 0x06,
-          (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0xe6,
-          (byte) 0x04, (byte) 0x06, (byte) 0x86, (byte) 0x04, (byte) 0x6c, (byte) 0x04, (byte) 0x8b, (byte) 0x04, (byte) 0x6c, (byte) 0xe6, (byte) 0x04,
-          (byte) 0x06, (byte) 0x82, (byte) 0x00, (byte) 0x00
-
-      });
-
-      ByteBuffer flippedImage = new ByteBuffer(new byte[] { (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04,
-          (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x6c, (byte) 0x04, (byte) 0x8b, (byte) 0x04, (byte) 0x6c,
-          (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04,
-          (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06,
-          (byte) 0x06, (byte) 0x6c, (byte) 0x8c, (byte) 0xb5, (byte) 0xbc, (byte) 0x0a, (byte) 0xde, (byte) 0xf2, (byte) 0xbd, (byte) 0x0a, (byte) 0xb5,
-          (byte) 0x8c, (byte) 0x6c, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x04, (byte) 0x6c, (byte) 0x87,
-          (byte) 0x0a, (byte) 0xf4, (byte) 0xf4, (byte) 0xf2, (byte) 0xde, (byte) 0xbd, (byte) 0xbd, (byte) 0xde, (byte) 0xf2, (byte) 0xf4, (byte) 0xf4,
-          (byte) 0x0a, (byte) 0xd0, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x00,
-          (byte) 0x00, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x8c, (byte) 0xb6, (byte) 0xf4, (byte) 0xf2,
-          (byte) 0x0a, (byte) 0x0a, (byte) 0x0a, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0x0a, (byte) 0x0a, (byte) 0x0a, (byte) 0xde,
-          (byte) 0xf4, (byte) 0x0a, (byte) 0x8b, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x00, (byte) 0x00,
-          (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0xa7, (byte) 0xbc, (byte) 0x1a, (byte) 0x0a, (byte) 0x0a, (byte) 0xb6,
-          (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0x0a, (byte) 0x0a,
-          (byte) 0xf2, (byte) 0x0a, (byte) 0x87, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x06,
-          (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x8b, (byte) 0xbc, (byte) 0xf2, (byte) 0x0a, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6,
-          (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0xb6, (byte) 0x0a,
-          (byte) 0xf2, (byte) 0x1a, (byte) 0x8c, (byte) 0xec, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06,
-          (byte) 0x04, (byte) 0x8b, (byte) 0xbc, (byte) 0x1a, (byte) 0x0a, (byte) 0xb6, (byte) 0xb6, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5,
-          (byte) 0xb5, (byte) 0xd0, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb6, (byte) 0xb6, (byte) 0x0a,
-          (byte) 0xde, (byte) 0x0a, (byte) 0xa7, (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0xed, (byte) 0x06, (byte) 0x6e,
-          (byte) 0xb5, (byte) 0x0a, (byte) 0xbc, (byte) 0xb6, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xd0, (byte) 0xd0, (byte) 0xd0, (byte) 0xb5,
-          (byte) 0xf4, (byte) 0xff, (byte) 0xf2, (byte) 0xd0, (byte) 0xd0, (byte) 0xd0, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb6, (byte) 0xbc,
-          (byte) 0x0a, (byte) 0x0a, (byte) 0x8b, (byte) 0x06, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x06, (byte) 0x87, (byte) 0x0a,
-          (byte) 0xbc, (byte) 0xb6, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xd0, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xb6, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xf2, (byte) 0xd0, (byte) 0xae, (byte) 0xd0, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb6, (byte) 0xbc,
-          (byte) 0x1a, (byte) 0xb5, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x6c, (byte) 0xb5, (byte) 0x0a, (byte) 0xb6,
-          (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xbc, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xf2, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb6, (byte) 0x0a,
-          (byte) 0x0a, (byte) 0x8b, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x8b, (byte) 0x0a, (byte) 0xbc, (byte) 0xb5, (byte) 0xb5,
-          (byte) 0xb5, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xb6, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xf2, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xb6, (byte) 0x0a,
-          (byte) 0x8c, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0xae, (byte) 0x0a, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xd0,
-          (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0x8c, (byte) 0x0a, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xf2, (byte) 0xae, (byte) 0xae, (byte) 0xd0, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0x0a, (byte) 0xb5,
-          (byte) 0x6c, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0xae, (byte) 0x0a, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xae, (byte) 0xae,
-          (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0xae, (byte) 0x8c, (byte) 0x0a, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xf2, (byte) 0xae, (byte) 0xae, (byte) 0xb5, (byte) 0xb5, (byte) 0xb5, (byte) 0xbc, (byte) 0xb5, (byte) 0x6c,
-          (byte) 0x00, (byte) 0x00, (byte) 0x6c, (byte) 0xae, (byte) 0xbc, (byte) 0xb5, (byte) 0xb5, (byte) 0xae, (byte) 0xb5, (byte) 0xf3, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xf2, (byte) 0xae, (byte) 0xae, (byte) 0xb5, (byte) 0xb5, (byte) 0xbc, (byte) 0xb5, (byte) 0x66, (byte) 0x00,
-          (byte) 0x00, (byte) 0x0b, (byte) 0xa7, (byte) 0xb5, (byte) 0xae, (byte) 0x8c, (byte) 0xa7, (byte) 0xf4, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xbd, (byte) 0xa7, (byte) 0x8c, (byte) 0xae, (byte) 0xb5, (byte) 0xae, (byte) 0x66, (byte) 0x00, (byte) 0x00,
-          (byte) 0x13, (byte) 0x04, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0xf4, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xbd, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0xa7, (byte) 0x66, (byte) 0x00, (byte) 0x00, (byte) 0x60,
-          (byte) 0xa7, (byte) 0x66, (byte) 0x60, (byte) 0x66, (byte) 0x66, (byte) 0x8c, (byte) 0xf1, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xbd,
-          (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x60, (byte) 0x66, (byte) 0xa7, (byte) 0x66, (byte) 0x00, (byte) 0x00, (byte) 0x6c, (byte) 0x04,
-          (byte) 0xa7, (byte) 0x60, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x66,
-          (byte) 0x66, (byte) 0x66, (byte) 0xb6, (byte) 0xf5, (byte) 0xf5, (byte) 0xf5, (byte) 0xf5, (byte) 0xf5, (byte) 0xef, (byte) 0x66, (byte) 0x66,
-          (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0xa7, (byte) 0x66, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x60, (byte) 0xa7,
-          (byte) 0x66, (byte) 0x66, (byte) 0x66, (byte) 0xa7, (byte) 0xa7, (byte) 0xa7, (byte) 0xa7, (byte) 0x8b, (byte) 0x8b, (byte) 0x8b, (byte) 0xa7,
-          (byte) 0xb6, (byte) 0xf3, (byte) 0xf3, (byte) 0xf3, (byte) 0xf3, (byte) 0xf3, (byte) 0x07, (byte) 0x66, (byte) 0xa7, (byte) 0xa7, (byte) 0x66,
-          (byte) 0x66, (byte) 0x66, (byte) 0xa7, (byte) 0xa7, (byte) 0x6c, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x66, (byte) 0xc8, (byte) 0xa7,
-          (byte) 0x66, (byte) 0xa7, (byte) 0xa7, (byte) 0x8b, (byte) 0x8b, (byte) 0x8b, (byte) 0x8b, (byte) 0xad, (byte) 0x8b, (byte) 0x92, (byte) 0xf1,
-          (byte) 0xf1, (byte) 0xf1, (byte) 0xf1, (byte) 0xf2, (byte) 0x07, (byte) 0xa7, (byte) 0xa7, (byte) 0x8b, (byte) 0xa7, (byte) 0xa7, (byte) 0x66,
-          (byte) 0x66, (byte) 0xc8, (byte) 0x66, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x6c, (byte) 0xa7, (byte) 0xad, (byte) 0xa7,
-          (byte) 0xa7, (byte) 0x8b, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xb5, (byte) 0xbd, (byte) 0xbd,
-          (byte) 0xbd, (byte) 0xbd, (byte) 0xf0, (byte) 0x8b, (byte) 0x8b, (byte) 0xad, (byte) 0x8b, (byte) 0x8b, (byte) 0xa7, (byte) 0xa7, (byte) 0xc8,
-          (byte) 0xc8, (byte) 0x60, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x06, (byte) 0x66, (byte) 0xae, (byte) 0xad, (byte) 0x8b,
-          (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xb3, (byte) 0xad, (byte) 0xb5, (byte) 0x07, (byte) 0x07, (byte) 0x07,
-          (byte) 0xf0, (byte) 0x8b, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0x8b, (byte) 0xa7, (byte) 0xae, (byte) 0xa7,
-          (byte) 0x6c, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x60, (byte) 0xa7, (byte) 0xb4, (byte) 0xad, (byte) 0xad,
-          (byte) 0xad, (byte) 0xb3, (byte) 0xb3, (byte) 0xd4, (byte) 0xd4, (byte) 0xb3, (byte) 0x8c, (byte) 0xb6, (byte) 0x07, (byte) 0xb6, (byte) 0x8c,
-          (byte) 0xb3, (byte) 0xd4, (byte) 0xb3, (byte) 0xb3, (byte) 0xad, (byte) 0xad, (byte) 0xad, (byte) 0xb4, (byte) 0xad, (byte) 0x66, (byte) 0x00,
-          (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0xed, (byte) 0x06, (byte) 0xed, (byte) 0x66, (byte) 0xae, (byte) 0xd5, (byte) 0xad, (byte) 0xd4,
-          (byte) 0xd4, (byte) 0xd5, (byte) 0xd5, (byte) 0xd5, (byte) 0xdb, (byte) 0xb4, (byte) 0xb4, (byte) 0xb4, (byte) 0xb4, (byte) 0xb4, (byte) 0xd5,
-          (byte) 0xd5, (byte) 0xd5, (byte) 0xd4, (byte) 0xd4, (byte) 0xad, (byte) 0xd5, (byte) 0xb4, (byte) 0x0e, (byte) 0x06, (byte) 0x06, (byte) 0x06,
-          (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x0b, (byte) 0xae, (byte) 0xdb, (byte) 0xd4, (byte) 0xd5,
-          (byte) 0xdb, (byte) 0xdb, (byte) 0xdb, (byte) 0xdb, (byte) 0xdb, (byte) 0xdb, (byte) 0xdb, (byte) 0xdb, (byte) 0xdb, (byte) 0xdb, (byte) 0xdb,
-          (byte) 0xdb, (byte) 0xd5, (byte) 0xd4, (byte) 0xdb, (byte) 0xb4, (byte) 0x66, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x00,
-          (byte) 0x00, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x0e, (byte) 0xae, (byte) 0xdc, (byte) 0xdb, (byte) 0xdb,
-          (byte) 0xdb, (byte) 0xdb, (byte) 0xdb, (byte) 0xdb, (byte) 0xdc, (byte) 0xdc, (byte) 0xdb, (byte) 0xdb, (byte) 0xdb, (byte) 0xdb, (byte) 0xdb,
-          (byte) 0xdb, (byte) 0xdc, (byte) 0xb4, (byte) 0x66, (byte) 0x6c, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x0b, (byte) 0xae, (byte) 0xdc, (byte) 0xe9, (byte) 0xdc,
-          (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xe9, (byte) 0xe9,
-          (byte) 0xb4, (byte) 0x0e, (byte) 0x00, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x06,
-          (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0xf8, (byte) 0x0e, (byte) 0x66, (byte) 0xb4, (byte) 0xdc, (byte) 0xe2,
-          (byte) 0xe2, (byte) 0xe2, (byte) 0xe2, (byte) 0xe2, (byte) 0xe2, (byte) 0xe2, (byte) 0xe2, (byte) 0xdd, (byte) 0xb4, (byte) 0xa7, (byte) 0x16,
-          (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x06,
-          (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x60, (byte) 0x0e, (byte) 0x60, (byte) 0x8c, (byte) 0xb4,
-          (byte) 0xb5, (byte) 0xdc, (byte) 0xdc, (byte) 0xbb, (byte) 0xb4, (byte) 0x8c, (byte) 0x66, (byte) 0x0b, (byte) 0x6c, (byte) 0x04, (byte) 0x06,
-          (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x06, (byte) 0xed,
-          (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0xec, (byte) 0x6c, (byte) 0x0e, (byte) 0x0e,
-          (byte) 0x44, (byte) 0x0e, (byte) 0x0e, (byte) 0x0e, (byte) 0x13, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06,
-          (byte) 0x06, (byte) 0xed, (byte) 0x06, (byte) 0x06, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 });
-      ByteBuffer dest = new AssertingByteBuffer(flipRawImage(flippedImage, width, height, bpp).data);
-
-      rleDecompress(src, dest, width, height, depth);
-
-    }
-
-    if (true) {
-      // 32x32@16
-      int width = 32, height = 32, depth = 16;
-
-      ByteBuffer src = new ByteBuffer(new byte[] { (byte) 0x85, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x06, (byte) 0x8b, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x06, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0x16, (byte) 0x69, (byte) 0x99, (byte) 0xd6, (byte) 0x06, (byte) 0x69, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x04, (byte) 0xcc, (byte) 0x89, (byte) 0x52, (byte) 0x03, (byte) 0x6e, (byte) 0xff, (byte) 0xff, (byte) 0x02, (byte) 0x6e,
-          (byte) 0x08, (byte) 0x42, (byte) 0x01, (byte) 0x70, (byte) 0x08, (byte) 0x42, (byte) 0x71, (byte) 0xff, (byte) 0xff, (byte) 0xce, (byte) 0x18,
-          (byte) 0xc6, (byte) 0x01, (byte) 0x81, (byte) 0x08, (byte) 0x42, (byte) 0xce, (byte) 0x66, (byte) 0x29, (byte) 0x02, (byte) 0xcd, (byte) 0x89,
-          (byte) 0x52, (byte) 0x03, (byte) 0x88, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xd8, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x03, (byte) 0xf8, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x66, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x05, (byte) 0x6a, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0xc4, (byte) 0xcc, (byte) 0x89, (byte) 0x52, (byte) 0x03, (byte) 0x6e,
-          (byte) 0xff, (byte) 0xff, (byte) 0x02, (byte) 0x6e, (byte) 0x08, (byte) 0x42, (byte) 0x01, (byte) 0x70, (byte) 0x08, (byte) 0x42, (byte) 0x71,
-          (byte) 0xff, (byte) 0xff, (byte) 0xce, (byte) 0x18, (byte) 0xc6, (byte) 0x01, (byte) 0x81, (byte) 0x08, (byte) 0x42, (byte) 0xce, (byte) 0x66,
-          (byte) 0x29, (byte) 0x02, (byte) 0xcd, (byte) 0x89, (byte) 0x52, (byte) 0x03, (byte) 0x00, (byte) 0x04, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0xc3, (byte) 0x80, (byte) 0x61, (byte) 0x00, (byte) 0xa5, (byte) 0x80, (byte) 0x40, (byte) 0xec, (byte) 0x52, (byte) 0x00, (byte) 0x5a,
-          (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x24, (byte) 0x00, (byte) 0x12, (byte) 0x00, (byte) 0x24, (byte) 0x00, (byte) 0x12, (byte) 0x00,
-          (byte) 0x5a, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0xa5, (byte) 0x80, (byte) 0x52, (byte) 0x00, (byte) 0xc3, (byte) 0x80, (byte) 0x61,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xcc, (byte) 0x89, (byte) 0x52, (byte) 0x03, (byte) 0x6e, (byte) 0xff,
-          (byte) 0xff, (byte) 0x02, (byte) 0xcb, (byte) 0x18, (byte) 0xc6, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08,
-          (byte) 0x42, (byte) 0xff, (byte) 0xff, });
-
-      ByteBuffer dest = new AssertingByteBuffer(new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10,
-          (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08,
-          (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08,
-          (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84,
-          (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10,
-          (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08,
-          (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42,
-          (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08,
-          (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0xff, (byte) 0xff, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42,
-          (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08,
-          (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42,
-          (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84,
-          (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10,
-          (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84,
-          (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84,
-          (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42,
-          (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42,
-          (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10,
-          (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08,
-          (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08,
-          (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10,
-          (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10,
-          (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84,
-          (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x99,
-          (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08,
-          (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42,
-          (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0xff,
-          (byte) 0xff, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42,
-          (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08,
-          (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84,
-          (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10,
-          (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10,
-          (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08,
-          (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08,
-          (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10,
-          (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84,
-          (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42,
-          (byte) 0x08, (byte) 0x42, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6,
-          (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99,
-          (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x99, (byte) 0xd6, (byte) 0x10, (byte) 0x84, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42,
-          (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10,
-          (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84,
-          (byte) 0x10, (byte) 0x84, (byte) 0x10, (byte) 0x84, (byte) 0x99, (byte) 0xd6, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-          (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42,
-          (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08,
-          (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42,
-          (byte) 0x08, (byte) 0x42, (byte) 0x08, (byte) 0x42, (byte) 0xff, (byte) 0xff, });
-
-      rleDecompress(src, dest, width, height, depth);
-
-    }
-  }
-}


[14/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java
new file mode 100755
index 0000000..639ca50
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java
@@ -0,0 +1,121 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.hyperv;
+
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * For HyperV server, client must send VM ID before any other packet.
+ */
+public class ClientPreConnectionBlob extends OneTimeSwitch {
+
+    protected String data;
+
+    public ClientPreConnectionBlob(String id, String data) {
+        super(id);
+        this.data = data;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("This element only sends data. This method must not be called. Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        sendPreConnectionBlobData(data);
+    }
+
+    protected void sendPreConnectionBlobData(String data) {
+        // Length of packet
+        ByteBuffer buf = new ByteBuffer(1024, true);
+
+        // Header
+        buf.writeBytes(new byte[] {(byte)0x5e, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,});
+
+        // Length of string in wide characters + two wide \0 (LE)
+        buf.writeShortLE(data.length() + 2);
+
+        // Wide string + two wide '\0' characters
+        buf.writeString(data + "\0\0", RdpConstants.CHARSET_16);
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String[] args) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        // Header
+        (byte) 0x5e, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        
+        // Length of string in wide characters + two wide \0 (LE)
+        (byte) 0x26, (byte) 0x00,
+
+        // Wide string
+        (byte) 0x33, (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x34, (byte) 0x00, (byte) 0x31, (byte) 0x00, (byte) 0x38, (byte) 0x00, (byte) 0x46,
+        (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x30, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x44, (byte) 0x00,
+        (byte) 0x30, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x34, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x38,
+        (byte) 0x00, (byte) 0x45, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x42, (byte) 0x00, (byte) 0x37, (byte) 0x00, (byte) 0x39, (byte) 0x00,
+        (byte) 0x36, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x31, (byte) 0x00, (byte) 0x43, (byte) 0x00, (byte) 0x36,
+        (byte) 0x00, (byte) 0x30, (byte) 0x00, (byte) 0x44, (byte) 0x00, (byte) 0x44, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x36, (byte) 0x00,
+        (byte) 0x35, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x41, (byte) 0x00,
+
+        // Two wide \0
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+    };
+    /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element pcb = new ClientPreConnectionBlob("pcb", "39418F90-6D03-468E-B796-91C60DD6653A");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, pcb, sink, mainSink);
+        pipeline.link("source", "pcb", "mainSink");
+        pipeline.link("pcb >" + OTOUT, "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java
new file mode 100755
index 0000000..d32c8ca
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java
@@ -0,0 +1,178 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp;
+
+import common.asn1.Tag;
+
+import rdpclient.ntlmssp.asn1.NegoItem;
+import rdpclient.ntlmssp.asn1.TSRequest;
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc236641.aspx
+ */
+public class ClientNtlmsspNegotiate extends OneTimeSwitch {
+
+    /**
+     * The set of client configuration flags (section 2.2.2.5) that specify the
+     * full set of capabilities of the client.
+     */
+    public NegoFlags clientConfigFlags = new NegoFlags().set_NEGOTIATE_56().set_NEGOTIATE_KEY_EXCH().set_NEGOTIATE_128().set_NEGOTIATE_VERSION()
+            .set_NEGOTIATE_EXTENDED_SESSION_SECURITY().set_NEGOTIATE_ALWAYS_SIGN().set_NEGOTIATE_NTLM().set_NEGOTIATE_LM_KEY().set_NEGOTIATE_SEAL()
+            .set_NEGOTIATE_SIGN().set_REQUEST_TARGET().set_NEGOTIATE_OEM().set_NEGOTIATE_UNICODE();
+
+    protected NtlmState ntlmState;
+
+    public ClientNtlmsspNegotiate(String id, NtlmState state) {
+        super(id);
+        this.ntlmState = state;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        ByteBuffer negoToken = generateNegotiateMessage();
+        ntlmState.negotiateMessage = negoToken.toByteArray(); // Store message for MIC calculation in AUTH message
+
+        // Length of packet
+        ByteBuffer buf = new ByteBuffer(1024, true);
+
+        TSRequest tsRequest = new TSRequest("TSRequest");
+        tsRequest.version.value = 2L;
+        NegoItem negoItem = new NegoItem("NegoItem");
+        negoItem.negoToken.value = negoToken;
+        tsRequest.negoTokens.tags = new Tag[] {negoItem};
+
+        tsRequest.writeTag(buf);
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    private ByteBuffer generateNegotiateMessage() {
+        ByteBuffer buf = new ByteBuffer(1024);
+
+        // Signature
+        buf.writeString("NTLMSSP", RdpConstants.CHARSET_8);
+        buf.writeByte(0);
+
+        // Message type
+        buf.writeIntLE(NtlmConstants.NEGOTIATE);
+
+        buf.writeIntLE(clientConfigFlags.value); // Flags
+
+        // If the NTLMSSP_NEGOTIATE_VERSION flag is set by the client application,
+        // the Version field MUST be set to the current version (section 2.2.2.10),
+        // the DomainName field MUST be set to a zero-length string, and the
+        // Workstation field MUST be set to a zero-length string.
+
+        // Domain: ""
+        buf.writeShortLE(0); // Length
+        buf.writeShortLE(0); // Allocated space
+        buf.writeIntLE(0); // Offset
+
+        // Workstation: ""
+        buf.writeShortLE(0); // Length
+        buf.writeShortLE(0); // Allocated space
+        buf.writeIntLE(0); // Offset
+
+        // OS Version: 6.1 (Build 7601); NTLM Current Revision 15
+        buf.writeBytes(new byte[] {(byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f});
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        return buf;
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+          // CredSSP BER header:
+
+          (byte)0x30, // Sequence
+          (byte)0x37, // Length, 55 bytes
+
+          (byte)0xa0, (byte)0x03, // TAG: [0] (constructed) LEN: 3 byte
+          (byte)0x02, (byte)0x01, (byte)0x02, // Version: (int, 1 byte, 0x02)
+
+          // Sequence of sequence
+          (byte)0xa1, (byte)0x30, // TAG: [1] (constructed) LEN: 48 bytes
+          (byte)0x30, (byte)0x2e, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 46 bytes
+          (byte)0x30, (byte)0x2c, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 44 bytes
+          (byte)0xa0, (byte)0x2a, // TAG: [0] (constructed) LEN: 42 bytes
+
+
+          (byte)0x04, (byte)0x28, // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 40 bytes
+
+          // NTLM negotiate request
+
+          (byte)0x4e, (byte)0x54, (byte)0x4c, (byte)0x4d, (byte)0x53, (byte)0x53, (byte)0x50, (byte)0x00, // "NTLMSSP\0"
+
+          (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, // Message type: NEGOTIATE (0x1, LE) 
+
+          (byte)0xb7, (byte)0x82, (byte)0x08, (byte)0xe2, // Flags: 0xe20882b7 (LE)
+
+          (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Domain (security buffer, 8bit, 8 bytes): length: 0x0000 (LE), allocated space: 0x0000 (LE), offset: 0x00000000 (LE)
+          (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Workstation  (security buffer, 8bit, 8 bytes): length: 0x0000 (LE), allocated space: 0x0000 (LE), offset: 0x00000000 (LE)
+          (byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f, // OS Version: 6.1 (Build 7601); NTLM Current Revision 15, 8 bytes
+        
+    };
+    /* @formatter:on */
+
+        NtlmState state = new NtlmState();
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element ntlmssp_negotiate = new ClientNtlmsspNegotiate("ntlmssp_negotiate", state);
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, ntlmssp_negotiate, sink, mainSink);
+        pipeline.link("source", "ntlmssp_negotiate", "mainSink");
+        pipeline.link("ntlmssp_negotiate >" + OTOUT, "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java
new file mode 100755
index 0000000..3d9e0c5
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java
@@ -0,0 +1,681 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp;
+
+import java.nio.charset.Charset;
+
+import rdpclient.ntlmssp.asn1.NegoItem;
+import rdpclient.ntlmssp.asn1.SubjectPublicKeyInfo;
+import rdpclient.ntlmssp.asn1.TSRequest;
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.Dumper;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+import streamer.ssl.SSLState;
+
+import common.asn1.Tag;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc236643.aspx
+ */
+public class ClientNtlmsspPubKeyAuth extends OneTimeSwitch implements NtlmConstants, Dumper {
+
+    /**
+     * Offset of first byte of allocated block after NTLMSSP header and block
+     * descriptors.
+     */
+    private static final int BLOCKS_OFFSET = 88;
+
+    protected NtlmState ntlmState;
+    protected SSLState sslState;
+
+    protected String targetDomain;
+    protected String user;
+    protected String password;
+    protected String workstation;
+    protected String serverHostName;
+
+    public ClientNtlmsspPubKeyAuth(String id, NtlmState ntlmState, SSLState sslState, String serverHostName, String targetDomain, String workstation,
+            String user, String password) {
+        super(id);
+        this.ntlmState = ntlmState;
+        this.sslState = sslState;
+        this.serverHostName = serverHostName;
+        this.targetDomain = targetDomain;
+        this.workstation = workstation;
+        this.user = user;
+        this.password = password;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        /*
+         * @see
+         * http://blogs.msdn.com/b/openspecification/archive/2010/04/20/ntlm-keys
+         * -and-sundry-stuff.aspx
+         */
+        ntlmState.domain = this.targetDomain;
+        ntlmState.user = this.user;
+        ntlmState.password = this.password;
+        ntlmState.workstation = this.workstation;
+        ntlmState.generateServicePrincipalName(serverHostName);
+        ntlmState.ntlm_construct_authenticate_target_info();
+        ntlmState.ntlm_generate_timestamp();
+        ntlmState.ntlm_generate_client_challenge();
+        ntlmState.ntlm_compute_lm_v2_response();
+        ntlmState.ntlm_compute_ntlm_v2_response();
+        ntlmState.ntlm_generate_key_exchange_key();
+        ntlmState.ntlm_generate_random_session_key();
+        ntlmState.ntlm_generate_exported_session_key();
+        ntlmState.ntlm_encrypt_random_session_key();
+        ntlmState.ntlm_init_rc4_seal_states();
+
+        ByteBuffer authenticateMessage = generateAuthenticateMessage(ntlmState);
+        ByteBuffer messageSignatureAndEncryptedServerPublicKey = generateMessageSignatureAndEncryptedServerPublicKey(ntlmState);
+
+        // Length of packet
+        ByteBuffer buf = new ByteBuffer(4096, true);
+
+        TSRequest tsRequest = new TSRequest("TSRequest");
+        tsRequest.version.value = 2L;
+        NegoItem negoItem = new NegoItem("NegoItem");
+        negoItem.negoToken.value = authenticateMessage;
+
+        tsRequest.negoTokens.tags = new Tag[] {negoItem};
+
+        tsRequest.pubKeyAuth.value = messageSignatureAndEncryptedServerPublicKey;
+
+        tsRequest.writeTag(buf);
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    private byte[] getServerPublicKey() {
+        // SSL certificate public key with algorithm
+        ByteBuffer subjectPublicKeyInfo = new ByteBuffer(sslState.serverCertificateSubjectPublicKeyInfo);
+
+        // Parse subjectPublicKeyInfo
+        SubjectPublicKeyInfo parser = new SubjectPublicKeyInfo("SubjectPublicKeyInfo");
+        parser.readTag(subjectPublicKeyInfo);
+
+        // Copy subjectPublicKey subfield to separate byte buffer
+        ByteBuffer subjectPublicKey = new ByteBuffer(subjectPublicKeyInfo.length);
+        parser.subjectPublicKey.writeTag(subjectPublicKey);
+
+        subjectPublicKeyInfo.unref();
+        subjectPublicKey.trimAtCursor();
+
+        // Skip tag:
+        // 03 82 01 0f (tag) 00 (padding byte)
+        subjectPublicKey.trimHeader(5);// FIXME: parse it properly
+        // * DEBUG */System.out.println("DEBUG: subjectPublicKey:\n" +
+        // subjectPublicKey.dump());
+
+        ntlmState.subjectPublicKey = subjectPublicKey.toByteArray();
+
+        return ntlmState.subjectPublicKey;
+    }
+
+    /**
+     * The client encrypts the public key it received from the server (contained
+     * in the X.509 certificate) in the TLS handshake from step 1, by using the
+     * confidentiality support of SPNEGO.
+     * 
+     * The public key that is encrypted is the ASN.1-encoded SubjectPublicKey
+     * sub-field of SubjectPublicKeyInfo from the X.509 certificate, as specified
+     * in [RFC3280] section 4.1. The encrypted key is encapsulated in the
+     * pubKeyAuth field of the TSRequest structure and is sent over the TLS
+     * channel to the server.
+     */
+    private ByteBuffer generateMessageSignatureAndEncryptedServerPublicKey(NtlmState ntlmState) {
+        return new ByteBuffer(ntlmState.ntlm_EncryptMessage(getServerPublicKey()));
+    }
+
+    public static ByteBuffer generateAuthenticateMessage(NtlmState ntlmState) {
+
+        // Allocate memory for blocks from given fixed offset
+        int blocksCursor = BLOCKS_OFFSET;
+
+        ByteBuffer buf = new ByteBuffer(4096);
+
+        // Signature: "NTLMSSP\0"
+        buf.writeString(NTLMSSP, RdpConstants.CHARSET_8);
+        buf.writeByte(0);
+
+        // NTLM Message Type: NTLMSSP_AUTH (0x00000003)
+        buf.writeIntLE(NtlmConstants.NTLMSSP_AUTH);
+
+        // Although the protocol allows authentication to succeed if the client
+        // provides either LmChallengeResponse or NtChallengeResponse, Windows
+        // implementations provide both.
+
+        // LM V2 response
+        blocksCursor = writeBlock(buf, ntlmState.lmChallengeResponse, blocksCursor);
+
+        // NT v2 response
+        blocksCursor = writeBlock(buf, ntlmState.ntChallengeResponse, blocksCursor);
+
+        // DomainName
+        blocksCursor = writeStringBlock(buf, ntlmState.domain, blocksCursor, RdpConstants.CHARSET_16);
+
+        // UserName
+        blocksCursor = writeStringBlock(buf, ntlmState.user, blocksCursor, RdpConstants.CHARSET_16);
+
+        // Workstation
+        blocksCursor = writeStringBlock(buf, ntlmState.workstation, blocksCursor, RdpConstants.CHARSET_16);
+
+        // EncryptedRandomSessionKey, 16 bytes
+        blocksCursor = writeBlock(buf, ntlmState.encryptedRandomSessionKey, blocksCursor);
+
+        // NegotiateFlags (4 bytes): In connection-oriented mode, a NEGOTIATE
+        // structure that contains the set of bit flags (section 2.2.2.5) negotiated
+        // in the previous messages.
+        buf.writeIntLE(/*ntlmState.negotiatedFlags.value*/0xe288b235); // FIXME: remove hardcoded value
+
+        buf.writeBytes(generateVersion());
+
+        // If the CHALLENGE_MESSAGE TargetInfo field (section 2.2.1.2) has an
+        // MsvAvTimestamp present, the client SHOULD provide a MIC(Message Integrity
+        // Check)
+
+        int savedCursorForMIC = buf.cursor; // Save cursor position to write MIC
+                                            // later
+        buf.writeBytes(new byte[16]); // Write 16 zeroes
+
+        if (BLOCKS_OFFSET != buf.cursor)
+            throw new RuntimeException("BUG: Actual offset of first byte of allocated blocks is not equal hardcoded offset. Hardcoded offset: " + BLOCKS_OFFSET
+                    + ", actual offset: " + buf.cursor + ". Update hardcoded offset to match actual offset.");
+
+        buf.cursor = blocksCursor;
+        buf.trimAtCursor();
+
+        ntlmState.authenticateMessage = buf.toByteArray();
+
+        // Calculate and write MIC to reserved position
+        ntlmState.ntlm_compute_message_integrity_check();
+        buf.cursor = savedCursorForMIC;
+        buf.writeBytes(ntlmState.messageIntegrityCheck);
+        buf.rewindCursor();
+
+        return buf;
+    }
+
+    /**
+     * Write string as security buffer, using given charset, without trailing '\0'
+     * character.
+     */
+    private static int writeStringBlock(ByteBuffer buf, String string, int blocksCursor, Charset charset) {
+        return writeBlock(buf, string.getBytes(charset), blocksCursor);
+    }
+
+    /**
+     * Write block to blocks buffer and block descriptor to main buffer.
+     */
+    private static int writeBlock(ByteBuffer buf, byte[] block, int blocksCursor) {
+
+        // Write block descriptor
+
+        // Length
+        buf.writeShortLE(block.length);
+        // Allocated
+        buf.writeShortLE(block.length);
+        // Offset
+        buf.writeIntLE(blocksCursor);
+
+        // Write block to position pointed by blocksCursor instead of buf.cursor
+        int savedCursor = buf.cursor;
+        buf.cursor = blocksCursor;
+        buf.writeBytes(block);
+        blocksCursor = buf.cursor;
+        buf.cursor = savedCursor;
+
+        return blocksCursor;
+    }
+
+    /**
+     * Version (8 bytes): A VERSION structure (section 2.2.2.10) that is present
+     * only when the NTLMSSP_NEGOTIATE_VERSION flag is set in the NegotiateFlags
+     * field. This structure is used for debugging purposes only. In normal
+     * protocol messages, it is ignored and does not affect the NTLM message
+     * processing.
+     */
+    private static byte[] generateVersion() {
+        // Version (6.1, Build 7601), NTLM current revision: 15
+        return new byte[] {0x06, 0x01, (byte)0xb1, 0x1d, 0x00, 0x00, 0x00, 0x0f};
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        System.setProperty("streamer.Element.debug", "true");
+
+        /* @formatter:off */
+    //
+ // Client NEGOTIATE
+ //
+    byte[] clientNegotiatePacket = new byte[] {
+        (byte)0x30, (byte)0x37, (byte)0xa0, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0xa1, (byte)0x30, (byte)0x30, (byte)0x2e, (byte)0x30, (byte)0x2c, (byte)0xa0, (byte)0x2a, (byte)0x04,
+        (byte)0x28, (byte)0x4e, (byte)0x54, (byte)0x4c, (byte)0x4d, (byte)0x53, (byte)0x53, (byte)0x50, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xb7, (byte)0x82, (byte)0x08,
+        (byte)0xe2, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f,
+    };
+    
+//
+// Server CHALLENGE
+//
+    byte[] serverChallengePacket = new byte[] {
+        0x30, (byte) 0x82, 0x01, 0x02, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 258 bytes
+
+        (byte) 0xa0, 0x03, // TAG: [0] (constructed) LEN: 3 bytes
+        0x02, 0x01, 0x03,  // TAG: [UNIVERSAL 2] (primitive) "INTEGER" LEN: 1 bytes, Version: 0x3
+        (byte) 0xa1, (byte) 0x81, (byte) 0xfa, // TAG: [1] (constructed) LEN: 250 bytes
+        0x30, (byte) 0x81, (byte) 0xf7, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 247 bytes
+        0x30, (byte) 0x81, (byte) 0xf4, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 244 bytes
+        (byte) 0xa0, (byte) 0x81, (byte) 0xf1, // TAG: [0] (constructed) LEN: 241 bytes
+        0x04, (byte) 0x81, (byte) 0xee, // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 238 bytes
+
+        0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, // "NTLMSSP\0"
+
+        0x02, 0x00, 0x00, 0x00, // MessageType (CHALLENGE) 
+
+        0x1e, 0x00, 0x1e, 0x00, 0x38, 0x00, 0x00, 0x00, // TargetName (length: 30, allocated space: 30, offset: 56)
+        0x35, (byte) 0x82, (byte) 0x8a, (byte) 0xe2, // NegotiateFlags: NEGOTIATE_56 NEGOTIATE_KEY_EXCH NEGOTIATE_128 NEGOTIATE_VERSION NEGOTIATE_TARGET_INFO NEGOTIATE_EXTENDED_SESSION_SECURITY TARGET_TYPE_SERVER NEGOTIATE_ALWAYS_SIGN NEGOTIATE_NTLM NEGOTIATE_SEAL NEGOTIATE_SIGN REQUEST_TARGET NEGOTIATE_UNICODE
+
+        (byte)0xc1, (byte)0x4a, (byte)0xc8, (byte)0x98, (byte)0x2f, (byte)0xd1, (byte)0x93, (byte)0xd4, //  ServerChallenge 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  Reserved
+        (byte) 0x98, 0x00, (byte) 0x98, 0x00, 0x56, 0x00, 0x00, 0x00, // TargetInfo (length: 152, allocated space: 152, offset: 86)
+        0x06, 0x03, (byte) 0xd7, 0x24, 0x00, 0x00, 0x00, 0x0f,  // Version (6.3, build 9431) , NTLM current revision: 15
+
+
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00,  // Target name value: "WIN-LO419B2LSR0"
+
+        // Target Info value:
+        
+        // Attribute list
+
+        0x02, 0x00, // Item Type: NetBIOS domain name (0x0002, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x01, 0x00,  //  Item Type: NetBIOS computer name (0x0001, LE) 
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x04, 0x00,  // Item Type: DNS domain name (0x0004, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x03, 0x00,  // Item Type: DNS computer name (0x0003, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x07, 0x00,  // Item Type: Timestamp (0x0007, LE)
+        0x08, 0x00, //  Item Length: 8 (LE)
+        (byte)0x1d, (byte)0xea, (byte)0x6b, (byte)0x60, (byte)0xf8, (byte)0xc5, (byte)0xce, (byte)0x01, // Time: Oct 10, 2013 23:36:20.056937300 EEST
+
+        // Attribute: End of list
+        0x00, 0x00,
+        0x00, 0x00, 
+
+    };
+  
+//
+// Client NTLMSSP_AUTH
+//
+    byte[] clientAuthPacket = new byte[] {
+        0x30, (byte) 0x82, 0x03, 0x13, //  TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 787 bytes
+
+        //
+        // TSRequest.version
+        // 
+        (byte) 0xa0, 0x03, //  TAG: [0] (constructed) LEN: 3 bytes
+        0x02, 0x01, 0x02, //  TAG: [UNIVERSAL 2] (primitive) "INTEGER" LEN: 1 bytes
+
+        //
+        // TSRequest.negoData
+        // 
+        (byte) 0xa1, (byte) 0x82, 0x01, (byte) 0xe4, //  TAG: [1] (constructed) LEN: 484 bytes
+        0x30, (byte) 0x82, 0x01, (byte) 0xe0, //  TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 480 bytes
+        0x30, (byte) 0x82, 0x01, (byte) 0xdc, //  TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 476 bytes
+
+        //
+        // NegoItem.negoToken
+        // 
+        (byte) 0xa0, (byte) 0x82, 0x01, (byte) 0xd8, //  TAG: [0] (constructed) LEN: 472 bytes
+        0x04, (byte) 0x82, 0x01, (byte) 0xd4,  // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 468 bytes
+
+        // NTLMSSP
+
+        0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, //  "NTLMSSP\0"
+
+        0x03, 0x00, 0x00, 0x00, //  NTLM Message Type: NTLMSSP_AUTH (0x00000003)
+        0x18, 0x00, 0x18, 0x00, (byte) 0x92, 0x00, 0x00, 0x00, //  LmChallengeResponse (length 24, allocated: 24, offset 146)
+        0x1a, 0x01, 0x1a, 0x01, (byte) 0xaa, 0x00, 0x00, 0x00, //  NtChallengeResponse (length 282, allocated: 282, offset 170) 
+        0x12, 0x00, 0x12, 0x00, 0x58, 0x00, 0x00, 0x00,  // DomainName (length 18, allocated: 88, offset 88) 
+        0x1a, 0x00, 0x1a, 0x00, 0x6a, 0x00, 0x00, 0x00,  // UserName (length 26, allocated:26, offset 106) 
+        0x0e, 0x00, 0x0e, 0x00, (byte) 0x84, 0x00, 0x00, 0x00,  // Workstation (length 14, offset 132) 
+        0x10, 0x00, 0x10, 0x00, (byte) 0xc4, 0x01, 0x00, 0x00,  // EncryptedRandomSessionKey (length 16, offset 452) 
+        0x35, (byte) 0xb2, (byte) 0x88, (byte) 0xe2,   // NegotiateFlags
+        0x06, 0x01, (byte) 0xb1, 0x1d, 0x00, 0x00, 0x00, 0x0f, //  Version (6.1, Build 7601), NTLM current revision: 15
+
+        (byte)0x8c, (byte)0x69, (byte)0x53, (byte)0x1c, (byte)0xbb, (byte)0x6f, (byte)0xfb, (byte)0x9a, (byte)0x5d, (byte)0x2c, (byte)0x63, (byte)0xf2, (byte)0xc9, (byte)0x51, (byte)0xc5, (byte)0x11, // Message integrity check
+
+        0x77, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x67, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x70, 0x00, // Domain name value: "Workgroup"
+
+        0x41, 0x00, 0x64, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x72, 0x00,  // User name value: "Administrator"
+
+        0x61, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x33, 0x00, //  Workstation host name value: "apollo3"
+
+        // Lan manager challenge response value
+        // Response: HMAC_MD(ResponseKeyLM, concatenate(ServerChallenge, ClientChallenge), where ResponseKeyLM=ntlmv2Hash(target, user, password)
+        (byte)0x17, (byte)0x9b, (byte)0x7d, (byte)0x7b, (byte)0x2f, (byte)0x79, (byte)0x9f, (byte)0x19, (byte)0xa0, (byte)0x4b, (byte)0x00, (byte)0xed, (byte)0x2b, (byte)0x39, (byte)0xbb, (byte)0x23,
+        // Client challenge (fixed for debugging)
+        (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08,
+
+        //
+        // NTLM challenge response value:
+        //
+
+        (byte)0x49, (byte)0xea, (byte)0x27, (byte)0x4f, (byte)0xcc, (byte)0x05, (byte)0x8b, (byte)0x79, (byte)0x20, (byte)0x0b, (byte)0x08, (byte)0x42, (byte)0xa9, (byte)0xc8, (byte)0x0e, (byte)0xc7, //  HMAC
+
+        0x01, 0x01, 0x00, 0x00, // Header: 0x00000101 (LE)
+        0x00, 0x00, 0x00, 0x00, // Reserved: 0x00000000
+        (byte)0x1d, (byte)0xea, (byte)0x6b, (byte)0x60, (byte)0xf8, (byte)0xc5, (byte)0xce, (byte)0x01, // Time: Oct 10, 2013 23:36:20.056937300 EEST
+        (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, // Client challenge (fixed)
+        0x00, 0x00, 0x00, 0x00, //  Reserved
+
+        // Target Info value:
+        
+        // Attribute list
+
+        0x02, 0x00, // Item Type: NetBIOS domain name (0x0002, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00,  //  "WIN-LO419B2LSR0 "
+
+        0x01, 0x00,  //  Item Type: NetBIOS computer name (0x0001, LE) 
+        0x1e, 0x00,  // Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, //  "WIN-LO419B2LSR0 "
+
+        0x04, 0x00,  // Item Type: DNS domain name (0x0004, LE)
+        0x1e, 0x00,  // Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, //  "WIN-LO419B2LSR0 "
+
+        0x03, 0x00,  // Item Type: DNS computer name (0x0003, LE)
+        0x1e, 0x00,  // Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, //  "WIN-LO419B2LSR0 "
+
+        0x07, 0x00,  // Item Type: Timestamp (0x0007, LE)
+        0x08, 0x00,  // Item Length: 8 (LE)
+        (byte)0x1d, (byte)0xea, (byte)0x6b, (byte)0x60, (byte)0xf8, (byte)0xc5, (byte)0xce, (byte)0x01, // Timestamp: Oct 10, 2013 23:36:20.056937300 EEST
+
+        0x06, 0x00,  // Item Type: Flags (0x0006, LE)
+        0x04, 0x00, // Item Length: 4 (LE)
+        0x02, 0x00, 0x00, 0x00, // Flags: 0x00000002
+
+        0x0a, 0x00, // Item Type: Channel Bindings (0x000a, LE)
+        0x10, 0x00, // Item Length: 16 (LE) 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Channel Bindings: 00000000000000000000000000000000
+
+        0x09, 0x00, // Item Type: Target Name (0x0009, LE)
+        0x2a, 0x00, // Item Length: 42 (LE)
+        0x54, 0x00, 0x45, 0x00, 0x52, 0x00, 0x4d, 0x00, 0x53, 0x00, 0x52, 0x00, 0x56, 0x00, 0x2f, 0x00, 0x31, 0x00, 0x39, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00, 0x38, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x30, 0x00, 0x31, 0x00, // Target Name: "TERMSRV/192.168.0.101" (UTF-16)
+
+        // Attribute: End of list
+        0x00, 0x00,  // 
+        0x00, 0x00,  // 
+        // Attribute: End of list
+        0x00, 0x00,  // 
+        0x00, 0x00,  // 
+        // Attribute: End of list
+        0x00, 0x00,  // 
+        0x00, 0x00,  // 
+        // Attribute: End of list
+        0x00, 0x00,  // 
+        0x00, 0x00,  // 
+
+        // Session Key
+        // RC4 key (Server KeyExchangeKey or SessionBaseKey):
+        // 6e bd e3 da 83 c2 fd f1 38 a2 78 be 8c e6 75 d6
+        //
+        // RC4 data (Client nonce):
+        // 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10
+        //
+        // RC4 encrypted:
+        // 2c 24 da 10 17 cf 40 69 35 49 6f 58 e1 29 9e 79
+        (byte)0x2c, (byte)0x24, (byte)0xda, (byte)0x10, (byte)0x17, (byte)0xcf, (byte)0x40, (byte)0x69, (byte)0x35, (byte)0x49, (byte)0x6f, (byte)0x58, (byte)0xe1, (byte)0x29, (byte)0x9e, (byte)0x79,
+
+        //
+        // TSRequest.publicKey 
+        // 
+        (byte) 0xa3, (byte) 0x82, 0x01, 0x22, // TAG: [3] (constructed) LEN: 290 bytes 
+        0x04, (byte) 0x82, 0x01, 0x1e,  // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 286 bytes
+
+        // NTLMSSP_MESSAGE_SIGNATURE, @see http://msdn.microsoft.com/en-us/library/cc422952.aspx
+        
+        // Version: 0x00000001
+        (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,  
+        
+        // Checksum (8 bytes): An 8-byte array that contains the checksum for the message.
+        (byte)0x72, (byte)0x76, (byte)0x1e, (byte)0x57, (byte)0x49, (byte)0xb5, (byte)0x0f, (byte)0xad, 
+        
+        // seqNum of the message: 0
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+        
+        // Encrypted public key
+        (byte)0x15, (byte)0xf7, (byte)0xf2, (byte)0x54, (byte)0xda, (byte)0xa9, (byte)0xe5, (byte)0xad, (byte)0x85, (byte)0x04, (byte)0x67, (byte)0x4d, (byte)0x0b, (byte)0xcb, (byte)0xf9, (byte)0xb1,
+        (byte)0xf8, (byte)0x02, (byte)0x8a, (byte)0x77, (byte)0xc2, (byte)0x63, (byte)0xab, (byte)0xd5, (byte)0x74, (byte)0x23, (byte)0x9f, (byte)0x9d, (byte)0x5d, (byte)0x1f, (byte)0xd3, (byte)0xb3,
+        (byte)0xa0, (byte)0xac, (byte)0x16, (byte)0x8a, (byte)0x4b, (byte)0x08, (byte)0xf5, (byte)0x47, (byte)0x70, (byte)0x58, (byte)0x10, (byte)0xb4, (byte)0xe7, (byte)0x87, (byte)0xb3, (byte)0x4b,
+        (byte)0xc9, (byte)0xa2, (byte)0xd5, (byte)0xd1, (byte)0xca, (byte)0x0f, (byte)0xd4, (byte)0xe3, (byte)0x8d, (byte)0x76, (byte)0x5a, (byte)0x60, (byte)0x28, (byte)0xf8, (byte)0x06, (byte)0x5d,
+        (byte)0xe4, (byte)0x7e, (byte)0x21, (byte)0xc8, (byte)0xbb, (byte)0xac, (byte)0xe5, (byte)0x79, (byte)0x85, (byte)0x30, (byte)0x9b, (byte)0x88, (byte)0x13, (byte)0x2f, (byte)0x8f, (byte)0xfc,
+        (byte)0x04, (byte)0x52, (byte)0xfe, (byte)0x87, (byte)0x94, (byte)0xcf, (byte)0xcb, (byte)0x49, (byte)0x4a, (byte)0xda, (byte)0x6f, (byte)0xdd, (byte)0xee, (byte)0x57, (byte)0xa5, (byte)0xe4,
+        (byte)0x4d, (byte)0x0e, (byte)0x5c, (byte)0x3d, (byte)0x0b, (byte)0x63, (byte)0x1f, (byte)0xf6, (byte)0x3d, (byte)0x1b, (byte)0xae, (byte)0x5a, (byte)0xf6, (byte)0x42, (byte)0x2a, (byte)0x46,
+        (byte)0xfa, (byte)0x42, (byte)0x71, (byte)0x67, (byte)0x46, (byte)0x02, (byte)0x71, (byte)0xea, (byte)0x51, (byte)0x98, (byte)0xf7, (byte)0xd4, (byte)0x43, (byte)0xbf, (byte)0x8e, (byte)0xe8,
+        (byte)0x3c, (byte)0xc8, (byte)0xfa, (byte)0x79, (byte)0x9d, (byte)0x8c, (byte)0xfc, (byte)0xc2, (byte)0x42, (byte)0xc9, (byte)0xbb, (byte)0xd0, (byte)0xab, (byte)0x81, (byte)0xc4, (byte)0x53,
+        (byte)0xfd, (byte)0x41, (byte)0xda, (byte)0xab, (byte)0x0f, (byte)0x25, (byte)0x79, (byte)0x5f, (byte)0xbd, (byte)0xa3, (byte)0x8c, (byte)0xd3, (byte)0xf5, (byte)0x1b, (byte)0xab, (byte)0x20,
+        (byte)0xd1, (byte)0xf4, (byte)0xd8, (byte)0x81, (byte)0x9c, (byte)0x18, (byte)0x4a, (byte)0xa4, (byte)0x77, (byte)0xee, (byte)0xe1, (byte)0x51, (byte)0xee, (byte)0x2a, (byte)0xc1, (byte)0x94,
+        (byte)0x37, (byte)0xc5, (byte)0x06, (byte)0x7a, (byte)0x3f, (byte)0x0f, (byte)0x25, (byte)0x5b, (byte)0x4e, (byte)0x6a, (byte)0xdc, (byte)0x0b, (byte)0x62, (byte)0x6f, (byte)0x12, (byte)0x83,
+        (byte)0x03, (byte)0xae, (byte)0x4e, (byte)0xce, (byte)0x2b, (byte)0x6e, (byte)0xd4, (byte)0xd5, (byte)0x23, (byte)0x27, (byte)0xf6, (byte)0xa6, (byte)0x38, (byte)0x67, (byte)0xec, (byte)0x95,
+        (byte)0x82, (byte)0xc6, (byte)0xba, (byte)0xd4, (byte)0xf6, (byte)0xe6, (byte)0x22, (byte)0x7d, (byte)0xb9, (byte)0xe4, (byte)0x81, (byte)0x97, (byte)0x24, (byte)0xff, (byte)0x40, (byte)0xb2,
+        (byte)0x42, (byte)0x3c, (byte)0x11, (byte)0x24, (byte)0xd0, (byte)0x3a, (byte)0x96, (byte)0xd9, (byte)0xc1, (byte)0x13, (byte)0xd6, (byte)0x62, (byte)0x45, (byte)0x21, (byte)0x60, (byte)0x5b,
+        (byte)0x7b, (byte)0x2b, (byte)0x62, (byte)0x44, (byte)0xf7, (byte)0x40, (byte)0x93, (byte)0x29, (byte)0x5b, (byte)0x44, (byte)0xb7, (byte)0xda, (byte)0x9c, (byte)0xa6, (byte)0xa9, (byte)0x3b,
+        (byte)0xe1, (byte)0x3b, (byte)0x9d, (byte)0x31, (byte)0xf2, (byte)0x21, (byte)0x53, (byte)0x0f, (byte)0xb3, (byte)0x70, (byte)0x55, (byte)0x84, (byte)0x2c, (byte)0xb4,
+    };
+
+    SSLState sslState = new SSLState();
+    
+    sslState.serverCertificateSubjectPublicKeyInfo = new byte[] {
+      0x30, (byte) 0x82, 0x01, 0x22, // Sequence, length: 290 bytes 
+        0x30, 0x0d, // Sequence, length: 13 bytes {
+          0x06, 0x09, // Object ID, length: 9 bytes
+          0x2a, (byte) 0x86, 0x48, (byte) 0x86, (byte) 0xf7, 0x0d, 0x01, 0x01, 0x01, 
+          0x05, 0x00, // NULL, length: 0 bytes
+        
+          (byte)0x03, (byte)0x82, (byte)0x01, (byte)0x0f, // Bit string, length: 271 bytes
+          
+          (byte)0x00, // Pading 
+          (byte)0x30, (byte)0x82, (byte)0x01, (byte)0x0a, // Sequence
+          (byte)0x02, (byte)0x82, (byte)0x01, (byte)0x01, // Integer, length: 257 bytes 
+          
+          (byte)0x00, (byte)0xa8, (byte)0x56,
+          (byte)0x65, (byte)0xd3, (byte)0xce, (byte)0x8a, (byte)0x54, (byte)0x4d, (byte)0x9d, (byte)0xb0,
+          (byte)0x84, (byte)0x31, (byte)0x19, (byte)0x71, (byte)0x7f, (byte)0xdd, (byte)0x42, (byte)0xfb,
+          (byte)0x2a, (byte)0x7a, (byte)0x72, (byte)0x13, (byte)0xa1, (byte)0xb9, (byte)0x72, (byte)0xbb,
+          (byte)0xd3, (byte)0x08, (byte)0xad, (byte)0x7d, (byte)0x6c, (byte)0x15, (byte)0x65, (byte)0x03,
+          (byte)0xd1, (byte)0xc4, (byte)0x54, (byte)0xc5, (byte)0x33, (byte)0x6b, (byte)0x7d, (byte)0x69,
+          (byte)0x89, (byte)0x5e, (byte)0xfe, (byte)0xe0, (byte)0x01, (byte)0xc0, (byte)0x7e, (byte)0x9b,
+          (byte)0xcb, (byte)0x5d, (byte)0x65, (byte)0x36, (byte)0xcd, (byte)0x77, (byte)0x5d, (byte)0xf3,
+          (byte)0x7a, (byte)0x5b, (byte)0x29, (byte)0x44, (byte)0x72, (byte)0xd5, (byte)0x38, (byte)0xe2,
+          (byte)0xcf, (byte)0xb1, (byte)0xc7, (byte)0x78, (byte)0x9b, (byte)0x58, (byte)0xb9, (byte)0x17,
+          (byte)0x7c, (byte)0xb7, (byte)0xd6, (byte)0xc7, (byte)0xc7, (byte)0xbf, (byte)0x90, (byte)0x4e,
+          (byte)0x7c, (byte)0x39, (byte)0x93, (byte)0xcb, (byte)0x2e, (byte)0xe0, (byte)0xc2, (byte)0x33,
+          (byte)0x2d, (byte)0xa5, (byte)0x7e, (byte)0xe0, (byte)0x7b, (byte)0xb6, (byte)0xf9, (byte)0x91,
+          (byte)0x32, (byte)0xb7, (byte)0xd4, (byte)0x85, (byte)0xb7, (byte)0x35, (byte)0x2d, (byte)0x2b,
+          (byte)0x00, (byte)0x6d, (byte)0xf8, (byte)0xea, (byte)0x8c, (byte)0x97, (byte)0x5f, (byte)0x51,
+          (byte)0x1d, (byte)0x68, (byte)0x04, (byte)0x3c, (byte)0x79, (byte)0x14, (byte)0x71, (byte)0xa7,
+          (byte)0xc7, (byte)0xd7, (byte)0x70, (byte)0x7a, (byte)0xe0, (byte)0xba, (byte)0x12, (byte)0x69,
+          (byte)0xc8, (byte)0xd3, (byte)0xd9, (byte)0x4e, (byte)0xab, (byte)0x51, (byte)0x47, (byte)0xa3,
+          (byte)0xec, (byte)0x99, (byte)0xd4, (byte)0x88, (byte)0xca, (byte)0xda, (byte)0xc2, (byte)0x7f,
+          (byte)0x79, (byte)0x4b, (byte)0x66, (byte)0xed, (byte)0x87, (byte)0xbe, (byte)0xc2, (byte)0x5f,
+          (byte)0xea, (byte)0xcf, (byte)0xe1, (byte)0xb5, (byte)0xf0, (byte)0x3d, (byte)0x9b, (byte)0xf2,
+          (byte)0x19, (byte)0xc3, (byte)0xe0, (byte)0xe1, (byte)0x7a, (byte)0x45, (byte)0x71, (byte)0x12,
+          (byte)0x3d, (byte)0x72, (byte)0x1d, (byte)0x6f, (byte)0x2b, (byte)0x1c, (byte)0x46, (byte)0x68,
+          (byte)0xc0, (byte)0x8f, (byte)0x4f, (byte)0xce, (byte)0x3a, (byte)0xc5, (byte)0xcd, (byte)0x22,
+          (byte)0x65, (byte)0x2d, (byte)0x43, (byte)0xb0, (byte)0x5c, (byte)0xdd, (byte)0x89, (byte)0xae,
+          (byte)0xbe, (byte)0x70, (byte)0x59, (byte)0x5e, (byte)0x0c, (byte)0xbd, (byte)0xf5, (byte)0x46,
+          (byte)0x82, (byte)0x1e, (byte)0xe4, (byte)0x86, (byte)0x95, (byte)0x7b, (byte)0x60, (byte)0xae,
+          (byte)0x45, (byte)0x50, (byte)0xc2, (byte)0x54, (byte)0x08, (byte)0x49, (byte)0x9a, (byte)0x9e,
+          (byte)0xfb, (byte)0xb2, (byte)0xb6, (byte)0x78, (byte)0xe5, (byte)0x2f, (byte)0x9c, (byte)0x5a,
+          (byte)0xd0, (byte)0x8a, (byte)0x03, (byte)0x77, (byte)0x68, (byte)0x30, (byte)0x93, (byte)0x78,
+          (byte)0x6d, (byte)0x90, (byte)0x6d, (byte)0x50, (byte)0xfa, (byte)0xa7, (byte)0x65, (byte)0xfe,
+          (byte)0x59, (byte)0x33, (byte)0x27, (byte)0x4e, (byte)0x4b, (byte)0xf8, (byte)0x38, (byte)0x44,
+          (byte)0x3a, (byte)0x12, (byte)0xf4, (byte)0x07, (byte)0xa0, (byte)0x8d, (byte)0x02, (byte)0x03,
+          (byte)0x01, (byte)0x00, (byte)0x01,
+    };
+    /* @formatter:on */
+
+        NtlmState ntlmState = new NtlmState();
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(serverChallengePacket, new byte[] {1, 2, 3}));
+        Element ntlmssp_negotiate = new ClientNtlmsspNegotiate("ntlmssp_negotiate", ntlmState);
+        Element ntlmssp_challenge = new ServerNtlmsspChallenge("ntlmssp_challenge", ntlmState);
+        Element ntlmssp_auth = new ClientNtlmsspPubKeyAuth("ntlmssp_auth", ntlmState, sslState, "192.168.0.101", "workgroup", "apollo3", "Administrator",
+                "R2Preview!");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(clientNegotiatePacket, clientAuthPacket), (Dumper)ntlmssp_auth);
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, ntlmssp_negotiate, ntlmssp_challenge, ntlmssp_auth, sink, mainSink);
+        pipeline.link("source", "ntlmssp_negotiate", "ntlmssp_challenge", "ntlmssp_auth", "mainSink");
+        pipeline.link("ntlmssp_negotiate >" + OTOUT, "ntlmssp_negotiate< sink");
+        pipeline.link("ntlmssp_challenge >" + OTOUT, "ntlmssp_challenge< sink");
+        pipeline.link("ntlmssp_auth >" + OTOUT, "ntlmssp_auth< sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+    }
+
+    @Override
+    public void dump(ByteBuffer buf) {
+        buf.rewindCursor();
+        TSRequest request = new TSRequest("TSRequest");
+        request.readTag(buf);
+        System.out.println("TSRequest version: " + request.version.value);
+        System.out.println("TSRequest pubKey: " + request.pubKeyAuth.value.toPlainHexString());
+
+        ByteBuffer negoToken = ((NegoItem)request.negoTokens.tags[0]).negoToken.value;
+        System.out.println("TSRequest negotoken: " + negoToken.toPlainHexString());
+        dumpNegoToken(negoToken);
+
+        negoToken.unref();
+    }
+
+    private void dumpNegoToken(ByteBuffer buf) {
+        String signature = buf.readVariableString(RdpConstants.CHARSET_8);
+        if (!signature.equals(NTLMSSP))
+            throw new RuntimeException("Unexpected NTLM message singature: \"" + signature + "\". Expected signature: \"" + NTLMSSP + "\". Data: " + buf + ".");
+
+        // MessageType (CHALLENGE)
+        int messageType = buf.readSignedIntLE();
+        if (messageType != NtlmConstants.NTLMSSP_AUTH)
+            throw new RuntimeException("Unexpected NTLM message type: " + messageType + ". Expected type: CHALLENGE (" + NtlmConstants.CHALLENGE + "). Data: " + buf
+                    + ".");
+
+        System.out.println("lmChallengeResponseFields: " + ServerNtlmsspChallenge.readBlockByDescription(buf).toPlainHexString());
+        ByteBuffer ntChallengeResponseBuf = ServerNtlmsspChallenge.readBlockByDescription(buf);
+        System.out.println("NtChallengeResponse: " + ntChallengeResponseBuf.toPlainHexString());
+        System.out.println("DomainName: " + ServerNtlmsspChallenge.readStringByDescription(buf));
+        System.out.println("UserName: " + ServerNtlmsspChallenge.readStringByDescription(buf));
+        System.out.println("Workstation: " + ServerNtlmsspChallenge.readStringByDescription(buf));
+        System.out.println("EncryptedRandomSessionKey: " + ServerNtlmsspChallenge.readBlockByDescription(buf).toPlainHexString());
+        System.out.println("NegotiateFlags: " + new NegoFlags(buf.readSignedIntLE()));
+        System.out.println("Version: " + buf.readBytes(8).toPlainHexString());
+
+        dumpNtChallengeResponse(ntChallengeResponseBuf);
+    }
+
+    private void dumpNtChallengeResponse(ByteBuffer buf) {
+        System.out.println("HMAC: " + buf.readBytes(16).toPlainHexString());
+        System.out.format("Header: 0x%08x\n", buf.readUnsignedIntLE());
+        System.out.format("Reserved: 0x%08x\n", buf.readUnsignedIntLE());
+        System.out.println("Time: " + buf.readBytes(8).toPlainHexString());
+        System.out.println("Client challenge: " + buf.readBytes(8).toPlainHexString());
+        System.out.format("Reserved: 0x%08x\n", buf.readUnsignedIntLE());
+
+        // Parse attribute list
+
+        while (buf.remainderLength() > 0) {
+            int type = buf.readUnsignedShortLE();
+            int length = buf.readUnsignedShortLE();
+
+            if (type == MSV_AV_EOL)
+                // End of list
+                break;
+
+            ByteBuffer data = buf.readBytes(length);
+            switch (type) {
+            case MSV_AV_NETBIOS_DOMAIN_NAME:
+                System.out.println("AV Netbios Domain name: " + data.readString(length, RdpConstants.CHARSET_16));
+                break;
+            case MSV_AV_NETBIOS_COMPUTER_NAME:
+                System.out.println("AV Netbios Computer name: " + data.readString(length, RdpConstants.CHARSET_16));
+                break;
+            case MSV_AV_DNS_DOMAIN_NAME:
+                System.out.println("AV DNS Domain name: " + data.readString(length, RdpConstants.CHARSET_16));
+                break;
+            case MSV_AV_DNS_COMPUTER_NAME:
+                System.out.println("AV DNS Computer name: " + data.readString(length, RdpConstants.CHARSET_16));
+                break;
+            case MSV_AV_CHANNEL_BINDINGS:
+                System.out.println("AV Channel Bindings: " + data.readBytes(length).toPlainHexString());
+                break;
+            case MSV_AV_TIMESTAMP:
+                System.out.println("AV Timestamp: " + data.readBytes(length).toPlainHexString());
+                break;
+            case MSV_AV_FLAGS:
+                System.out.println("AV Flags: " + data.readBytes(length).toPlainHexString());
+                break;
+            case MSV_AV_TARGET_NAME:
+                System.out.println("AV Target Name: " + data.readString(length, RdpConstants.CHARSET_16));
+                break;
+            default:
+                System.out.println("Unknown NTLM target info attribute: " + type + ". Data: " + data + ".");
+            }
+            data.unref();
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java
new file mode 100755
index 0000000..50584c3
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java
@@ -0,0 +1,128 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp;
+
+import rdpclient.ntlmssp.asn1.TSCredentials;
+import rdpclient.ntlmssp.asn1.TSPasswordCreds;
+import rdpclient.ntlmssp.asn1.TSRequest;
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ClientNtlmsspUserCredentials extends OneTimeSwitch implements Element {
+
+    protected NtlmState ntlmState;
+
+    public ClientNtlmsspUserCredentials(String id, NtlmState ntlmState) {
+        super(id);
+        this.ntlmState = ntlmState;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        ByteBuffer buf = new ByteBuffer(4096, true);
+
+        TSRequest tsRequest = new TSRequest("TSRequest");
+        tsRequest.version.value = 2L;
+
+        ByteBuffer tsCredentialsBuf = generateTSCredentials();
+        tsRequest.authInfo.value = encryptTSCredentials(tsCredentialsBuf);
+        tsCredentialsBuf.unref();
+
+        tsRequest.writeTag(buf);
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    private ByteBuffer encryptTSCredentials(ByteBuffer buf2) {
+        return new ByteBuffer(ntlmState.ntlm_EncryptMessage(buf2.toByteArray()));
+    }
+
+    private ByteBuffer generateTSCredentials() {
+        ByteBuffer buf = new ByteBuffer(4096);
+
+        TSCredentials tsCredentials = new TSCredentials("authInfo");
+        // 1 means that credentials field contains a TSPasswordCreds structure
+        tsCredentials.credType.value = 1L;
+
+        ByteBuffer tsPasswordCredsBuf = new ByteBuffer(4096, true);
+        TSPasswordCreds tsPasswordCreds = new TSPasswordCreds("credentials");
+        tsPasswordCreds.domainName.value = new ByteBuffer(ntlmState.domain.getBytes(RdpConstants.CHARSET_16));
+        tsPasswordCreds.userName.value = new ByteBuffer(ntlmState.user.getBytes(RdpConstants.CHARSET_16));
+        tsPasswordCreds.password.value = new ByteBuffer(ntlmState.password.getBytes(RdpConstants.CHARSET_16));
+        tsPasswordCreds.writeTag(tsPasswordCredsBuf);
+        tsPasswordCredsBuf.trimAtCursor();
+        //* DEBUG */System.out.println("TSPasswordCreds:\n" + tsPasswordCredsBuf.dump());
+
+        tsCredentials.credentials.value = tsPasswordCredsBuf;
+
+        tsCredentials.writeTag(buf);
+        tsPasswordCredsBuf.unref();
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+        //* DEBUG */System.out.println("TSCredentials:\n" + buf.dump());
+
+        return buf;
+    }
+
+    /**
+     * @param args
+     */
+    public static void main(String[] args) {
+        // TODO Auto-generated method stub
+
+        /* @formatter:off */
+    // TSCredentials
+//  30 57 // Sequence 
+//  a0 03 // TAG 0 
+//  02 01 01 // Integer: 1 : credentials contains a TSPasswordCreds structure
+//  a1 50 // TAG 1
+//  04 4e // OCTETSTRING
+    // TSPasswordCreds
+//  30 4c // SEQUENCE 
+//  a0 14 // TAG 0 
+//  04 12 // OCTETSTRING 
+//  77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 00 70 00 // "workgroup" 
+//  a1 1c // TAG 1 
+//  04 1a // OCTETSTRING
+//  41 00 64 00 6d 00 69 00 6e 00 69 00 73 00 74 00 72 00 61 00 74 00 6f 00 72 00 // "Administrator" 
+//  a2 16 // TAG 2 
+//  04 14 //
+//  52 00 32 00 50 00 72 00 65 00 76 00 69 00 65 00 77 00 21 00 // "R2Preview!"
+  /* @formatter:on */
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java
new file mode 100755
index 0000000..817dbd9
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java
@@ -0,0 +1,361 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp;
+
+import java.lang.reflect.Method;
+import java.security.Key;
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import rdpclient.rdp.RdpConstants;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc236717.aspx
+ */
+public class CryptoAlgos implements NtlmConstants {
+
+    /**
+     * Indicates the left-to-right concatenation of the string parameters, from
+     * the first string to the Nnth. Any numbers are converted to strings and all
+     * numeric conversions to strings retain all digits, even nonsignificant ones.
+     * The result is a string. For example, ConcatenationOf(0x00122, "XYZ",
+     * "Client") results in the string "00122XYZClient."
+     */
+    public static String concatenationOf(String... args) {
+        StringBuffer sb = new StringBuffer();
+        for (String arg : args) {
+            sb.append(arg);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Concatenate byte arrays.
+     */
+    public static byte[] concatenationOf(byte[]... arrays) {
+        int length = 0;
+        for (byte[] array : arrays) {
+            length += array.length;
+        }
+
+        byte[] result = new byte[length];
+        int destPos = 0;
+        for (byte[] array : arrays) {
+            System.arraycopy(array, 0, result, destPos, array.length);
+            destPos += array.length;
+        }
+
+        return result;
+    }
+
+    /** Indicates a 32-bit CRC calculated over M. */
+    public static byte[] CRC32(byte[] M) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Indicates the encryption of an 8-byte data item D with the 7-byte key K
+     * using the Data Encryption Standard (DES) algorithm in Electronic Codebook
+     * (ECB) mode. The result is 8 bytes in length ([FIPS46-2]).
+     */
+    public static byte[] DES(byte[] K, byte[] D) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Indicates the encryption of an 8-byte data item D with the 16-byte key K
+     * using the Data Encryption Standard Long (DESL) algorithm. The result is 24
+     * bytes in length. DESL(K, D) is computed as follows.
+     * 
+     * <pre>
+     *   ConcatenationOf( DES(K[0..6], D), 
+     *     DES(K[7..13], D), DES(  
+     *       ConcatenationOf(K[14..15], Z(5)), D));
+     * </pre>
+     * 
+     * Note K[] implies a key represented as a character array.
+     */
+    public static byte[] DESL(byte[] K, byte[] D) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * An auxiliary function that returns an operating system version-specific
+     * value (section 2.2.2.8).
+     */
+    public static byte[] getVersion() {
+        // Version (6.1, Build 7601), NTLM current revision: 15
+        return new byte[] {0x06, 0x01, (byte)0xb1, 0x1d, 0x00, 0x00, 0x00, 0x0f};
+    }
+
+    /**
+     * Retrieve the user's LM response key from the server database (directory or
+     * local database).
+     */
+    public static byte[] LMGETKEY(byte[] U, byte[] D) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /** Retrieve the user's NT response key from the server database. */
+    public static byte[] NTGETKEY(byte[] U, byte[] D) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Indicates the encryption of data item M with the key K using the HMAC
+     * algorithm ([RFC2104]).
+     */
+    public static byte[] HMAC(byte[] K, byte[] M) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Indicates the computation of a 16-byte HMAC-keyed MD5 message digest of the
+     * byte string M using the key K.
+     */
+    public static byte[] HMAC_MD5(byte[] K, byte[] M) {
+        try {
+            String algorithm = "HMacMD5";
+            Mac hashMac = Mac.getInstance(algorithm);
+
+            Key secretKey = new SecretKeySpec(K, 0, K.length, algorithm);
+            hashMac.init(secretKey);
+            return hashMac.doFinal(M);
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot calculate HMAC-MD5.", e);
+        }
+    }
+
+    /**
+     * Produces a key exchange key from the session base key K, LM response and
+     * server challenge SC as defined in the sections KXKEY, SIGNKEY, and SEALKEY.
+     */
+    public static byte[] KXKEY(byte[] sessionBaseKey/*K, byte[] LM, byte[] SC*/) {
+        // Key eXchange Key is server challenge
+        /* In NTLMv2, KeyExchangeKey is the 128-bit SessionBaseKey */
+        return Arrays.copyOf(sessionBaseKey, sessionBaseKey.length);
+    }
+
+    /**
+     * Computes a one-way function of the user's password to use as the response
+     * key. NTLM v1 and NTLM v2 define separate LMOWF() functions in the NTLM v1
+     * authentication and NTLM v2 authentication sections, respectively.
+     */
+    public static byte[] LMOWF() {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Indicates the computation of an MD4 message digest of the null-terminated
+     * byte string M ([RFC1320]).
+     */
+    public static byte[] MD4(byte[] M) {
+        try {
+            return sun.security.provider.MD4.getInstance().digest(M);
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot calculate MD5.", e);
+        }
+    }
+
+    /**
+     * Indicates the computation of an MD5 message digest of the null-terminated
+     * byte string M ([RFC1321]).
+     */
+    public static byte[] MD5(byte[] M) {
+        try {
+            return MessageDigest.getInstance("MD5").digest(M);
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot calculate MD5.", e);
+        }
+    }
+
+    /**
+     * Indicates the computation of an MD5 message digest of a binary blob
+     * ([RFC4121] section 4.1.1.2).
+     */
+    public static byte[] MD5_HASH(byte[] M) {
+        try {
+            return MessageDigest.getInstance("MD5").digest(M);
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot calculate MD5.", e);
+        }
+    }
+
+    /** A zero-length string. */
+    public static final String NIL = "";
+
+    /**
+     * Indicates the computation of an N-byte cryptographic-strength random
+     * number.
+     * 
+     * Note The NTLM Authentication Protocol does not define the statistical
+     * properties of the random number generator. It is left to the discretion of
+     * the implementation to define the strength requirements of the NONCE(N)
+     * operation.
+     */
+    public static byte[] NONCE(int N) {
+        // Generate random nonce for LMv2 and NTv2 responses
+        byte[] nonce = new byte[N];
+        SecureRandom random = new SecureRandom();
+        random.nextBytes(nonce);
+
+        // Fixed nonce for debugging purposes
+        //* DEBUG */for (int i = 0; i < N; i++) nonce[i] = (byte) (i + 1);
+
+        return nonce;
+    }
+
+    /**
+     * Computes a one-way function of the user's password to use as the response
+     * key. NTLM v1 and NTLM v2 define separate NTOWF() functions in the NTLM v1
+     * authentication and NTLM v2 authentication sections, respectively.
+     */
+    public static byte[] NTOWF() {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * The RC4 Encryption Algorithm. To obtain this stream cipher that is licensed
+     * by RSA Data Security, Inc., contact this company.
+     * 
+     * Indicates the encryption of data item D with the current session or message
+     * key state, using the RC4 algorithm. H is the handle to a key state
+     * structure initialized by RC4INIT.
+     */
+    public static byte[] RC4(Cipher H, byte[] D) {
+        return H.update(D);
+    }
+
+    /**
+     * Indicates the encryption of data item D with the key K using the RC4
+     * algorithm.
+     * 
+     * Note The key sizes for RC4 encryption in NTLM are defined in sections
+     * KXKEY, SIGNKEY, and SEALKEY, where they are created.
+     */
+    public static byte[] RC4K(byte[] K, byte[] D) {
+        try {
+            Cipher cipher = Cipher.getInstance("RC4");
+            Key key = new SecretKeySpec(K, "RC4");
+            cipher.init(Cipher.ENCRYPT_MODE, key);
+            return cipher.doFinal(D);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Initialization of the RC4 key and handle to a key state structure for the
+     * session.
+     */
+    public static Cipher RC4Init(byte[] K) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Produces an encryption key from the session key as defined in sections
+     * KXKEY, SIGNKEY, and SEALKEY.
+     */
+    public static byte[] SEALKEY(byte[] F, byte[] K, byte[] string1) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Produces a signing key from the session key as defined in sections KXKEY,
+     * SIGNKEY, and SEALKEY.
+     */
+    public static byte[] SIGNKEY(int flag, byte[] K, byte[] string1) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Indicates the retrieval of the current time as a 64-bit value, represented
+     * as the number of 100-nanosecond ticks elapsed since midnight of January
+     * 1st, 1601 (UTC).
+     */
+    public static byte[] Currenttime() {
+        // (current time + milliseconds from 1.01.1601 to 1.01.1970) *
+        // 100-nanosecond ticks
+        long time = (System.currentTimeMillis() + 11644473600000L) * 10000;
+
+        // Convert 64bit value to byte array.
+        byte[] result = new byte[8];
+        for (int i = 0; i < 8; i++, time >>>= 8) {
+            result[i] = (byte)time;
+        }
+
+        return result;
+    }
+
+    /**
+     * Indicates the 2-byte little-endian byte order encoding of the Unicode
+     * UTF-16 representation of string. The Byte Order Mark (BOM) is not sent over
+     * the wire.
+     */
+    public static byte[] UNICODE(String string) {
+        return string.getBytes(RdpConstants.CHARSET_16);
+    }
+
+    /** Indicates the uppercase representation of string. */
+    public static String UpperCase(String string) {
+        return string.toUpperCase();
+    }
+
+    /**
+     * Indicates the creation of a byte array of length N. Each byte in the array
+     * is initialized to the value zero.
+     */
+    public static byte[] Z(int N) {
+        return new byte[N];
+    }
+
+    public static Cipher initRC4(byte[] key) {
+        try {
+            Cipher cipher = Cipher.getInstance("RC4");
+            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "RC4"));
+            return cipher;
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot initialize RC4 sealing handle with client sealing key.", e);
+        }
+    }
+
+    /**
+     * Helper method for embedded test cases.
+     */
+    public static void callAll(Object obj) {
+        Method[] methods = obj.getClass().getDeclaredMethods();
+        for (Method m : methods) {
+            if (m.getName().startsWith("test")) {
+                try {
+                    m.invoke(obj, (Object[])null);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public static void main(String args[]) {
+        callAll(new CryptoAlgos());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java
new file mode 100755
index 0000000..c35dbec
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java
@@ -0,0 +1,492 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.ntlmssp;
+
+/**
+ * During NTLM authentication, each of the following flags is a possible value
+ * of the NegotiateFlags field of the NEGOTIATE_MESSAGE, CHALLENGE_MESSAGE, and
+ * AUTHENTICATE_MESSAGE, unless otherwise noted. These flags define client or
+ * server NTLM capabilities supported by the sender.
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc236650.aspx
+ */
+public class NegoFlags {
+
+    /**
+     * 56-bit encryption. If the client sends NTLMSSP_NEGOTIATE_SEAL or
+     * NTLMSSP_NEGOTIATE_SIGN with NTLMSSP_NEGOTIATE_56 to the server in the
+     * NEGOTIATE_MESSAGE, the server MUST return NTLMSSP_NEGOTIATE_56 to the
+     * client in the CHALLENGE_MESSAGE. Otherwise it is ignored. If both
+     * NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128 are requested and supported
+     * by the client and server, NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128
+     * will both be returned to the client. Clients and servers that set
+     * NTLMSSP_NEGOTIATE_SEAL SHOULD set NTLMSSP_NEGOTIATE_56 if it is supported.
+     * An alternate name for this field is
+     */
+    public static final int NTLMSSP_NEGOTIATE_56 = 0x80000000;
+
+    /**
+     * Explicit key exchange. This capability SHOULD be used because it improves
+     * security for message integrity or confidentiality. See sections 3.2.5.1.2,
+     * 3.2.5.2.1, and 3.2.5.2.2 for details.
+     */
+    public static final int NTLMSSP_NEGOTIATE_KEY_EXCH = 0x40000000;
+
+    /**
+     * 128-bit session key negotiation. An alternate name for this field is
+     * NTLMSSP_NEGOTIATE_128. If the client sends NTLMSSP_NEGOTIATE_128 to the
+     * server in the NEGOTIATE_MESSAGE, the server MUST return
+     * NTLMSSP_NEGOTIATE_128 to the client in the CHALLENGE_MESSAGE only if the
+     * client sets NTLMSSP_NEGOTIATE_SEAL or NTLMSSP_NEGOTIATE_SIGN. Otherwise it
+     * is ignored. If both NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128 are
+     * requested and supported by the client and server, NTLMSSP_NEGOTIATE_56 and
+     * NTLMSSP_NEGOTIATE_128 will both be returned to the client. Clients and
+     * servers that set NTLMSSP_NEGOTIATE_SEAL SHOULD set NTLMSSP_NEGOTIATE_128 if
+     * it is supported.
+     */
+    public static final int NTLMSSP_NEGOTIATE_128 = 0x20000000;
+
+    /**
+     * Protocol version number. The data corresponding to this flag is provided in
+     * the Version field of the NEGOTIATE_MESSAGE, the CHALLENGE_MESSAGE, and the
+     * AUTHENTICATE_MESSAGE.
+     */
+    public static final int NTLMSSP_NEGOTIATE_VERSION = 0x02000000;
+
+    /**
+     * TargetInfo fields in the CHALLENGE_MESSAGE (section 2.2.1.2) are populated.
+     */
+    public static final int NTLMSSP_NEGOTIATE_TARGET_INFO = 0x00800000;
+
+    /** LMOWF (section 3.3). */
+    public static final int NTLMSSP_REQUEST_NON_NT_SESSION_KEY = 0x00400000;
+
+    /** An identify level token. */
+    public static final int NTLMSSP_NEGOTIATE_IDENTIFY = 0x00100000;
+
+    /**
+     * NTLM v2 session security. NTLM v2 session security is a misnomer because it
+     * is not NTLM v2. It is NTLM v1 using the extended session security that is
+     * also in NTLM v2. NTLMSSP_NEGOTIATE_LM_KEY and
+     * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are mutually exclusive. If both
+     * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY and NTLMSSP_NEGOTIATE_LM_KEY are
+     * requested, NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY alone MUST be
+     * returned to the client. NTLM v2 authentication session key generation MUST
+     * be supported by both the client and the DC in order to be used, and
+     * extended session security signing and sealing requires support from the
+     * client and the server in order to be used.
+     */
+    public static final int NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY = 0x00080000;
+
+    /**
+     * TargetName MUST be a server name. The data corresponding to this flag is
+     * provided by the server in the TargetName field of the CHALLENGE_MESSAGE. If
+     * this bit is set, then NTLMSSP_TARGET_TYPE_DOMAIN MUST NOT be set. This flag
+     * MUST be ignored in the NEGOTIATE_MESSAGE and the AUTHENTICATE_MESSAGE.
+     */
+    public static final int NTLMSSP_TARGET_TYPE_SERVER = 0x00020000;
+
+    /**
+     * TargetName MUST be a domain name. The data corresponding to this flag is
+     * provided by the server in the TargetName field of the CHALLENGE_MESSAGE. If
+     * set, then NTLMSSP_TARGET_TYPE_SERVER MUST NOT be set. This flag MUST be
+     * ignored in the NEGOTIATE_MESSAGE and the AUTHENTICATE_MESSAGE.
+     */
+    public static final int NTLMSSP_TARGET_TYPE_DOMAIN = 0x00010000;
+
+    /**
+     * Signature block on all messages. NTLMSSP_NEGOTIATE_ALWAYS_SIGN MUST be set
+     * in the NEGOTIATE_MESSAGE to the server and the CHALLENGE_MESSAGE to the
+     * client. NTLMSSP_NEGOTIATE_ALWAYS_SIGN is overridden by
+     * NTLMSSP_NEGOTIATE_SIGN and NTLMSSP_NEGOTIATE_SEAL, if they are supported.
+     */
+    public static final int NTLMSSP_NEGOTIATE_ALWAYS_SIGN = 0x00008000;
+
+    /**
+     * Workstation field is present. If this flag is not set, the Workstation
+     * field MUST be ignored. If this flag is set, the length field of the
+     * Workstation field specifies whether the workstation name is nonempty or
+     * not.
+     */
+    public static final int NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED = 0x00002000;
+
+    /**
+     * Domain name is provided.
+     * 
+     * Sent by the client in the Type 1 message to indicate that the name of the
+     * domain in which the client workstation has membership is included in the
+     * message. This is used by the server to determine whether the client is
+     * eligible for local authentication.
+     */
+    public static final int NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED = 0x00001000;
+
+    /**
+     * Connection SHOULD be anonymous.
+     * 
+     * Sent by the client in the Type 3 message to indicate that an anonymous
+     * context has been established. This also affects the response fields (as
+     * detailed in the "Anonymous Response" section).
+     */
+    public static final int NTLMSSP_NEGOTIATE_ANONYMOUS = 0x00000800;
+
+    /**
+     * Usage of the NTLM v1 session security protocol. NTLMSSP_NEGOTIATE_NTLM MUST
+     * be set in the NEGOTIATE_MESSAGE to the server and the CHALLENGE_MESSAGE to
+     * the client.
+     */
+    public static final int NTLMSSP_NEGOTIATE_NTLM = 0x00000200;
+
+    /**
+     * LAN Manager (LM) session key computation. NTLMSSP_NEGOTIATE_LM_KEY and
+     * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are mutually exclusive. If both
+     * NTLMSSP_NEGOTIATE_LM_KEY and NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are
+     * requested, NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY alone MUST be
+     * returned to the client. NTLM v2 authentication session key generation MUST
+     * be supported by both the client and the DC in order to be used, and
+     * extended session security signing and sealing requires support from the
+     * client and the server to be used.
+     */
+    public static final int NTLMSSP_NEGOTIATE_LM_KEY = 0x00000080;
+
+    /**
+     * Connectionless authentication. If NTLMSSP_NEGOTIATE_DATAGRAM is set, then
+     * NTLMSSP_NEGOTIATE_KEY_EXCH MUST always be set in the AUTHENTICATE_MESSAGE
+     * to the server and the CHALLENGE_MESSAGE to the client.
+     */
+    public static final int NTLMSSP_NEGOTIATE_DATAGRAM = 0x00000040;
+
+    /**
+     * Session key negotiation for message confidentiality. If the client sends
+     * NTLMSSP_NEGOTIATE_SEAL to the server in the NEGOTIATE_MESSAGE, the server
+     * MUST return NTLMSSP_NEGOTIATE_SEAL to the client in the CHALLENGE_MESSAGE.
+     * Clients and servers that set NTLMSSP_NEGOTIATE_SEAL SHOULD always set
+     * NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128, if they are supported.
+     */
+    public static final int NTLMSSP_NEGOTIATE_SEAL = 0x00000020;
+
+    /**
+     * Session key negotiation for message signatures. If the client sends
+     * NTLMSSP_NEGOTIATE_SIGN to the server in the NEGOTIATE_MESSAGE, the server
+     * MUST return NTLMSSP_NEGOTIATE_SIGN to the client in the CHALLENGE_MESSAGE.
+     */
+    public static final int NTLMSSP_NEGOTIATE_SIGN = 0x00000010;
+
+    /**
+     * TargetName field of the CHALLENGE_MESSAGE (section 2.2.1.2) MUST be
+     * supplied.
+     */
+    public static final int NTLMSSP_REQUEST_TARGET = 0x00000004;
+
+    /**
+     * OEM character set encoding.
+     * 
+     * @see NTLMSSP_NEGOTIATE_UNICODE
+     */
+    public static final int NTLMSSP_NEGOTIATE_OEM = 0x00000002;
+
+    /**
+     * Unicode character set encoding.
+     * 
+     * The NTLMSSP_NEGOTIATE_UNICODE(A) and NTLM_NEGOTIATE_OEM(B) bits are
+     * evaluated together as follows:
+     * <ul>
+     * <li>A==1: The choice of character set encoding MUST be Unicode.
+     * 
+     * <li>A==0 and B==1: The choice of character set encoding MUST be OEM.
+     * 
+     * <li>A==0 and B==0: The protocol MUST return SEC_E_INVALID_TOKEN.
+     * <ul>
+     * */
+    public static final int NTLMSSP_NEGOTIATE_UNICODE = 0x00000001;
+
+    public int value;
+
+    public NegoFlags(int value) {
+        this.value = value;
+    }
+
+    public NegoFlags() {
+        this.value = 0;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("NegoFlags [value=0x%04x (%s)]", value, flagsToSting());
+    }
+
+    public String flagsToSting() {
+
+        String str = "";
+
+        if (NEGOTIATE_56())
+            str += "NEGOTIATE_56 ";
+        if (NEGOTIATE_KEY_EXCH())
+            str += "NEGOTIATE_KEY_EXCH ";
+        if (NEGOTIATE_128())
+            str += "NEGOTIATE_128 ";
+        if (NEGOTIATE_VERSION())
+            str += "NEGOTIATE_VERSION ";
+        if (NEGOTIATE_TARGET_INFO())
+            str += "NEGOTIATE_TARGET_INFO ";
+        if (REQUEST_NON_NT_SESSION_KEY())
+            str += "REQUEST_NON_NT_SESSION_KEY ";
+        if (NEGOTIATE_IDENTIFY())
+            str += "NEGOTIATE_IDENTIFY ";
+        if (NEGOTIATE_EXTENDED_SESSION_SECURITY())
+            str += "NEGOTIATE_EXTENDED_SESSION_SECURITY ";
+        if (TARGET_TYPE_SERVER())
+            str += "TARGET_TYPE_SERVER ";
+        if (TARGET_TYPE_DOMAIN())
+            str += "TARGET_TYPE_DOMAIN ";
+        if (NEGOTIATE_ALWAYS_SIGN())
+            str += "NEGOTIATE_ALWAYS_SIGN ";
+        if (NEGOTIATE_OEM_WORKSTATION_SUPPLIED())
+            str += "NEGOTIATE_OEM_WORKSTATION_SUPPLIED ";
+        if (NEGOTIATE_OEM_DOMAIN_SUPPLIED())
+            str += "NEGOTIATE_OEM_DOMAIN_SUPPLIED ";
+        if (NEGOTIATE_ANONYMOUS())
+            str += "NEGOTIATE_ANONYMOUS ";
+        if (NEGOTIATE_NTLM())
+            str += "NEGOTIATE_NTLM ";
+        if (NEGOTIATE_LM_KEY())
+            str += "NEGOTIATE_LM_KEY ";
+        if (NEGOTIATE_DATAGRAM())
+            str += "NEGOTIATE_DATAGRAM ";
+        if (NEGOTIATE_SEAL())
+            str += "NEGOTIATE_SEAL ";
+        if (NEGOTIATE_SIGN())
+            str += "NEGOTIATE_SIGN ";
+        if (REQUEST_TARGET())
+            str += "REQUEST_TARGET ";
+        if (NEGOTIATE_OEM())
+            str += "NEGOTIATE_OEM ";
+        if (NEGOTIATE_UNICODE())
+            str += "NEGOTIATE_UNICODE ";
+
+        return str;
+    }
+
+    public boolean NEGOTIATE_56() {
+        return ((value & NTLMSSP_NEGOTIATE_56) != 0);
+    }
+
+    public boolean NEGOTIATE_KEY_EXCH() {
+        return ((value & NTLMSSP_NEGOTIATE_KEY_EXCH) != 0);
+    }
+
+    public boolean NEGOTIATE_128() {
+        return ((value & NTLMSSP_NEGOTIATE_128) != 0);
+    }
+
+    public boolean NEGOTIATE_VERSION() {
+        return ((value & NTLMSSP_NEGOTIATE_VERSION) != 0);
+    }
+
+    public boolean NEGOTIATE_TARGET_INFO() {
+        return ((value & NTLMSSP_NEGOTIATE_TARGET_INFO) != 0);
+    }
+
+    public boolean REQUEST_NON_NT_SESSION_KEY() {
+        return ((value & NTLMSSP_REQUEST_NON_NT_SESSION_KEY) != 0);
+    }
+
+    public boolean NEGOTIATE_IDENTIFY() {
+        return ((value & NTLMSSP_NEGOTIATE_IDENTIFY) != 0);
+    }
+
+    public boolean NEGOTIATE_EXTENDED_SESSION_SECURITY() {
+        return ((value & NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY) != 0);
+    }
+
+    public boolean TARGET_TYPE_SERVER() {
+        return ((value & NTLMSSP_TARGET_TYPE_SERVER) != 0);
+    }
+
+    public boolean TARGET_TYPE_DOMAIN() {
+        return ((value & NTLMSSP_TARGET_TYPE_DOMAIN) != 0);
+    }
+
+    public boolean NEGOTIATE_ALWAYS_SIGN() {
+        return ((value & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) != 0);
+    }
+
+    public boolean NEGOTIATE_OEM_WORKSTATION_SUPPLIED() {
+        return ((value & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED) != 0);
+    }
+
+    public boolean NEGOTIATE_OEM_DOMAIN_SUPPLIED() {
+        return ((value & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED) != 0);
+    }
+
+    public boolean NEGOTIATE_ANONYMOUS() {
+        return ((value & NTLMSSP_NEGOTIATE_ANONYMOUS) != 0);
+    }
+
+    public boolean NEGOTIATE_NTLM() {
+        return ((value & NTLMSSP_NEGOTIATE_NTLM) != 0);
+    }
+
+    public boolean NEGOTIATE_LM_KEY() {
+        return ((value & NTLMSSP_NEGOTIATE_LM_KEY) != 0);
+    }
+
+    public boolean NEGOTIATE_DATAGRAM() {
+        return ((value & NTLMSSP_NEGOTIATE_DATAGRAM) != 0);
+    }
+
+    public boolean NEGOTIATE_SEAL() {
+        return ((value & NTLMSSP_NEGOTIATE_SEAL) != 0);
+    }
+
+    public boolean NEGOTIATE_SIGN() {
+        return ((value & NTLMSSP_NEGOTIATE_SIGN) != 0);
+    }
+
+    public boolean REQUEST_TARGET() {
+        return ((value & NTLMSSP_REQUEST_TARGET) != 0);
+    }
+
+    public boolean NEGOTIATE_OEM() {
+        return ((value & NTLMSSP_NEGOTIATE_OEM) != 0);
+    }
+
+    public boolean NEGOTIATE_UNICODE() {
+        return ((value & NTLMSSP_NEGOTIATE_UNICODE) != 0);
+    }
+
+    public NegoFlags set_NEGOTIATE_56() {
+        value |= NTLMSSP_NEGOTIATE_56;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_KEY_EXCH() {
+        value |= NTLMSSP_NEGOTIATE_KEY_EXCH;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_128() {
+        value |= NTLMSSP_NEGOTIATE_128;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_VERSION() {
+        value |= NTLMSSP_NEGOTIATE_VERSION;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_TARGET_INFO() {
+        value |= NTLMSSP_NEGOTIATE_TARGET_INFO;
+        return this;
+    }
+
+    public NegoFlags set_REQUEST_NON_NT_SESSION_KEY() {
+        value |= NTLMSSP_REQUEST_NON_NT_SESSION_KEY;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_IDENTIFY() {
+        value |= NTLMSSP_NEGOTIATE_IDENTIFY;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_EXTENDED_SESSION_SECURITY() {
+        value |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
+        return this;
+    }
+
+    public NegoFlags set_TARGET_TYPE_SERVER() {
+        value |= NTLMSSP_TARGET_TYPE_SERVER;
+        return this;
+    }
+
+    public NegoFlags set_TARGET_TYPE_DOMAIN() {
+        value |= NTLMSSP_TARGET_TYPE_DOMAIN;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_ALWAYS_SIGN() {
+        value |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_OEM_WORKSTATION_SUPPLIED() {
+        value |= NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_OEM_DOMAIN_SUPPLIED() {
+        value |= NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_ANONYMOUS() {
+        value |= NTLMSSP_NEGOTIATE_ANONYMOUS;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_NTLM() {
+        value |= NTLMSSP_NEGOTIATE_NTLM;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_LM_KEY() {
+        value |= NTLMSSP_NEGOTIATE_LM_KEY;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_DATAGRAM() {
+        value |= NTLMSSP_NEGOTIATE_DATAGRAM;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_SEAL() {
+        value |= NTLMSSP_NEGOTIATE_SEAL;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_SIGN() {
+        value |= NTLMSSP_NEGOTIATE_SIGN;
+        return this;
+    }
+
+    public NegoFlags set_REQUEST_TARGET() {
+        value |= NTLMSSP_REQUEST_TARGET;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_OEM() {
+        value |= NTLMSSP_NEGOTIATE_OEM;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_UNICODE() {
+        value |= NTLMSSP_NEGOTIATE_UNICODE;
+        return this;
+    }
+
+    /**
+     * Example.
+     */
+
+    public static void main(String args[]) {
+
+        NegoFlags flags = new NegoFlags(0xe20882b7);
+        System.out.println("Negotiation flags: " + flags);
+
+    }
+
+}


[08/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerBitmapUpdate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerBitmapUpdate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerBitmapUpdate.java
new file mode 100755
index 0000000..f938422
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerBitmapUpdate.java
@@ -0,0 +1,200 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import common.BitmapOrder;
+import common.BitmapRectangle;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.FakeSink;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240624.aspx
+ */
+public class ServerBitmapUpdate extends BaseElement {
+    public static final int UPDATETYPE_BITMAP = 0x0001;
+
+    /**
+     * Indicates that the bitmap data is compressed. The bitmapComprHdr field MUST
+     * be present if the NO_BITMAP_COMPRESSION_HDR (0x0400) flag is not set.
+     */
+    public static final int BITMAP_COMPRESSION = 0x0001;
+
+    /**
+     * Indicates that the bitmapComprHdr field is not present (removed for
+     * bandwidth efficiency to save 8 bytes).
+     */
+    private static final int NO_BITMAP_COMPRESSION_HDR = 0x0400;
+
+    public ServerBitmapUpdate(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // * DEBUG */System.out.println(buf.toHexString(buf.length));
+
+        BitmapOrder order = new BitmapOrder();
+
+        // (2 bytes): A 16-bit, unsigned integer. The update type. This field MUST
+        // be set to UPDATETYPE_BITMAP (0x0001).
+        int updateType = buf.readSignedShortLE();
+        if (updateType != UPDATETYPE_BITMAP)
+            throw new RuntimeException("Unknown update type. Expected update type: UPDATETYPE_BITMAP (0x1). Actual update type: " + updateType + ", buf: " + buf
+                    + ".");
+
+        // (2 bytes): A 16-bit, unsigned integer. The number of screen rectangles
+        // present in the rectangles field.
+        int numberRectangles = buf.readSignedShortLE();
+
+        // (variable): Variable-length array of TS_BITMAP_DATA structures, each of
+        // which contains a rectangular clipping taken from the server-side screen
+        // frame buffer. The number of screen clippings in the array is specified by
+        // the numberRectangles field.
+        BitmapRectangle[] rectangles = new BitmapRectangle[numberRectangles];
+        for (int i = 0; i < numberRectangles; i++) {
+            rectangles[i] = readRectangle(buf);
+        }
+        order.rectangles = rectangles;
+
+        buf.assertThatBufferIsFullyRead();
+
+        ByteBuffer data = new ByteBuffer(order);
+        pushDataToAllOuts(data);
+
+        buf.unref();
+    }
+
+    public BitmapRectangle readRectangle(ByteBuffer buf) {
+
+        BitmapRectangle rectangle = new BitmapRectangle();
+
+        // (2 bytes): A 16-bit, unsigned integer. Left bound of the rectangle.
+        rectangle.x = buf.readSignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. Top bound of the rectangle.
+        rectangle.y = buf.readSignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. Inclusive right bound of the
+        // rectangle.
+        int destRight = buf.readSignedShortLE();
+        rectangle.width = destRight - rectangle.x + 1;
+
+        // (2 bytes): A 16-bit, unsigned integer. Inclusive bottom bound of the
+        // rectangle.
+        int destBottom = buf.readSignedShortLE();
+        rectangle.height = destBottom - rectangle.y + 1;
+
+        // (2 bytes): A 16-bit, unsigned integer. The width of the rectangle.
+        rectangle.bufferWidth = buf.readSignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. The height of the rectangle.
+        rectangle.bufferHeight = buf.readSignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. The color depth of the rectangle
+        // data in bits-per-pixel.
+        rectangle.colorDepth = buf.readSignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. The flags describing the format of
+        // the bitmap data in the bitmapDataStream field.
+        int flags = buf.readSignedShortLE();
+
+        // BITMAP_COMPRESSION 0x0001
+        // Indicates that the bitmap data is compressed. The bitmapComprHdr field
+        // MUST be present if the NO_BITMAP_COMPRESSION_HDR (0x0400) flag is not
+        // set.
+        boolean compressed = ((flags & BITMAP_COMPRESSION) > 0);
+
+        // (2 bytes): A 16-bit, unsigned integer. The size in bytes of the data in
+        // the bitmapComprHdr and bitmapDataStream fields.
+        int bitmapLength = buf.readSignedShortLE();
+
+        // NO_BITMAP_COMPRESSION_HDR 0x0400
+        // Indicates that the bitmapComprHdr field is not present (removed for
+        // bandwidth efficiency to save 8 bytes).
+        if (compressed && (flags & NO_BITMAP_COMPRESSION_HDR) == 0) {
+            // (8 bytes): Optional Compressed Data Header structure specifying the
+            // bitmap data in the bitmapDataStream.
+            // This field MUST be present if the BITMAP_COMPRESSION (0x0001) flag is
+            // present in the Flags field, but the NO_BITMAP_COMPRESSION_HDR (0x0400)
+            // flag is not.
+
+            // Note: Even when compression header is enabled, server sends nothing.
+            // rectangle.compressedBitmapHeader = buf.readBytes(8);
+        }
+
+        // (variable): A variable-length array of bytes describing a bitmap image.
+        // Bitmap data is either compressed or uncompressed, depending on whether
+        // the BITMAP_COMPRESSION flag is present in the Flags field. Uncompressed
+        // bitmap data is formatted as a bottom-up, left-to-right series of pixels.
+        // Each pixel is a whole number of bytes. Each row contains a multiple of
+        // four bytes (including up to three bytes of padding, as necessary).
+        // Compressed bitmaps not in 32 bpp format are compressed using Interleaved
+        // RLE and encapsulated in an RLE Compressed Bitmap Stream structure,
+        // while compressed bitmaps at a color depth of 32 bpp are compressed
+        // using RDP 6.0 Bitmap Compression and stored inside
+        // an RDP 6.0 Bitmap Compressed Stream structure.
+        if (!compressed) {
+            rectangle.bitmapDataStream = buf.readBytes(bitmapLength);
+        } else {
+            ByteBuffer compressedImage = buf.readBytes(bitmapLength);
+            //* DEBUG */System.out.println("Compressed image: " + compressedImage + ", depth: " + rectangle.bitsPerPixel + ".");
+            rectangle.bitmapDataStream = RLEBitmapDecompression.rleDecompress(compressedImage, rectangle.bufferWidth, rectangle.bufferHeight, rectangle.colorDepth);
+            compressedImage.unref();
+        }
+
+        return rectangle;
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        ByteBuffer packet = new ByteBuffer(new byte[] {0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x00,
+                0x01, 0x04, 0x0a, 0x00, 0x0c, (byte)0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
+
+        Element bitmap = new ServerBitmapUpdate("bitmap") {
+            {
+                verbose = true;
+            }
+        };
+        FakeSink fakeSink = new FakeSink("sink") {
+            {
+                verbose = true;
+            }
+        };
+        Pipeline pipeline = new PipelineImpl("test");
+
+        // BufferedImageCanvas canvas = new BufferedImageCanvas(1024, 768);
+        // Element adapter = new AwtRdpAdapter("test",canvas );
+        // pipeline.addAndLink(bitmap, adapter);
+        pipeline.addAndLink(bitmap, fakeSink);
+
+        bitmap.handleData(packet, null);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUCooperate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUCooperate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUCooperate.java
new file mode 100755
index 0000000..efdf807
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUCooperate.java
@@ -0,0 +1,117 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ServerControlPDUCooperate extends OneTimeSwitch {
+
+    public ServerControlPDUCooperate(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Ignore packet
+        buf.unref();
+        switchOff();
+    }
+
+}
+
+/* @formatter:off */
+/*
+03 00 00 28 02 F0 80 68 00 01 03 EB 70 1A 1A 00 17 00 EA 03 EA 03 01 00 9A 02 1A 00 14 00 00 00 04 00 00 00 00 00 00 00 
+
+
+  Frame: Number = 38, Captured Frame Length = 97, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 40
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 40 (0x28)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: Data Packet
+  - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
+   - Type: Send Data Indication
+    - RootIndex: 26
+       Value: (011010..) 0x1a
+   - UserID: 0x3ea
+    - UserID: 0x3ea
+     - ChannelId: 1002
+      - Align: No Padding
+         Padding2: (00......) 0x0
+        Value: 1 (0x1)
+   - Channel: 0x3eb
+    - ChannelId: 1003
+       Align: No Padding
+       Value: 1003 (0x3EB)
+   - DataPriority: high
+    - DataPriority: high
+     - RootIndex: 1
+        Value: (01......) 0x1
+   - Segmentation: Begin End
+      Begin: (1.......) Begin
+      End:   (.1......) End
+   - Length: 26
+    - Align: No Padding
+       Padding4: (0000....) 0x0
+      Length: 26
+    RDP: RDPBCGR
+- RDPBCGR: TsControlPDU
+  - SlowPathPacket: TsControlPDU 
+   - SlowPath: Type = TS_PDUTYPE_DATAPDU
+    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
+       TotalLength: 26 (0x1A)
+     - PDUType: 23 (0x17)
+        Type:            (............0111) TS_PDUTYPE_DATAPDU
+        ProtocolVersion: (000000000001....) 1
+       PDUSource: 1002 (0x3EA)
+    - SlowPathIoPacket: 0x0
+     - ShareDataHeader: TS_PDUTYPE2_CONTROL
+        ShareID: 66538 (0x103EA)
+        Pad1: 154 (0x9A)
+        StreamID: TS_STREAM_MED
+        UncompressedLength: 26 (0x1A)
+        PDUType2: TS_PDUTYPE2_CONTROL
+      - CompressedType: Not Compressed
+         MPPC:       (....0000) MPPC 8K
+         Reserved:   (...0....)
+         Compressed: (..0.....) Not Compressed
+         Front:      (.0......) Not At Front
+         Flush:      (0.......) Not Flushed
+        CompressedLength: 0 (0x0)
+     - TsControlPDU: Action = Cooperate
+        Action: Cooperate
+        GrantID: 0 (0x0)
+        ControlID: 0 (0x0)
+
+ */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUGrantedControl.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUGrantedControl.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUGrantedControl.java
new file mode 100755
index 0000000..0758da8
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUGrantedControl.java
@@ -0,0 +1,114 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ServerControlPDUGrantedControl extends OneTimeSwitch {
+
+    public ServerControlPDUGrantedControl(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Ignore packet
+        buf.unref();
+        switchOff();
+    }
+
+}
+/* @formatter:off */
+/*
+03 00 00 28 02 F0 80 68 00 01 03 EB 70 1A 1A 00 17 00 EA 03 EA 03 01 00 50 02 1A 00 14 00 00 00 02 00 EC 03 EA 03 00 00 
+
+  Frame: Number = 45, Captured Frame Length = 97, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 40
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 40 (0x28)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: Data Packet
+  - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
+   - Type: Send Data Indication
+    - RootIndex: 26
+       Value: (011010..) 0x1a
+   - UserID: 0x3ea
+    - UserID: 0x3ea
+     - ChannelId: 1002
+      - Align: No Padding
+         Padding2: (00......) 0x0
+        Value: 1 (0x1)
+   - Channel: 0x3eb
+    - ChannelId: 1003
+       Align: No Padding
+       Value: 1003 (0x3EB)
+   - DataPriority: high
+    - DataPriority: high
+     - RootIndex: 1
+        Value: (01......) 0x1
+   - Segmentation: Begin End
+      Begin: (1.......) Begin
+      End:   (.1......) End
+   - Length: 26
+    - Align: No Padding
+       Padding4: (0000....) 0x0
+      Length: 26
+    RDP: RDPBCGR
+- RDPBCGR: TsControlPDU
+  - SlowPathPacket: TsControlPDU 
+   - SlowPath: Type = TS_PDUTYPE_DATAPDU
+    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
+       TotalLength: 26 (0x1A)
+     - PDUType: 23 (0x17)
+        Type:            (............0111) TS_PDUTYPE_DATAPDU
+        ProtocolVersion: (000000000001....) 1
+       PDUSource: 1002 (0x3EA)
+    - SlowPathIoPacket: 0x0
+     - ShareDataHeader: TS_PDUTYPE2_CONTROL
+        ShareID: 66538 (0x103EA)
+        Pad1: 80 (0x50)
+        StreamID: TS_STREAM_MED
+        UncompressedLength: 26 (0x1A)
+        PDUType2: TS_PDUTYPE2_CONTROL
+      - CompressedType: Not Compressed
+         MPPC:       (....0000) MPPC 8K
+         Reserved:   (...0....)
+         Compressed: (..0.....) Not Compressed
+         Front:      (.0......) Not At Front
+         Flush:      (0.......) Not Flushed
+        CompressedLength: 0 (0x0)
+     - TsControlPDU: Action = Granted Control
+        Action: Granted Control
+        GrantID: 1004 (0x3EC)
+        ControlID: 1002 (0x3EA)
+ */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerDemandActivePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerDemandActivePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerDemandActivePDU.java
new file mode 100755
index 0000000..60dc5b7
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerDemandActivePDU.java
@@ -0,0 +1,661 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Order;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.FakeSink;
+import streamer.debug.MockSource;
+
+import common.ScreenDescription;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240669.aspx
+ * @see http://msdn.microsoft.com/en-us/library/cc240484.aspx
+ */
+public class ServerDemandActivePDU extends BaseElement {
+
+    /**
+     * Demand Active PDU.
+     */
+    public static final int PDUTYPE_DEMANDACTIVEPDU = 0x1;
+
+    protected RdpState state;
+    protected ScreenDescription screen;
+
+    public ServerDemandActivePDU(String id, ScreenDescription screen, RdpState state) {
+        super(id);
+        this.state = state;
+        this.screen = screen;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Total length of packet
+        int length = buf.readSignedShortLE(); // Ignore
+        if (buf.length != length)
+            throw new RuntimeException("Incorrect length of packet. Length: " + length + ", data: " + buf + ".");
+
+        int type = buf.readSignedShortLE() & 0xf;
+        if (type != PDUTYPE_DEMANDACTIVEPDU)
+            throw new RuntimeException("Unknown PDU type. Expected type: Demand Active PDU (0x1), actual tyoe: " + type + ", data: " + buf + ".");
+
+        // TS_SHARECONTROLHEADER::pduSource = 0x03ea (1002)
+        int pduSource = buf.readSignedShortLE();
+        if (pduSource != 1002)
+            throw new RuntimeException("Unexepcted source of demand active PDU. Expected source: 1002, actual source: " + pduSource + ".");
+
+        // (4 bytes): A 32-bit, unsigned integer. The share identifier for the
+        // packet (see [T128] section 8.4.2 for more information regarding share
+        // IDs).
+        long shareId = buf.readUnsignedIntLE();
+        state.serverShareId = shareId;
+
+        // Ignore rest of server data because it is not used by this client.
+        // (2 bytes): A 16-bit, unsigned integer. The size in bytes of the
+        // sourceDescriptor field.
+        int lengthSourceDescriptor = buf.readUnsignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. The combined size in bytes of the
+        // numberCapabilities, pad2Octets, and capabilitySets fields.
+        int lengthCombinedCapabilities = buf.readUnsignedShortLE();
+
+        // (variable): A variable-length array of bytes containing a source
+        // descriptor,
+        // ByteBuffer sourceDescriptor = buf.readBytes(lengthSourceDescriptor);
+        buf.skipBytes(lengthSourceDescriptor);
+
+        // (variable): An array of Capability Set (section 2.2.1.13.1.1.1)
+        // structures. The number of capability sets is specified by the
+        // numberCapabilities field.
+        handleCapabiltySets(buf.readBytes(lengthCombinedCapabilities));
+
+        // (4 bytes): A 32-bit, unsigned integer. The session identifier. This field
+        // is ignored by the client.
+        buf.skipBytes(4);
+
+        /* DEBUG */buf.assertThatBufferIsFullyRead();
+
+        buf.unref();
+
+        sendHandshakePackets();
+    }
+
+    /**
+     * General Capability Set
+     */
+    public static final int CAPSTYPE_GENERAL = 0x0001;
+    /**
+     * Bitmap Capability Set
+     */
+    public static final int CAPSTYPE_BITMAP = 0x0002;
+    /**
+     * Order Capability Set
+     */
+    public static final int CAPSTYPE_ORDER = 0x0003;
+    /**
+     * Revision 1 Bitmap Cache Capability Set
+     */
+    public static final int CAPSTYPE_BITMAPCACHE = 0x0004;
+    /**
+     * Control Capability Set
+     */
+    public static final int CAPSTYPE_CONTROL = 0x0005;
+    /**
+     * Window Activation Capability Set
+     */
+    public static final int CAPSTYPE_ACTIVATION = 0x0007;
+    /**
+     * Pointer Capability Set
+     */
+    public static final int CAPSTYPE_POINTER = 0x0008;
+    /**
+     * Share Capability Set
+     */
+    public static final int CAPSTYPE_SHARE = 0x0009;
+    /**
+     * Color Table Cache Capability Set
+     */
+    public static final int CAPSTYPE_COLORCACHE = 0x000A;
+    /**
+     * Sound Capability Set
+     */
+    public static final int CAPSTYPE_SOUND = 0x000C;
+    /**
+     * Input Capability Set
+     */
+    public static final int CAPSTYPE_INPUT = 0x000D;
+    /**
+     * Font Capability Set
+     */
+    public static final int CAPSTYPE_FONT = 0x000E;
+    /**
+     * Brush Capability Set
+     */
+    public static final int CAPSTYPE_BRUSH = 0x000F;
+    /**
+     * Glyph Cache Capability Set
+     */
+    public static final int CAPSTYPE_GLYPHCACHE = 0x0010;
+    /**
+     * Offscreen Bitmap Cache Capability Set
+     */
+    public static final int CAPSTYPE_OFFSCREENCACHE = 0x0011;
+    /**
+     * Bitmap Cache Host Support Capability Set
+     */
+    public static final int CAPSTYPE_BITMAPCACHE_HOSTSUPPORT = 0x0012;
+    /**
+     * Revision 2 Bitmap Cache Capability Set
+     */
+    public static final int CAPSTYPE_BITMAPCACHE_REV2 = 0x0013;
+    /**
+     * Virtual Channel Capability Set
+     */
+    public static final int CAPSTYPE_VIRTUALCHANNEL = 0x0014;
+    /**
+     * DrawNineGrid Cache Capability Set
+     */
+    public static final int CAPSTYPE_DRAWNINEGRIDCACHE = 0x0015;
+    /**
+     * Draw GDI+ Cache Capability Set
+     */
+    public static final int CAPSTYPE_DRAWGDIPLUS = 0x0016;
+    /**
+     * Remote Programs Capability Set
+     */
+    public static final int CAPSTYPE_RAIL = 0x0017;
+    /**
+     * Window List Capability Set
+     */
+    public static final int CAPSTYPE_WINDOW = 0x0018;
+    /**
+     * Desktop Composition Extension Capability Set
+     */
+    public static final int CAPSETTYPE_COMPDESK = 0x0019;
+    /**
+     * Multifragment Update Capability Set
+     */
+    public static final int CAPSETTYPE_MULTIFRAGMENTUPDATE = 0x001A;
+    /**
+     * Large Pointer Capability Set
+     */
+    public static final int CAPSETTYPE_LARGE_POINTER = 0x001B;
+    /**
+     * Surface Commands Capability Set
+     */
+    public static final int CAPSETTYPE_SURFACE_COMMANDS = 0x001C;
+    /**
+     * Bitmap Codecs Capability Set
+     */
+    public static final int CAPSETTYPE_BITMAP_CODECS = 0x001D;
+    /**
+     * Frame Acknowledge Capability Set
+     */
+    public static final int CAPSSETTYPE_FRAME_ACKNOWLEDGE = 0x001E;
+
+    /**
+     * @see http://msdn.microsoft.com/en-us/library/cc240486.aspx
+     */
+    protected void handleCapabiltySets(ByteBuffer buf) {
+        // (2 bytes): A 16-bit, unsigned integer. The number of capability sets
+        // included in the Demand Active PDU.
+        int numberCapabilities = buf.readSignedShortLE();
+
+        // (2 bytes): Padding.
+        buf.skipBytes(2);
+
+        for (int i = 0; i < numberCapabilities; i++) {
+            // (2 bytes): A 16-bit, unsigned integer. The type identifier of the
+            // capability set.
+            int capabilitySetType = buf.readUnsignedShortLE();
+
+            // (2 bytes): A 16-bit, unsigned integer. The length in bytes of the
+            // capability data, including the size of the capabilitySetType and
+            // lengthCapability fields.
+            int lengthCapability = buf.readUnsignedShortLE();
+
+            // (variable): Capability set data which conforms to the structure of the
+            // type given by the capabilitySetType field.
+            ByteBuffer capabilityData = buf.readBytes(lengthCapability - 4);
+
+            switch (capabilitySetType) {
+            case CAPSTYPE_GENERAL:
+                break;
+            case CAPSTYPE_BITMAP:
+                handleBitmapCapabilities(capabilityData);
+                break;
+            case CAPSTYPE_ORDER:
+                break;
+            case CAPSTYPE_BITMAPCACHE:
+                break;
+            case CAPSTYPE_CONTROL:
+                break;
+            case CAPSTYPE_ACTIVATION:
+                break;
+            case CAPSTYPE_POINTER:
+                break;
+            case CAPSTYPE_SHARE:
+                break;
+            case CAPSTYPE_COLORCACHE:
+                break;
+            case CAPSTYPE_SOUND:
+                break;
+            case CAPSTYPE_INPUT:
+                break;
+            case CAPSTYPE_FONT:
+                break;
+            case CAPSTYPE_BRUSH:
+                break;
+            case CAPSTYPE_GLYPHCACHE:
+                break;
+            case CAPSTYPE_OFFSCREENCACHE:
+                break;
+            case CAPSTYPE_BITMAPCACHE_HOSTSUPPORT:
+                break;
+            case CAPSTYPE_BITMAPCACHE_REV2:
+                break;
+            case CAPSTYPE_VIRTUALCHANNEL:
+                break;
+            case CAPSTYPE_DRAWNINEGRIDCACHE:
+                break;
+            case CAPSTYPE_DRAWGDIPLUS:
+                break;
+            case CAPSTYPE_RAIL:
+                break;
+            case CAPSTYPE_WINDOW:
+                break;
+            case CAPSETTYPE_COMPDESK:
+                break;
+            case CAPSETTYPE_MULTIFRAGMENTUPDATE:
+                break;
+            case CAPSETTYPE_LARGE_POINTER:
+                break;
+            case CAPSETTYPE_SURFACE_COMMANDS:
+                break;
+            case CAPSETTYPE_BITMAP_CODECS:
+                break;
+            case CAPSSETTYPE_FRAME_ACKNOWLEDGE:
+                break;
+            default:
+                // Ignore
+                break;
+            }
+
+            capabilityData.unref();
+        }
+
+        // TODO
+
+        buf.unref();
+    }
+
+    /**
+     * @see http://msdn.microsoft.com/en-us/library/cc240554.aspx
+     */
+    protected void handleBitmapCapabilities(ByteBuffer buf) {
+
+        // (2 bytes): A 16-bit, unsigned integer. The server MUST set this field to
+        // the color depth of the session, while the client SHOULD set this field to
+        // the color depth requested in the Client Core Data (section 2.2.1.3.2).
+        int preferredBitsPerPixel = buf.readUnsignedShortLE();
+        screen.setPixelFormatRGBTrueColor(preferredBitsPerPixel);
+
+        // receive1BitPerPixel (2 bytes): A 16-bit, unsigned integer. Indicates
+        // whether the client can receive 1 bpp. This field is ignored and SHOULD be
+        // set to TRUE (0x0001).
+        buf.skipBytes(2);
+
+        // receive4BitsPerPixel(2 bytes): A 16-bit, unsigned integer. Indicates
+        // whether the client can receive 4 bpp. This field is ignored and SHOULD be
+        // set to TRUE (0x0001).
+        buf.skipBytes(2);
+
+        // receive8BitsPerPixel (2 bytes): A 16-bit, unsigned integer. Indicates
+        // whether the client can receive 8 bpp. This field is ignored and SHOULD be
+        // set to TRUE (0x0001).
+        buf.skipBytes(2);
+
+        // (2 bytes): A 16-bit, unsigned integer. The width of the desktop in the
+        // session.
+        int desktopWidth = buf.readUnsignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. The height of the desktop in the
+        // session.
+        int desktopHeight = buf.readUnsignedShortLE();
+
+        screen.setFramebufferSize(desktopWidth, desktopHeight);
+
+        // pad2octets (2 bytes): A 16-bit, unsigned integer. Padding. Values in this
+        // field MUST be ignored.
+
+        // desktopResizeFlag (2 bytes): A 16-bit, unsigned integer. Indicates
+        // whether resizing the desktop by using a Deactivation-Reactivation
+        // Sequence is supported.
+
+        // bitmapCompressionFlag (2 bytes): A 16-bit, unsigned integer. Indicates
+        // whether bitmap compression is supported. This field MUST be set to TRUE
+        // (0x0001) because support for compressed bitmaps is required for a
+        // connection to proceed.
+
+        // highColorFlags (1 byte): An 8-bit, unsigned integer. Client support for
+        // 16 bpp color modes. This field is ignored and SHOULD be set to zero.
+
+        // drawingFlags (1 byte): An 8-bit, unsigned integer. Flags describing
+        // support for 32 bpp bitmaps.
+
+        // multipleRectangleSupport (2 bytes): A 16-bit, unsigned integer. Indicates
+        // whether the use of multiple bitmap rectangles is supported in the Bitmap
+        // Update (section 2.2.9.1.1.3.1.2). This field MUST be set to TRUE (0x0001)
+        // because multiple rectangle support is required for a connection to
+        // proceed.
+
+        // pad2octetsB (2 bytes): A 16-bit, unsigned integer. Padding. Values in
+        // this field MUST be ignored.
+    }
+
+    /**
+     * Send all client requests in one hop, to simplify logic.
+     */
+    protected void sendHandshakePackets() {
+        // Send reactivation sequence in bulk
+        pushDataToPad("confirm_active", new ByteBuffer((Order)null));
+    }
+
+    /**
+     * Example.
+     * 
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        0x67, 0x01,  //  TS_SHARECONTROLHEADER::totalLength = 0x0167 = 359 bytes
+        0x11, 0x00,  //  TS_SHARECONTROLHEADER::pduType = 0x0011 0x0011 = 0x0010 | 0x0001  = TS_PROTOCOL_VERSION | PDUTYPE_DEMANDACTIVEPDU
+
+        (byte) 0xea, 0x03,  //  TS_SHARECONTROLHEADER::pduSource = 0x03ea (1002)
+
+        (byte) 0xea, 0x03, 0x01, 0x00,  //  TS_DEMAND_ACTIVE_PDU::shareId
+        0x04, 0x00,  //  TS_DEMAND_ACTIVE_PDU::lengthSourceDescriptor = 4 bytes
+        0x51, 0x01,  //  TS_DEMAND_ACTIVE_PDU::lengthCombinedCapabilities = 0x151 = 337 bytes
+
+        0x52, 0x44, 0x50, 0x00,  //  TS_DEMAND_ACTIVE_PDU::sourceDescriptor = "RDP"
+
+        0x0d, 0x00,  //  TS_DEMAND_ACTIVE_PDU::numberCapabilities = 13
+        0x00, 0x00,  //  TS_DEMAND_ACTIVE_PDU::pad2octets
+
+        //  Share Capability Set (8 bytes)
+        // 0x09, 0x00, 0x08, 0x00, (byte) 0xea, 0x03, (byte) 0xdc, (byte) 0xe2,
+        // 
+        0x09, 0x00,  //  TS_SHARE_CAPABILITYSET::capabilitySetType = CAPSTYPE_SHARE (9)
+        0x08, 0x00,  //  TS_SHARE_CAPABILITYSET::lengthCapability = 8 bytes
+        (byte) 0xea, 0x03,  //  TS_SHARE_CAPABILITYSET::nodeID = 0x03ea (1002)
+        (byte) 0xdc, (byte) 0xe2,  //  TS_SHARE_CAPABILITYSET::pad2octets
+
+        //  General Capability Set (24 bytes)
+        // 0x01, 0x00, 0x18, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x04, 
+        // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 
+        // 
+        0x01, 0x00,  //  TS_GENERAL_CAPABILITYSET::capabilitySetType = CAPSTYPE_GENERAL (1)
+        0x18, 0x00,  //  TS_GENERAL_CAPABILITYSET::lengthCapability = 24 bytes
+
+        0x01, 0x00,  //  TS_GENERAL_CAPABILITYSET::osMajorType = TS_OSMAJORTYPE_WINDOWS (1)
+        0x03, 0x00,  //  TS_GENERAL_CAPABILITYSET::osMinorType = TS_OSMINORTYPE_WINDOWS_NT (3)
+        0x00, 0x02,  //  TS_GENERAL_CAPABILITYSET::protocolVersion = TS_CAPS_PROTOCOLVERSION (0x0200)
+        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::pad2octetsA
+        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::generalCompressionTypes = 0
+        0x1d, 0x04,  //  TS_GENERAL_CAPABILITYSET::extraFlags = 0x041d = 0x0400 | 0x0010 | 0x0008 | 0x0004 | 0x0001 = NO_BITMAP_COMPRESSION_HDR | ENC_SALTED_CHECKSUM | AUTORECONNECT_SUPPORTED | LONG_CREDENTIALS_SUPPORTED | FASTPATH_OUTPUT_SUPPORTED
+
+        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::updateCapabilityFlag = 0
+        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::remoteUnshareFlag = 0
+        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::generalCompressionLevel = 0
+        0x01,  //  TS_GENERAL_CAPABILITYSET::refreshRectSupport = TRUE
+        0x01,  //  TS_GENERAL_CAPABILITYSET::suppressOutputSupport = TRUE
+
+        // Virtual Channel Capability Set (8 bytes)
+        // 0x14, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 
+        // 
+        0x14, 0x00,  //  TS_VIRTUALCHANNEL_CAPABILITYSET::capabilitySetType = CAPSTYPE_VIRTUALCHANNEL (20)
+        0x08, 0x00,  //  TS_VIRTUALCHANNEL_CAPABILITYSET::lengthCapability = 8 bytes
+
+        0x02, 0x00, 0x00, 0x00,  //  TS_VIRTUALCHANNEL_CAPABILITYSET::vccaps1 = 0x00000002 = VCCAPS_COMPR_CS_8K
+
+        //  DrawGdiPlus Capability Set (40 bytes)
+        // 0x16, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, (byte) 0xf6, 0x13, (byte) 0xf3, 0x01, 0x00, 0x00, 0x00, 
+        // 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, (byte) 0x9c, (byte) 0xf6, 0x13, (byte) 0xf3, 0x61, (byte) 0xa6, (byte) 0x82, (byte) 0x80, 
+        // 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, (byte) 0x91, (byte) 0xbf, 
+        // 
+        0x16, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::capabilitySetType = CAPSTYPE_DRAWGDIPLUS (22)
+        0x28, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::lengthCapability = 40 bytes
+
+        0x00, 0x00, 0x00, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::drawGdiplusSupportLevel = TS_DRAW_GDIPLUS_DEFAULT (0)
+        0x70, (byte) 0xf6, 0x13, (byte) 0xf3,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::GdipVersion (not initialized by server)
+        0x01, 0x00, 0x00, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::drawGdiplusCacheLevel  = TS_DRAW_GDIPLUS_CACHE_LEVEL_ONE (1)
+
+        0x01, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipGraphicsCacheEntries  (not initialized by server)
+        0x00, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectBrushCacheEntries (not initialized by server)
+        0x18, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectPenCacheEntries (not initialized by server)
+        0x00, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectImageCacheEntries (not initialized by server)
+        (byte) 0x9c, (byte) 0xf6,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectImageAttributesCacheEntries (not initialized by server)
+
+        0x13, (byte) 0xf3,  //  TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipGraphicsCacheChunkSize  (not initialized by server)
+        0x61, (byte) 0xa6,  //  TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipObjectBrushCacheChunkSize (not initialized by server)
+        (byte) 0x82, (byte) 0x80,  //  TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipObjectPenCacheChunkSize (not initialized by server)
+        0x00, 0x00,  //   TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipObjectImageAttributesCacheChunkSize (not initialized by server)
+
+        0x00, 0x00,  //  TS_GDIPLUS_IMAGE_CACHE_PROPERTIES::GdipObjectImageCacheChunkSize  (not initialized by server)
+        0x00, 0x50,  //  TS_GDIPLUS_IMAGE_CACHE_PROPERTIES::GdipObjectImageCacheTotalSize  (not initialized by server)
+        (byte) 0x91, (byte) 0xbf,  //  TS_GDIPLUS_IMAGE_CACHE_PROPERTIES::GdipObjectImageCacheMaxSize (not initialized by server)
+
+        //  Font Capability Set (4 bytes)
+        // 0x0e, 0x00, 0x04, 0x00,
+        //
+        // Due to a bug, the TS_FONT_CAPABILITYSET capability set size is incorrectly set to 4 bytes (it must be 8 bytes). As a result of this bug, the fontSupportFlags and pad2octets fields are missing.
+        0x0e, 0x00,  //  TS_FONT_CAPABILITYSET::capabilitySetType = CAPSTYPE_FONT (14)
+        0x04, 0x00,  //  TS_FONT_CAPABILITYSET::lengthCapability = 4 bytes
+
+
+        //  Bitmap Capability Set (28 bytes)
+        // 0x02, 0x00, 0x1c, 0x00, 0x18, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 
+        // 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
+        // 
+        0x02, 0x00,  //  TS_BITMAP_CAPABILITYSET::capabilitySetType = CAPSTYPE_BITMAP (2)
+        0x1c, 0x00,  //  TS_BITMAP_CAPABILITYSET::lengthCapability = 28 bytes
+
+        0x18, 0x00,  //  TS_BITMAP_CAPABILITYSET::preferredBitsPerPixel = 24 bpp
+        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::receive1BitPerPixel = TRUE
+        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::receive4BitsPerPixel = TRUE
+        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::receive8BitsPerPixel = TRUE
+        0x00, 0x05,  //  TS_BITMAP_CAPABILITYSET::desktopWidth = 1280 pixels
+        0x00, 0x04,  //  TS_BITMAP_CAPABILITYSET::desktopHeight = 1024 pixels
+        0x00, 0x00,  //  TS_BITMAP_CAPABILITYSET::pad2octets
+        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::desktopResizeFlag = TRUE
+        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::bitmapCompressionFlag = TRUE
+        0x00,  //  TS_BITMAP_CAPABILITYSET::highColorFlags = 0
+        0x00,  //  TS_BITMAP_CAPABILITYSET::pad1octet
+        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::multipleRectangleSupport = TRUE
+        0x00, 0x00,  //  TS_BITMAP_CAPABILITYSET::pad2octetsB
+
+        //  Order Capability Set (88 bytes)
+        // 0x03, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        // 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 
+        // 0x00, 0x00, 0x22, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 
+        // 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 
+        // 0x00, 0x00, 0x00, 0x00, (byte) 0xa1, 0x06, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x40, 0x42, 0x0f, 0x00, 
+        // 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        // 
+        0x03, 0x00,  //  TS_ORDER_CAPABILITYSET::capabilitySetType = CAPSTYPE_ORDER (3)
+        0x58, 0x00,  //  TS_ORDER_CAPABILITYSET::lengthCapability = 88 bytes
+
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // TS_ORDER_CAPABILITYSET::terminalDescriptor = ""
+        0x40, 0x42, 0x0f, 0x00,  //  TS_ORDER_CAPABILITYSET::pad4octetsA
+
+        0x01, 0x00,  //  TS_ORDER_CAPABILITYSET::desktopSaveXGranularity = 1
+        0x14, 0x00,  //  TS_ORDER_CAPABILITYSET::desktopSaveYGranularity = 20
+        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsA
+        0x01, 0x00,  //  TS_ORDER_CAPABILITYSET::maximumOrderLevel = ORD_LEVEL_1_ORDERS (1)
+        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::numberFonts = 0
+
+        0x22, 0x00,  //  TS_ORDER_CAPABILITYSET::orderFlags = 0x0022 = 0x0020 | 0x0002 = COLORINDEXSUPPORT | NEGOTIATEORDERSUPPORT   
+
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_DSTBLT_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_PATBLT_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_SCRBLT_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEMBLT_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEM3BLT_INDEX] = TRUE
+        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_ATEXTOUT_INDEX] = FALSE
+        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_AEXTTEXTOUT_INDEX] = FALSE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_DRAWNINEGRID_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_LINETO_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTI_DRAWNINEGRID_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_OPAQUERECT_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_SAVEBITMAP_INDEX] = TRUE
+        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WTEXTOUT_INDEX] = FALSE
+        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEMBLT_R2_INDEX] = FALSE
+        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEM3BLT_R2_INDEX] = FALSE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTIDSTBLT_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTIPATBLT_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTISCRBLT_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTIOPAQUERECT_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_FAST_INDEX_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_POLYGON_SC_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_POLYGON_CB_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_POLYLINE_INDEX] = TRUE
+        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[23] = 0
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_FAST_GLYPH_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_ELLIPSE_SC_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_ELLIPSE_CB_INDEX] = TRUE
+        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_INDEX_INDEX] = TRUE
+        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WEXTTEXTOUT_INDEX] = FALSE
+        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WLONGTEXTOUT_INDEX] = FALSE
+        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WLONGEXTTEXTOUT_INDEX] = FALSE
+        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[24] = 0
+
+        (byte) 0xa1, 0x06,  //  TS_ORDER_CAPABILITYSET::textFlags = 0x06a1
+
+        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsB
+        0x40, 0x42, 0x0f, 0x00,  //  TS_ORDER_CAPABILITYSET::pad4octetsB
+
+        0x40, 0x42, 0x0f, 0x00,  //  TS_ORDER_CAPABILITYSET::desktopSaveSize = 0xf4240 = 1000000
+        0x01, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsC
+        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsD
+        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::textANSICodePage
+        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsE
+
+        // Color Table Cache Capability Set (8 bytes)
+        // 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 
+        // 
+        0x0a, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::capabilitySetType = CAPSTYPE_COLORCACHE (10)
+        0x08, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::lengthCapability = 8 bytes
+
+        0x06, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::colorTableCacheSize = 6
+        0x00, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::pad2octets
+
+        // Bitmap Cache Host Support Capability Set (8 bytes)
+        // 0x12, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 
+        // 
+        0x12, 0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::capabilitySetType  = CAPSTYPE_BITMAPCACHE_HOSTSUPPORT (18)
+        0x08, 0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::lengthCapability  = 8 bytes
+
+        0x01,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::CacheVersion = 1  (corresponds to rev. 2 capabilities)
+        0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::Pad1
+        0x00, 0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::Pad2
+
+        // Pointer Capability Set (10 bytes)
+        // 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00, 0x19, 0x00, 
+        // 
+        0x08, 0x00,  //  TS_POINTER_CAPABILITYSET::capabilitySetType = CAPSTYPE_POINTER (8)
+        0x0a, 0x00,  //  TS_POINTER_CAPABILITYSET::lengthCapability = 10 bytes
+
+        0x01, 0x00,  //  TS_POINTER_CAPABILITYSET::colorPointerFlag = TRUE
+        0x19, 0x00,  //  TS_POINTER_CAPABILITYSET::colorPointerCacheSize = 25
+        0x19, 0x00,  //  TS_POINTER_CAPABILITYSET::pointerCacheSize = 25
+
+        //  Input Capability Set (88 bytes)
+        // 0x0d, 0x00, 0x58, 0x00, 0x35, 0x00, 0x00, 0x00, (byte) 0xa1, 0x06, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 
+        // 0x0c, (byte) 0xf6, 0x13, (byte) 0xf3, (byte) 0x93, 0x5a, 0x37, (byte) 0xf3, 0x00, (byte) 0x90, 0x30, (byte) 0xe1, 0x34, 0x1c, 0x38, (byte) 0xf3, 
+        // 0x40, (byte) 0xf6, 0x13, (byte) 0xf3, 0x04, 0x00, 0x00, 0x00, 0x4c, 0x54, (byte) 0xdc, (byte) 0xe2, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 
+        // 0x01, 0x00, 0x00, 0x00, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 0x00, 0x00, 0x00, 0x00, 0x38, (byte) 0xf6, 0x13, (byte) 0xf3, 
+        // 0x2e, 0x05, 0x38, (byte) 0xf3, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 0x2c, (byte) 0xf6, 0x13, (byte) 0xf3, 0x00, 0x00, 0x00, 0x00, 
+        // 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00,
+        // 
+        0x0d, 0x00,  //  TS_INPUT_CAPABILITYSET::capabilitySetType = CAPSTYPE_INPUT (13)
+        0x58, 0x00,  //  TS_INPUT_CAPABILITYSET::lengthCapability = 88 bytes
+
+        0x35, 0x00,  //  TS_INPUT_CAPABILITYSET::inputFlags = 0x0035 = 0x0020 | 0x0010 | 0x0004 | 0x0001 = INPUT_FLAG_FASTPATH_INPUT2 | INPUT_FLAG_VKPACKET | INPUT_FLAG_MOUSEX | INPUT_FLAG_SCANCODES
+
+        0x00, 0x00,  //  TS_INPUT_CAPABILITYSET::pad2octetsA
+        (byte) 0xa1, 0x06, 0x00, 0x00,  //  TS_INPUT_CAPABILITYSET::keyboardLayout (not initialized by server)
+        0x40, 0x42, 0x0f, 0x00,  //  TS_INPUT_CAPABILITYSET::keyboardType (not initialized by server)
+        0x0c, (byte) 0xf6, 0x13, (byte) 0xf3,  //  TS_INPUT_CAPABILITYSET::keyboardSubType  (not initialized by server)
+        (byte) 0x93, 0x5a, 0x37, (byte) 0xf3,  //  TS_INPUT_CAPABILITYSET::keyboardFunctionKey (not initialized by server)
+
+        // TS_INPUT_CAPABILITYSET::imeFileName (not initialized by server)
+        0x00, (byte) 0x90, 0x30, (byte) 0xe1, 0x34, 0x1c, 0x38, (byte) 0xf3, 0x40, (byte) 0xf6, 0x13, (byte) 0xf3, 0x04, 0x00, 0x00, 0x00, 
+        0x4c, 0x54, (byte) 0xdc, (byte) 0xe2, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 0x01, 0x00, 0x00, 0x00, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 
+        0x00, 0x00, 0x00, 0x00, 0x38, (byte) 0xf6, 0x13, (byte) 0xf3, 0x2e, 0x05, 0x38, (byte) 0xf3, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 
+        0x2c, (byte) 0xf6, 0x13, (byte) 0xf3, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00, 
+
+        //  RAIL Capability Set (8 bytes)
+        // 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        // 
+        0x17, 0x00,  //  TS_RAIL_CAPABILITYSET::capabilitySetType = CAPSTYPE_RAIL (23)
+        0x08, 0x00,  //  TS_RAIL_CAPABILITYSET::lengthCapability = 8 bytes
+
+        0x00, 0x00, 0x00, 0x00,  //  TS_RAIL_CAPABILITYSET::railSupportLevel = TS_RAIL_LEVEL_DEFAULT (0)
+
+        //  Windowing Capability Set (11 bytes)
+        // 0x18, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        //
+        0x18, 0x00,  //  TS_WINDOW_CAPABILITYSET::capabilitySetType =  CAPSTYPE_WINDOW (24)
+        0x0b, 0x00,  //  TS_WINDOW_CAPABILITYSET::lengthCapability = 11 bytes
+
+        0x00, 0x00, 0x00, 0x00,  //  TS_WINDOW_CAPABILITYSET::wndSupportLevel = TS_WINDOW_LEVEL_DEFAULT (0)
+        0x00,  //  TS_WINDOW_CAPABILITYSET::nIconCaches = 0
+        0x00, 0x00,  //  TS_WINDOW_CAPABILITYSET::nIconCacheEntries = 0
+
+        // Remainder of Demand Active PDU:
+
+        0x00, 0x00, 0x00, 0x00,  //  TS_DEMAND_ACTIVE_PDU::sessionId = 0    
+    };
+    /* @formatter:on */
+
+        RdpState rdpState = new RdpState();
+        ScreenDescription screenDescription = new ScreenDescription();
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element demandActive = new ServerDemandActivePDU("demand_active", screenDescription, rdpState);
+        Element sink = new FakeSink("sink");
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, demandActive, sink);
+        pipeline.link("source", "demand_active", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerFastPath.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerFastPath.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerFastPath.java
new file mode 100755
index 0000000..f88f492
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerFastPath.java
@@ -0,0 +1,315 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240621.aspx
+ */
+public class ServerFastPath extends BaseElement {
+
+    /**
+     * TPKT protocol version (first byte).
+     */
+    public static final int PROTOCOL_TPKT = 0x03;
+
+    /**
+     * Fast path protocol version (first two bits of first byte).
+     */
+    public static final int PROTOCOL_FASTPATH = 0x00;
+
+    /**
+     * CredSSP packets.
+     */
+    public static final int PROTOCOL_CREDSSP = 0x30;
+
+    /**
+     * TPKT packets will be pushed to that pad.
+     */
+    public static final String TPKT_PAD = "tpkt";
+
+    /**
+     * CredSSP packets will be pushed to same pad as TPKT, because they are part
+     * of slow-path initialization sequence.
+     */
+    public static final String CREDSSP_PAD = "tpkt";
+
+    private static final String ORDERS_PAD = "orders";
+    private static final String BITMAP_PAD = "bitmap";
+    private static final String PALETTE_PAD = "palette";
+
+    /**
+     * Indicates that packet contains 8 byte secure checksum at top of packet. Top
+     * two bits of first byte.
+     */
+    public static final int FASTPATH_OUTPUT_SECURE_CHECKSUM = 1;
+
+    /**
+     * Indicates that packet contains 8 byte secure checksum at top of packet and
+     * packet content is encrypted. Top two bits of first byte.
+     */
+    public static final int FASTPATH_OUTPUT_ENCRYPTED = 2;
+
+    public static final int FASTPATH_UPDATETYPE_ORDERS = 0;
+    public static final int FASTPATH_UPDATETYPE_BITMAP = 1;
+    public static final int FASTPATH_UPDATETYPE_PALETTE = 2;
+    public static final int FASTPATH_UPDATETYPE_SYNCHRONIZE = 3;
+    public static final int FASTPATH_UPDATETYPE_SURFCMDS = 4;
+    public static final int FASTPATH_UPDATETYPE_PTR_NULL = 5;
+    public static final int FASTPATH_UPDATETYPE_PTR_DEFAULT = 6;
+    public static final int FASTPATH_UPDATETYPE_PTR_POSITION = 8;
+    public static final int FASTPATH_UPDATETYPE_COLOR = 9;
+    public static final int FASTPATH_UPDATETYPE_CACHED = 0xa;
+    public static final int FASTPATH_UPDATETYPE_POINTER = 0xb;
+
+    public static final int FASTPATH_FRAGMENT_SINGLE = 0;
+    public static final int FASTPATH_FRAGMENT_LAST = 1;
+    public static final int FASTPATH_FRAGMENT_FIRST = 2;
+    public static final int FASTPATH_FRAGMENT_NEXT = 3;
+
+    public static final int FASTPATH_OUTPUT_COMPRESSION_USED = 2;
+
+    public ServerFastPath(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // * DEBUG */System.out.println(buf.toHexString(buf.length));
+
+        // We need at 4 bytes to read packet type (TPKT or FastPath) and packet
+        // length
+        if (!cap(buf, 4, UNLIMITED, link, false))
+            return;
+
+        int typeAndFlags = buf.readUnsignedByte();
+
+        switch (typeAndFlags) {
+        case PROTOCOL_TPKT: // 0x03
+            handleTpkt(buf, link);
+            break;
+
+        case PROTOCOL_CREDSSP: // 0x30, potential clash with FastPath
+            handleCredSSP(buf, link);
+            break;
+
+        default: // (value & 0x03) == 0x00
+        case PROTOCOL_FASTPATH:
+            handleFastPath(buf, link, typeAndFlags);
+            break;
+        }
+
+    }
+
+    private void handleTpkt(ByteBuffer buf, Link link) {
+        // Reserved
+        buf.skipBytes(1);
+
+        // Read TPKT length
+        int length = buf.readUnsignedShort();
+
+        if (!cap(buf, length, length, link, false))
+            // Wait for full packet to arrive
+            return;
+
+        int payloadLength = length - buf.cursor;
+
+        // Extract payload
+        ByteBuffer outBuf = buf.slice(buf.cursor, payloadLength, true);
+        buf.unref();
+
+        if (verbose) {
+            outBuf.putMetadata("source", this);
+        }
+
+        pushDataToPad(TPKT_PAD, outBuf);
+    }
+
+    private void handleCredSSP(ByteBuffer buf, Link link) {
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: CredSSP data received: " + buf + ".");
+
+        // Store header position: will parse whole header later in BER format parser
+        int headerPosition = buf.cursor - 1;
+
+        long payloadLength = buf.readBerLength();
+        if (payloadLength > 10 * 1024)
+            throw new RuntimeException("[" + this + "] ERROR: CredSSP packets seems to be too long: " + payloadLength + "bytes. Data: " + buf + ".");
+
+        // Length is the size of payload, so we need to append size of header
+        int headerLength = buf.cursor - headerPosition;
+        int packetLength = (int)payloadLength + headerLength;
+        if (!cap(buf, packetLength, packetLength, link, false))
+            // Wait for full packet to arrive
+            return;
+
+        // Extract payload (with header)
+        ByteBuffer outBuf = buf.slice(headerPosition, packetLength, true);
+        buf.unref();
+
+        if (verbose) {
+            outBuf.putMetadata("source", this);
+        }
+
+        pushDataToPad(CREDSSP_PAD, outBuf);
+    }
+
+    private void handleFastPath(ByteBuffer buf, Link link, int typeAndFlags) {
+        // Number of bytes in updateData field (including header (1+1 or 2
+        // bytes))
+        int length = buf.readVariableUnsignedShort();
+
+        if (!cap(buf, length, length, link, false))
+            // Wait for full packet to arrive
+            return;
+
+        int type = typeAndFlags & 0x3;
+        int securityFlags = (typeAndFlags >> 6) & 0x3;
+
+        // Assertions
+        {
+            if (type != PROTOCOL_FASTPATH)
+                throw new RuntimeException("Unknown protocol. Expected protocol: 0 (FastPath). Actual protocol: " + type + ", data: " + buf + ".");
+
+            switch (securityFlags) {
+            case FASTPATH_OUTPUT_SECURE_CHECKSUM:
+                // TODO
+                throw new RuntimeException("Secure checksum is not supported in FastPath packets.");
+            case FASTPATH_OUTPUT_ENCRYPTED:
+                // TODO
+                throw new RuntimeException("Encryption is not supported in FastPath packets.");
+            }
+        }
+
+        // TODO: optional FIPS information, when FIPS is selected
+        // TODO: optional data signature (checksum), when checksum or FIPS is
+        // selected
+
+        // Array of FastPath update fields
+        while (buf.cursor < buf.length) {
+
+            int updateHeader = buf.readUnsignedByte();
+
+            int size = buf.readUnsignedShortLE();
+
+            int updateCode = updateHeader & 0xf;
+            int fragmentation = (updateHeader >> 4) & 0x3;
+            int compression = (updateHeader >> 6) & 0x3;
+
+            if (verbose)
+                System.out.println("[" + this + "] INFO: FastPath update received. UpdateCode: " + updateCode + ", fragmentation: " + fragmentation + ", compression: "
+                        + compression + ", size: " + size + ".");
+
+            ByteBuffer data = buf.readBytes(size);
+            buf.putMetadata("fragmentation", fragmentation);
+            buf.putMetadata("compression", compression);
+
+            switch (updateCode) {
+
+            case FASTPATH_UPDATETYPE_ORDERS:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_ORDERS.");
+                pushDataToPad(ORDERS_PAD, data);
+                break;
+
+            case FASTPATH_UPDATETYPE_BITMAP:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_BITMAP.");
+                pushDataToPad(BITMAP_PAD, data);
+                break;
+
+            case FASTPATH_UPDATETYPE_PALETTE:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PALETTE.");
+                pushDataToPad(PALETTE_PAD, data);
+                break;
+
+            case FASTPATH_UPDATETYPE_SYNCHRONIZE:
+                // @see http://msdn.microsoft.com/en-us/library/cc240625.aspx
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_SYNCHRONIZE.");
+
+                data.unref();
+
+                if (size != 0)
+                    throw new RuntimeException("Size of FastPath synchronize packet must be 0. UpdateCode: " + updateCode + ", fragmentation: " + fragmentation
+                            + ", compression: " + compression + ", size: " + size + ", data: " + data + ".");
+                break;
+
+            case FASTPATH_UPDATETYPE_SURFCMDS:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_SURFCMDS.");
+
+                break;
+
+            case FASTPATH_UPDATETYPE_PTR_NULL:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PTR_NULL.");
+
+                break;
+
+            case FASTPATH_UPDATETYPE_PTR_DEFAULT:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PTR_DEFAULT.");
+
+                break;
+
+            case FASTPATH_UPDATETYPE_PTR_POSITION:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PTR_POSITION.");
+
+                break;
+
+            case FASTPATH_UPDATETYPE_COLOR:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_COLOR.");
+
+                break;
+
+            case FASTPATH_UPDATETYPE_CACHED:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_CACHED.");
+
+                break;
+
+            case FASTPATH_UPDATETYPE_POINTER:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_POINTER.");
+
+                break;
+
+            default:
+                throw new RuntimeException("Unknown FastPath update. UpdateCode: " + updateCode + ", fragmentation: " + fragmentation + ", compression: " + compression
+                        + ", size: " + size + ", data: " + data + ".");
+
+            }
+            buf.unref();
+
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerIOChannelRouter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerIOChannelRouter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerIOChannelRouter.java
new file mode 100755
index 0000000..5fd6dc6
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerIOChannelRouter.java
@@ -0,0 +1,534 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class ServerIOChannelRouter extends BaseElement {
+
+    /**
+     * Demand Active PDU.
+     */
+    public static final int PDUTYPE_DEMANDACTIVEPDU = 0x1;
+
+    /**
+     * Confirm Active PDU.
+     */
+    public static final int PDUTYPE_CONFIRMACTIVEPDU = 0x3;
+
+    /**
+     * Deactivate All PDU.
+     */
+    public static final int PDUTYPE_DEACTIVATEALLPDU = 0x6;
+
+    /**
+     * Data PDU (actual type is revealed by the pduType2 field in the Share Data
+     * Header).
+     */
+    public static final int PDUTYPE_DATAPDU = 0x7;
+
+    /**
+     * Enhanced Security Server Redirection PDU.
+     */
+    public static final int PDUTYPE_SERVER_REDIR_PKT = 0xA;
+
+    protected RdpState state;
+
+    public ServerIOChannelRouter(String id, RdpState state) {
+        super(id);
+        this.state = state;
+    }
+
+    /**
+     * @see http://msdn.microsoft.com/en-us/library/cc240576.aspx
+     */
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        int length = buf.readUnsignedShortLE();
+        if (buf.length != length)
+        {
+            // It is ServerErrorAlert-ValidClient
+            // Ignore it
+            //throw new RuntimeException("[" + this + "] ERROR: Incorrect PDU length: " + length + ", data: " + buf + ".");
+        }
+
+        int type = buf.readUnsignedShortLE() & 0xf;
+
+        // int sourceId = buf.readUnsignedShortLE();
+        buf.skipBytes(2);
+
+        switch (type) {
+        case PDUTYPE_DEMANDACTIVEPDU:
+            pushDataToPad("demand_active", buf);
+            break;
+        case PDUTYPE_CONFIRMACTIVEPDU:
+            throw new RuntimeException("Unexpected client CONFIRM ACTIVE PDU. Data: " + buf + ".");
+        case PDUTYPE_DEACTIVATEALLPDU:
+            // pushDataToPad("deactivate_all", buf);
+            /* ignore */buf.unref();
+            break;
+        case PDUTYPE_DATAPDU:
+            handleDataPdu(buf);
+            break;
+        case PDUTYPE_SERVER_REDIR_PKT:
+            // pushDataToPad("server_redir", buf);
+            /* ignore */buf.unref();
+            break;
+        default:
+            throw new RuntimeException("[" + this + "] ERROR: Unknown PDU type: " + type + ", data: " + buf + ".");
+        }
+
+    }
+
+    /**
+     * Graphics Update PDU.
+     */
+    public static final int PDUTYPE2_UPDATE = 0x02;
+
+    /**
+     * Control PDU.
+     */
+    public static final int PDUTYPE2_CONTROL = 0x14;
+
+    /**
+     * Pointer Update PDU.
+     */
+    public static final int PDUTYPE2_POINTER = 0x1B;
+
+    /**
+     * Input Event PDU.
+     */
+    public static final int PDUTYPE2_INPUT = 0x1C;
+
+    /**
+     * Synchronize PDU.
+     */
+    public static final int PDUTYPE2_SYNCHRONIZE = 0x1F;
+
+    /**
+     * Refresh Rect PDU.
+     */
+    public static final int PDUTYPE2_REFRESH_RECT = 0x21;
+
+    /**
+     * Play Sound PDU.
+     */
+    public static final int PDUTYPE2_PLAY_SOUND = 0x22;
+
+    /**
+     * Suppress Output PDU.
+     */
+    public static final int PDUTYPE2_SUPPRESS_OUTPUT = 0x23;
+
+    /**
+     * Shutdown Request PDU.
+     */
+    public static final int PDUTYPE2_SHUTDOWN_REQUEST = 0x24;
+
+    /**
+     * Shutdown Request Denied PDU.
+     */
+    public static final int PDUTYPE2_SHUTDOWN_DENIED = 0x25;
+
+    /**
+     * Save Session Info PDU.
+     */
+    public static final int PDUTYPE2_SAVE_SESSION_INFO = 0x26;
+
+    /**
+     * Font List PDU.
+     */
+    public static final int PDUTYPE2_FONTLIST = 0x27;
+
+    /**
+     * Font Map PDU.
+     */
+    public static final int PDUTYPE2_FONTMAP = 0x28;
+
+    /**
+     * Set Keyboard Indicators PDU.
+     */
+    public static final int PDUTYPE2_SET_KEYBOARD_INDICATORS = 0x29;
+
+    /**
+     * Persistent Key List PDU.
+     */
+    public static final int PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST = 0x2B;
+
+    /**
+     * Bitmap Cache Error PDU.
+     */
+    public static final int PDUTYPE2_BITMAPCACHE_ERROR_PDU = 0x2C;
+
+    /**
+     * Set Keyboard IME Status PDU.
+     */
+    public static final int PDUTYPE2_SET_KEYBOARD_IME_STATUS = 0x2D;
+
+    /**
+     * Offscreen Bitmap Cache Error PDU.
+     */
+    public static final int PDUTYPE2_OFFSCRCACHE_ERROR_PDU = 0x2E;
+
+    /**
+     * Set Error Info PDU.
+     */
+    public static final int PDUTYPE2_SET_ERROR_INFO_PDU = 0x2F;
+
+    /**
+     * DrawNineGrid Cache Error PDU.
+     */
+    public static final int PDUTYPE2_DRAWNINEGRID_ERROR_PDU = 0x30;
+
+    /**
+     * GDI+ Error PDU.
+     */
+    public static final int PDUTYPE2_DRAWGDIPLUS_ERROR_PDU = 0x31;
+
+    /**
+     * Auto-Reconnect Status PDU.
+     */
+    public static final int PDUTYPE2_ARC_STATUS_PDU = 0x32;
+
+    /**
+     * Status Info PDU.
+     */
+    public static final int PDUTYPE2_STATUS_INFO_PDU = 0x36;
+
+    /**
+     * Monitor Layout PDU.
+     */
+    public static final int PDUTYPE2_MONITOR_LAYOUT_PDU = 0x37;
+
+    /**
+     * Indicates an Orders Update.
+     */
+    public static final int UPDATETYPE_ORDERS = 0x0000;
+
+    /**
+     * Indicates a Bitmap Graphics Update.
+     */
+    public static final int UPDATETYPE_BITMAP = 0x0001;
+
+    /**
+     * Indicates a Palette Update.
+     */
+    public static final int UPDATETYPE_PALETTE = 0x0002;
+
+    /**
+     * Indicates a Synchronize Update.
+     */
+    public static final int UPDATETYPE_SYNCHRONIZE = 0x0003;
+
+    /**
+     * @see http://msdn.microsoft.com/en-us/library/cc240577.aspx
+     */
+    protected void handleDataPdu(ByteBuffer buf) {
+
+        // (4 bytes): A 32-bit, unsigned integer. Share identifier for the packet.
+        long shareId = buf.readUnsignedIntLE();
+        if (shareId != state.serverShareId)
+            throw new RuntimeException("Unexpected share ID: " + shareId + ".");
+//    buf.skipBytes(4);
+
+        // Padding.
+        buf.skipBytes(1);
+
+        // (1 byte): An 8-bit, unsigned integer. The stream identifier for the
+        // packet.
+        // int streamId = buf.readUnsignedByte();
+        buf.skipBytes(1);
+
+        // (2 bytes): A 16-bit, unsigned integer. The uncompressed length of the
+        // packet in bytes.
+        int uncompressedLength = buf.readUnsignedShortLE();
+
+        // (1 byte): An 8-bit, unsigned integer. The type of Data PDU.
+        int type2 = buf.readUnsignedByte();
+
+        // (1 byte): An 8-bit, unsigned integer. The compression type and flags
+        // specifying the data following the Share Data Header
+        int compressedType = buf.readUnsignedByte();
+        if (compressedType != 0)
+            throw new RuntimeException("Compression of protocol packets is not supported. Data: " + buf + ".");
+
+        // (2 bytes): A 16-bit, unsigned integer. The compressed length of the
+        // packet in bytes.
+        int compressedLength = buf.readUnsignedShortLE();
+        if (compressedLength != 0)
+            throw new RuntimeException("Compression of protocol packets is not supported. Data: " + buf + ".");
+
+        ByteBuffer data = buf.readBytes(uncompressedLength - 18);
+        buf.unref();
+
+        switch (type2) {
+
+        case PDUTYPE2_UPDATE: {
+
+            // (2 bytes): A 16-bit, unsigned integer. Type of the graphics update.
+            int updateType = data.readUnsignedShortLE();
+            ByteBuffer payload = data.readBytes(data.length - data.cursor);
+            data.unref();
+
+            switch (updateType) {
+            case UPDATETYPE_ORDERS:
+                pushDataToPad("orders", payload);
+                break;
+            case UPDATETYPE_BITMAP:
+                pushDataToPad("bitmap", payload);
+                break;
+            case UPDATETYPE_PALETTE:
+                pushDataToPad("palette", payload);
+                break;
+            case UPDATETYPE_SYNCHRONIZE:
+                // Ignore
+                payload.unref();
+                break;
+            }
+
+            break;
+        }
+        case PDUTYPE2_CONTROL:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_CONTROL ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_POINTER:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_POINTER ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_INPUT:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_INPUT ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SYNCHRONIZE:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SYNCHRONIZE ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_REFRESH_RECT:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_REFRESH_RECT ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_PLAY_SOUND:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_PLAY_SOUND ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SUPPRESS_OUTPUT:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SUPPRESS_OUTPUT ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SHUTDOWN_REQUEST:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SHUTDOWN_REQUEST ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SHUTDOWN_DENIED:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SHUTDOWN_DENIED ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SAVE_SESSION_INFO:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SAVE_SESSION_INFO ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_FONTLIST:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_FONTLIST ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_FONTMAP:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_FONTMAP ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SET_KEYBOARD_INDICATORS:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SET_KEYBOARD_INDICATORS ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_BITMAPCACHE_ERROR_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_BITMAPCACHE_ERROR_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SET_KEYBOARD_IME_STATUS:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SET_KEYBOARD_IME_STATUS ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_OFFSCRCACHE_ERROR_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_OFFSCRCACHE_ERROR_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SET_ERROR_INFO_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SET_ERROR_INFO_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_DRAWNINEGRID_ERROR_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_DRAWNINEGRID_ERROR_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_DRAWGDIPLUS_ERROR_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_DRAWGDIPLUS_ERROR_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_ARC_STATUS_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_ARC_STATUS_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_STATUS_INFO_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_STATUS_INFO_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_MONITOR_LAYOUT_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_MONITOR_LAYOUT_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+
+        default:
+            throw new RuntimeException("Unknow data PDU type: " + type2 + ", data: " + buf + ".");
+        }
+    }
+
+    /**
+     * Example.
+     * 
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        byte[] packet = new byte[] {
+                // TPKT
+                (byte)0x03, (byte)0x00, // TPKT Header: TPKT version = 3
+                (byte)0x00, (byte)0x1B, // TPKT length: 27 bytes
+
+                // X224
+                (byte)0x02, // X224 Length: 2 bytes
+                (byte)0xF0, // X224 Type: Data
+                (byte)0x80, // X224 EOT
+
+                // MCS
+                // Type: send data indication: 26 (0x1a, top 6 bits)
+                (byte)0x68, // ??
+
+                (byte)0x00, (byte)0x01, // User ID: 1002 (1001+1)
+                (byte)0x03, (byte)0xEB, // Channel ID: 1003
+                (byte)0x70, // Data priority: high, segmentation: begin|end
+                (byte)0x0D, // Payload length: 13 bytes
+
+                // Deactivate all PDU
+                (byte)0x0D, (byte)0x00, // Length: 13 bytes (LE)
+
+                // - PDUType: (0x16, LE)
+                // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
+                // ProtocolVersion: (000000000001....) 1
+                (byte)0x16, (byte)0x00,
+
+                (byte)0xEA, (byte)0x03, // PDU source: 1002 (LE)
+                (byte)0xEA, (byte)0x03, (byte)0x01, (byte)0x00, // ShareID = 66538
+
+                (byte)0x01, (byte)0x00, // Length if source descriptor: 1 (LE)
+                (byte)0x00, // Source descriptor (should be set to 0): 0
+        };
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        RdpState rdpState = new RdpState() {
+            {
+                serverShareId = 66538;
+            }
+        };
+        Element channel1003 = new ServerIOChannelRouter("channel_1003", rdpState);
+        Element mcs = new ServerMCSPDU("mcs");
+        Element tpkt = new ServerTpkt("tpkt");
+        Element x224 = new ServerX224DataPdu("x224");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
+                // Deactivate all PDU
+                (byte)0x0D, (byte)0x00, // Length: 13 bytes (LE)
+
+                // - PDUType: 22 (0x16, LE)
+                // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
+                // ProtocolVersion: (000000000001....) 1
+                (byte)0x16, (byte)0x00,
+
+                (byte)0xEA, (byte)0x03, // PDU source: 1002 (LE)
+                (byte)0xEA, (byte)0x03, (byte)0x01, (byte)0x00, // ShareID = 66538
+
+                (byte)0x01, (byte)0x00, // Length if source descriptor: 1 (LE)
+                (byte)0x00, // Source descriptor (should be set to 0): 0
+        }));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, tpkt, x224, mcs, channel1003, sink);
+        pipeline.link("source", "tpkt", "x224", "mcs >channel_1003", "channel_1003 >deactivate_all", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerLicenseErrorPDUValidClient.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerLicenseErrorPDUValidClient.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerLicenseErrorPDUValidClient.java
new file mode 100755
index 0000000..22e8094
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerLicenseErrorPDUValidClient.java
@@ -0,0 +1,121 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 rdpclient.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ServerLicenseErrorPDUValidClient extends OneTimeSwitch {
+
+    public ServerLicenseErrorPDUValidClient(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Ignore packet
+        buf.unref();
+        switchOff();
+    }
+
+    /* @formatter:off */
+//   * Server Error alert
+//
+//03 00 00 22 02 F0 80 68 00 01 03 EB 70 14 80 00 F1 BC FF 03 10 00 07 00 00 00 02 00 00 00 04 00 00 00
+//
+//
+// Frame: Number = 30, Captured Frame Length = 91, MediaType = DecryptedPayloadHeader
+//+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+// TLSSSLData: Transport Layer Security (TLS) Payload Data
+//+ TLS: TLS Rec Layer-1 SSL Application Data
+// ISOTS: TPKTCount = 1
+//- TPKT: version: 3, Length: 34
+//    version: 3 (0x3)
+//    Reserved: 0 (0x0)
+//    PacketLength: 34 (0x22)
+//- X224: Data
+//    Length: 2 (0x2)
+//    Type: Data
+//    EOT: 128 (0x80)
+//- T125: Data Packet
+// - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
+//  - Type: Send Data Indication
+//    - RootIndex: 26
+//      Value: (011010..) 0x1a
+//  - UserID: 0x3ea
+//    - UserID: 0x3ea
+//    - ChannelId: 1002
+//     - Align: No Padding
+//        Padding2: (00......) 0x0
+//       Value: 1 (0x1)
+//  - Channel: 0x3eb
+//    - ChannelId: 1003
+//      Align: No Padding
+//      Value: 1003 (0x3EB)
+//  - DataPriority: high
+//    - DataPriority: high
+//    - RootIndex: 1
+//       Value: (01......) 0x1
+//  - Segmentation: Begin End
+//     Begin: (1.......) Begin
+//     End:   (.1......) End
+//  - Length: 20
+//    - Align: No Padding
+//      Padding4: (0000....) 0x0
+//     Length: 20
+//    RDP: RDPBCGR
+//- RDPBCGR: RDPELE
+// - SecurityHeader: License Packet
+//  - Flags: 128 (0x80)
+//     SecurityExchange:        (...............0) Not Security Exchange PDU
+//     Reserved1:               (.............00.) Reserved
+//     Encrypted:               (............0...) Not Encrypted packet
+//     ResetSeqNumber:          (...........0....) MUST be ignored.
+//     IgnoreSeqNumber:         (..........0.....) MUST be ignored.
+//     InfoPacket:              (.........0......) Not Client Info PDU
+//     LicensePacket:           (........1.......) License Packet
+//     Reserved2:               (.......0........) Reserved
+//     LicensePacketEncryption: (......0.........) Not License Packet Encryption
+//     ServerRedirectionPacket: (.....0..........) Not Standard Security Server Redirection PDU
+//     ImprovedChecksumForMACG: (....0...........) Not Improved Checksum for MAC Generation
+//     Reserved3:               (.000............) Reserved
+//     FlagsHiValid:            (0...............) FlagsHi should be ignored
+//    FlagsHi: Should be ignored
+//- RDPELE: GM_ERROR_ALERT
+// - TsPreambleHeader: Type = GM_ERROR_ALERT
+//    MsgType: GM_ERROR_ALERT
+//  - Flags: 3 (0x3)
+//     LicenseProtocolVersionMask: (....0011) RDP 5.0, 5.1, 5.2, 6.0, 6.1, and 7.0
+//     Unused:                     (.000....)
+//     ExtendedErrorMSGsupported:  (0.......) that extended error information using the License Error Message is NOT supported.
+//    MsgSize: 16 (0x10)
+// - TsLicenseErrorMessage: ErrorCode = STATUS_VALID_CLIENT
+//    ErrorCode: STATUS_VALID_CLIENT
+//    StateTransition: ST_NO_TRANSITION
+//  - LiceseBinaryBlob: Type = Not Available
+//     RandomData: This value should be ignored
+//     BlobLen: 0 (0x0)
+//
+
+}