PCFkb2N0eXBlIGh0bWwgcHVibGljICItLy93M2MvL2R0ZCBodG1sIDQuMCB0cmFuc2l0aW9uYWwvL2VuIj4KPGh0bWw+CjxoZWFkPgo8dGl0bGU+QWN0aXZlWCBTdXBwb3J0IEluIFNXVDwvdGl0bGU+CjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iLi4vLi4vZGVmYXVsdF9zdHlsZS5jc3MiPgo8L2hlYWQ+Cjxib2R5IGJnY29sb3I9IiNGRkZGRkYiPgoJCTxkaXYgYWxpZ249InJpZ2h0Ij4KCQkJPGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuLCBUaW1lcywgc2VyaWYiIHNpemU9IjIiPkNvcHlyaWdodCAKICAmY29weTsgMjAwMSBPYmplY3QgVGVjaG5vbG9neSBJbnRlcm5hdGlvbmFsLCBJbmMuPC9mb250PgombmJzcDsKCgkJCTx0YWJsZSBCT1JERVI9MCBDRUxMU1BBQ0lORz0wIENFTExQQURESU5HPTIgV0lEVEg9IjEwMCUiID4KCQkJCTx0cj4KCQkJCQk8dGQgQUxJR049TEVGVCBWQUxJR049VE9QIENPTFNQQU49IjIiIEJHQ09MT1I9IiMwMDgwQzAiPjxiPjxmb250IGZhY2U9IkFyaWFsLEhlbHZldGljYSI+PGZvbnQgY29sb3I9IiNGRkZGRkYiPiZuYnNwO0VjbGlwc2UKQ29ybmVyIEFydGljbGU8L2ZvbnQ+PC9mb250PjwvYj48L3RkPgoJCQkJPC90cj4KCQkJPC90YWJsZT4KCQk8L2Rpdj4KCQk8aDE+PGltZyBTUkM9IklkZWEuanBnIiBoZWlnaHQ9ODYgd2lkdGg9MTIwIGFsaWduPUNFTlRFUj48L2gxPgoJCTxjZW50ZXI+CiAgPGgxPkFjdGl2ZVggU3VwcG9ydCBJbiBTV1Q8L2gxPgo8L2NlbnRlcj4KCjxjZW50ZXI+CjxoMz5Ib3cgZG8gSSBpbmNsdWRlIGFuIE9MRSBEb2N1bWVudCBvciBBY3RpdmVYIENvbnRyb2wgaW4gbXkgRWNsaXBzZSBwbHVnaW4/PC9oMz48L2NlbnRlcj4KCjxibG9ja3F1b3RlPjxiPlN1bW1hcnk8L2I+Cjxicj5PTEUgRG9jdW1lbnRzLCBzdWNoIGFzIFdvcmQsIEV4Y2VsIG9yIFBvd2VyUG9pbnQsIGFuZCBBY3RpdmVYIENvbnRyb2xzIHN1Y2ggYXMgSW50ZXJuZXQgRXhwbG9yZXIKYXJlIENPTSBvYmplY3RzIHRoYXQgY2FuIGJlIGVtYmVkZGVkIGludG8gb3RoZXIgYXBwbGljYXRpb25zIHJ1bm5pbmcgb24gYSBNaWNyb3NvZnQmcmVnOyBXaW5kb3dzJnJlZzsgCnBsYXRmb3JtLiBUaGlzIGFydGljbGUgcHJvdmlkZXMgYW4gb3ZlcnZpZXcgb2YgaW50ZWdyYXRpbmcgT0xFIERvY3VtZW50cyAKYW5kIEFjdGl2ZVggQ29udHJvbHMgaW50byBhbiBhcHBsaWNhdGlvbiB1c2luZyBTV1QuCgo8cD48Yj5CeSBWZXJvbmlrYSBJcnZpbmUsIE9USTwvYj4KPGJyPgogIDxmb250IHNpemU9Ii0xIj5NYXJjaCAyMiwgMjAwMTwvZm9udD4gPC9wPgo8L2Jsb2NrcXVvdGU+Cgo8aHIgV0lEVEg9IjEwMCUiPgoKCgo8aDI+RW1iZWRkaW5nIGFuIE9MRSBPYmplY3QgaW4geW91ciBTV1QgQXBwbGljYXRpb248L2gyPgogICAgICAgIDxwPk9MRSBPYmplY3RzIGNhbiBiZSBjb250YWluZWQgaW4gU1dUIHdpZGdldHMuIEZyb20gdGhlcmUsIHRoZXkgY2FuIGJlCiAgICAgICAgYWN0aXZhdGVkIGFuZCBkZWFjdGl2YXRlZCBmb3IgdXNlciBpbnRlcmFjdGlvbiwgYW5kIG1hbmlwdWxhdGVkIGJ5IHRoZQogICAgICAgIGFwcGxpY2F0aW9uIGFjY29yZGluZyB0byB0aGVpciBzcGVjaWZpY2F0aW9uLiBGb3IgZXhhbXBsZSwgZWRpdGVkIGRhdGEKICAgICAgICBhbmQgc3RhdGUgY2FuIGJlIHJldHJpZXZlZCBvciBzYXZlZC4gSWYgdGhlIG9iamVjdCBpcyBubyBsb25nZXIKICAgICAgICByZXF1aXJlZCwgaXQgY2FuIGJlIGRpc3Bvc2VkLjwvcD4KPGgzPkNyZWF0ZSB0aGUgT0xFIE9iamVjdDwvaDM+CkFuIE9MRSBEb2N1bWVudCBvciBBY3RpdmVYIENvbnRyb2wgaXMgYWRkZWQgdG8gYW4gYXBwbGljYXRpb24gYnkgaW5zZXJ0aW5nIGl0IGludG8gYSBDb250YWluZXIuClRoZSBDb250YWluZXIgaXMgbWFkZSB1cCBvZiB0d28gcGFydHM6CjxvbD4KPGxpPlRoZSA8aT4gT2xlRnJhbWU8L2k+IG9iamVjdCBoYW5kbGVzIHNpemluZywgbWVudSBtYW5hZ2VtZW50IGFuZCB3aW5kb3cgcGxhY2VtZW50LjwvbGk+CjxsaT5UaGUgPGk+IE9sZUNsaWVudFNpdGU8L2k+IChmb3IgT0xFIERvY3VtZW50cykgb3IgPGk+IE9sZUNvbnRyb2xTaXRlPC9pPiAoZm9yIEFjdGl2ZVggQ29udHJvbHMpIGhhbmRsZXMKaW50ZXJhY3Rpb25zIHdpdGggYSBzcGVjaWZpYyBPTEUgT2JqZWN0LjwvbGk+Cjwvb2w+Cgo8cD5UaGUgZmlyc3Qgc3RlcCBpbiBlbWJlZGRpbmcgYW4gT0xFIE9iamVjdCBpcyB0byBjcmVhdGUgdGhlIDxpPk9sZUZyYW1lPC9pPjoKPHByZT4KCURpc3BsYXkgZGlzcGxheSA9IG5ldyBEaXNwbGF5KCk7CglTaGVsbCBzaGVsbCA9IG5ldyBTaGVsbChkaXNwbGF5KTsKCU9sZUZyYW1lIGZyYW1lID0gbmV3IE9sZUZyYW1lKHNoZWxsLCBTV1QuTk9ORSk7CjwvcHJlPgoKPHA+V2hlbiBhY3RpdmF0ZWQsIGFuIE9MRSBEb2N1bWVudCBkaXNwbGF5cyBpdHMgb3duIG1lbnUgYmFyIG92ZXIgdG9wIG9mIHRoZSBhcHBsaWNhdGlvbidzCm1lbnUgYmFyLgpUaGUgYXBwbGljYXRpb24gY2FuIGNvbnRyaWJ1dGUgbWVudXMgdG8gdGhlIE9MRSBEb2N1bWVudCdzIG1lbnUgYmFyIHRocm91Z2ggdGhlIDxpPiBPbGVGcmFtZTwvaT4gCmFzIGZvbGxvd3M6Cgo8cHJlPgoJTWVudSBiYXIgPSBuZXcgTWVudShzaGVsbCwgU1dULkJBUik7CglzaGVsbC5zZXRNZW51QmFyKGJhcik7CgkKCU1lbnVJdGVtIGZpbGVJdGVtMSA9IG5ldyBNZW51SXRlbShiYXIsIFNXVC5DQVNDQURFKTsKCWZpbGVJdGVtMS5zZXRUZXh0KCZxdW90OyZhbXA7RmlsZV9JdGVtXzEmcXVvdDspOwoJTWVudUl0ZW0gZmlsZUl0ZW0yID0gbmV3IE1lbnVJdGVtKGJhciwgU1dULkNBU0NBREUpOwoJZmlsZUl0ZW0yLnNldFRleHQoJnF1b3Q7JmFtcDtGaWxlX0l0ZW1fMiZxdW90Oyk7CgoJTWVudUl0ZW0gY29udGFpbmVySXRlbSA9IG5ldyBNZW51SXRlbShiYXIsIFNXVC5DQVNDQURFKTsKCWNvbnRhaW5lckl0ZW0uc2V0VGV4dCgmcXVvdDsmYW1wO0NvbnRhaW5lcl9JdGVtJnF1b3Q7KTsKCglNZW51SXRlbSB3aW5kb3dJdGVtMSA9IG5ldyBNZW51SXRlbShiYXIsIFNXVC5DQVNDQURFKTsKCXdpbmRvd0l0ZW0xLnNldFRleHQoJnF1b3Q7JmFtcDtXaW5kb3dfSXRlbV8xJnF1b3Q7KTsKCU1lbnVJdGVtIHdpbmRvd0l0ZW0yID0gbmV3IE1lbnVJdGVtKGJhciwgU1dULkNBU0NBREUpOwoJd2luZG93SXRlbTIuc2V0VGV4dCgmcXVvdDsmYW1wO1dpbmRvd19JdGVtXzImcXVvdDspOwoKCWZyYW1lLnNldEZpbGVNZW51cyhuZXcgTWVudUl0ZW1bXSB7ZmlsZUl0ZW0xLCBmaWxlSXRlbTJ9KTsKCWZyYW1lLnNldENvbnRhaW5lck1lbnVzKG5ldyBNZW51SXRlbVtdIHtjb250YWluZXJJdGVtfSk7CglmcmFtZS5zZXRXaW5kb3dNZW51cyhuZXcgTWVudUl0ZW1bXSB7d2luZG93SXRlbTEsIHdpbmRvd0l0ZW0yfSk7CjwvcHJlPgoKPHA+VGhlIG5leHQgc3RlcCBpcyB0byBjcmVhdGUgYW4gPGk+IE9sZUNsaWVudFNpdGU8L2k+IG9yIGFuIDxpPk9sZUNvbnRyb2xTaXRlPC9pPi4KU29tZSBDT00gb2JqZWN0cyBjYW4gZnVuY3Rpb24gYXMgYm90aCBhbiBPTEUgRG9jdW1lbnQgYW5kIGFuIEFjdGl2ZVggQ29udHJvbC4gIApFbWJlZGRpbmcgYW4gT0xFIERvY3VtZW50IGlzIGVxdWl2YWxlbnQgdG8gZW1iZWRkaW5nIHRoZSBlbnRpcmUgYXBwbGljYXRpb24uIApUaGUgT0xFIERvY3VtZW50IHByb3ZpZGVzIGl0cyBvd24gdG9vbGJhciBhbmQgbWVudSBiYXIgZm9yIGFjY2Vzc2luZyBpdHMgYmVoYXZpb3IuICAKQW4gQWN0aXZlWCBDb250cm9sIG9ubHkgcHJvdmlkZXMgdGhlIGNvbnRlbnQgcGFydCBhbmQgdGhlIHBhcmVudCBhcHBsaWNhdGlvbiBtdXN0IG1hbmFnZSB0aGUKYmVoYXZpb3Igb2YgdGhlIGNvbnRlbnQgdGhyb3VnaCB0aGUgQVBJIG9mIHRoZSBBY3RpdmVYIENvbnRyb2wuClRvIGRldGVybWluZSBpZiBhIENPTSBvYmplY3Qgc3VwcG9ydHMgdGhlIE9MRSBEb2N1bWVudCBiZWhhdmlvciwgbG9vayBmb3IKdGhlIElPbGVEb2N1bWVudCBpbnRlcmZhY2UuClRvIGRldGVybWluZSBpZiBhIENPTSBvYmplY3Qgc3VwcG9ydHMgdGhlIEFjdGl2ZVggQ29udHJvbCBiZWhhdmlvciwgbG9vayBmb3IgCnRoZSBJT2xlQ29udHJvbCBpbnRlcmZhY2UuIApUbyBzZWUgd2hpY2ggaW50ZXJmYWNlcyB0aGUgT0xFIE9iamVjdCBpbXBsZW1lbnRzLCBsb29rIGF0IHRoZSB0eXBlIGxpYnJhcnkuIAoKPHA+VG8gZW1iZWQgYW4gT0xFIERvY3VtZW50LCBjcmVhdGUgYW4gPGk+IE9sZUNsaWVudFNpdGU8L2k+IG9iamVjdC4KVG8gZW1iZWQgYW4gQWN0aXZlWCBDb250cm9sLCBjcmVhdGUgYW4gPGk+IE9sZUNvbnRyb2xTaXRlPC9pPiBvYmplY3QuClRoZSBwYXJlbnQgaW4gZWl0aGVyIGNhc2UgaXMgdGhlIDxpPk9sZUZyYW1lPC9pPi4gCldoZW4geW91IGNyZWF0ZSB0aGUgPGk+IE9sZUNsaWVudFNpdGU8L2k+IG9yIHRoZSA8aT5PbGVDb250cm9sU2l0ZTwvaT4sIHRoZSBhc3NvY2lhdGVkIE9MRSBEb2N1bWVudCBvciBBY3RpdmVYIENvbnRyb2wgCndpbGwgYXV0b21hdGljYWxseSBiZSBjcmVhdGVkIGFuZCBhc3NvY2lhdGVkIHdpdGggdGhlIGNvbnRhaW5lciBzaXRlLgoKPHA+VGhlcmUgYXJlIHR3byB3YXlzIHRvIGNyZWF0ZSBhbiA8aT5PbGVDbGllbnRTaXRlPC9pPjoKPG9sPgo8bGk+Q3JlYXRlIGFuIDxpPiBPbGVDbGllbnRTaXRlPC9pPiBmcm9tIGEgUHJvZ3JhbUlELiAKQSBQcm9ncmFtSUQgaXMgYSBzdHJpbmcgdGhhdCBpZGVudGlmaWVzIHRoZSBhcHBsaWNhdGlvbi4KRm9yIGV4YW1wbGUsIHRoZSBQcm9ncmFtSUQgZm9yIFdvcmQgaXMgk1dvcmQuRG9jdW1lbnSUIGFuZCB0aGUgUHJvZ3JhbUlEIGZvciBFeGNlbCBpcwqTRXhjZWwuQ2hhcnSULiBUaGUgUHJvZ3JhbUlEIGZvciBhbiBhcHBsaWNhdGlvbiBjYW4gYmUgZm91bmQgaW4gdGhlIFdpbmRvd3MgUmVnaXN0cnkuClVzaW5nIHRoZSBmb2xsb3dpbmcgY29uc3RydWN0b3IsIGEgYmxhbmsgZG9jdW1lbnQgaXMgY3JlYXRlZCAoc2ltaWxhciB0byBjaG9vc2luZwpGaWxlLT5OZXcgZnJvbSBhIHN0YW5kYWxvbmUgYXBwbGljYXRpb24pOjwvbGk+Cgo8cHJlPgoJT2xlQ2xpZW50U2l0ZSBjbGllbnRTaXRlID0gbmV3IE9sZUNsaWVudFNpdGUoZnJhbWUsIFNXVC5OT05FLCCTV29yZC5Eb2N1bWVudJQpOwo8L3ByZT4KCjxsaT5DcmVhdGUgYW4gPGk+IE9sZUNsaWVudFNpdGU8L2k+IGZyb20gYSBTdG9yYWdlIGZpbGUuCkEgU3RvcmFnZSBmaWxlIGlzIGEgZmlsZSB3aXRoIGFuIE9MRSBmb3JtYXQgdGhhdCBjb250YWlucyBpbmZvcm1hdGlvbgphYm91dCB0aGUgdHlwZSBvZiBPTEUgT2JqZWN0IHRoYXQgY2FuIHZpZXcgaXQuIEl0IGFsc28gY29udGFpbnMgYSBzdHJ1Y3R1cmVkCnN0b3JhZ2UgZm9ybWF0IGFuZCB3aWxsIHN0b3JlIGluZm9ybWF0aW9uIHN1Y2ggYXMgcGFyYWdyYXBoIGZvcm1hdHMsIGRpY3Rpb25hcmllcwpvciBBdXRob3IvVGl0bGUvRGVzY3JpcHRpb24gdGFncy4gIEZvciBleGFtcGxlLCBhIJMuZG9jlCBmaWxlIGNyZWF0ZWQgYnkKV29yZCBpcyBhIFN0b3JhZ2UgZmlsZS4gR2l2ZW4gYSBTdG9yYWdlIGZpbGUsIE9MRSB3aWxsIGZpZ3VyZQpvdXQgd2hpY2ggT0xFIERvY3VtZW50IHRvIGNyZWF0ZS48L2xpPgoKPHByZT4KCUZpbGUgZmlsZSA9IG5ldyBGaWxlKJNDOlxcT2xlRG9jdW1lbnRhdGlvbi5kb2OUKTsKCU9sZUNsaWVudFNpdGUgY2xpZW50U2l0ZSA9IG5ldyBPbGVDbGllbnRTaXRlKGZyYW1lLCBTV1QuTk9ORSwgZmlsZSk7CjwvcHJlPgo8L29sPgoKPHA+QW4gPGk+IE9sZUNvbnRyb2xTaXRlPC9pPiBpcyBjcmVhdGVkIGZyb20gdGhlIFByb2dyYW1JRCBmb3IgdGhlIEFjdGl2ZVggQ29udHJvbC4gCkZvciBleGFtcGxlLCB0aGUgUHJvZ3JhbUlEIGZvciB0aGUgSW50ZXJuZXQgRXhwbG9yZXIgaXMgk1NoZWxsLkV4cGxvcmVylC4gIApUaGUgd2ViIGJyb3dzZXIgY2FuIGJlIGVtYmVkZGVkIGluIGFuIGFwcGxpY2F0aW9uIGFzCmZvbGxvd3M6Cgo8cHJlPgoJT2xlQ29udHJvbFNpdGUgY29udHJvbFNpdGUgPSBuZXcgT2xlQ29udHJvbFNpdGUoZnJhbWUsIFNXVC5OT05FLCAmcXVvdDtTaGVsbC5FeHBsb3JlciZxdW90Oyk7CjwvcHJlPgoKPGgzPkFjdGl2YXRlIHRoZSBPTEUgT2JqZWN0PC9oMz4KClRoZSBmaW5hbCBzdGVwIGJlZm9yZSBhbiBPTEUgRG9jdW1lbnQgb3IgQWN0aXZlWCBjb250cm9sIGJlY29tZXMgdmlzaWJsZSBpbnNpZGUgdGhlCiAgICAgICAgYXBwbGljYXRpb24gCmlzIHRvIGFjdGl2YXRlIHRoZSBPTEUgT2JqZWN0IChvZnRlbiByZWZlcnJlZCB0byBhcyA8aT4gaW4tcGxhY2UgYWN0aXZhdGlvbjwvaT4pLgpUaGlzIGlzIGRvbmUgYnkgaW52b2tpbmcgdGhlIJNkb1ZlcmKUIGFjdGlvbiBvbiB0aGUgPGk+IE9sZUNsaWVudFNpdGU8L2k+Cm9yIDxpPiBPbGVDb250cm9sU2l0ZTwvaT4uIFRoZSCTZG9WZXJilCBzeW50YXggaXMgYXMgZm9sbG93czoKPHByZT4KCXB1YmxpYyBpbnQgZG9WZXJiKGludCB2ZXJiKQo8L3ByZT4KCndoZXJlCjx1bD4KPGxpPgo8Yj52ZXJiPC9iPiCWIGFuIGludGVnZXIgdmFsdWUgbWFwcGluZyB0byBvbmUgb2YgdGhlIGZvbGxvd2luZyBwcmUtZGVmaW5lZCB2ZXJiIHZhbHVlczoKPC9saT4KCjx1bD4KPGxpPk9MRS5PTEVJVkVSQl9QUklNQVJZIC0gU3BlY2lmaWVzIHRoZSBhY3Rpb24gdGhhdCBvY2N1cnMgd2hlbiBhbiBlbmQgdXNlciBkb3VibGUtY2xpY2tzCnRoZSBvYmplY3QgaW4gaXRzIGNvbnRhaW5lci4gVGhlIG9iamVjdCwgbm90IHRoZSBjb250YWluZXIsIGRldGVybWluZXMKdGhpcyBhY3Rpb24uIElmIHRoZSBvYmplY3Qgc3VwcG9ydHMgaW4tcGxhY2UgYWN0aXZhdGlvbiwgdGhlIHByaW1hcnkgdmVyYgp1c3VhbGx5IGFjdGl2YXRlcyB0aGUgb2JqZWN0IGluIHBsYWNlLjwvbGk+Cgo8bGk+T0xFLk9MRUlWRVJCX1NIT1cgLSBJbnN0cnVjdHMgYW4gb2JqZWN0IHRvIHNob3cgaXRzZWxmIGZvciBlZGl0aW5nIG9yIHZpZXdpbmcuCkNhbGxlZCB0byBkaXNwbGF5IG5ld2x5IGluc2VydGVkIG9iamVjdHMgZm9yIGluaXRpYWwgZWRpdGluZyBhbmQgdG8gc2hvdwpsaW5rIHNvdXJjZXMuIFVzdWFsbHkgYW4gYWxpYXMgZm9yIHNvbWUgb3RoZXIgb2JqZWN0LWRlZmluZWQgdmVyYi48L2xpPgoKPGxpPk9MRS5PTEVJVkVSQl9PUEVOIC0gSW5zdHJ1Y3RzIGFuIG9iamVjdCwgaW5jbHVkaW5nIG9uZSB0aGF0IG90aGVyd2lzZSBzdXBwb3J0cwppbi1wbGFjZSBhY3RpdmF0aW9uLCB0byBvcGVuIGl0c2VsZiBmb3IgZWRpdGluZyBpbiBhIHdpbmRvdyBzZXBhcmF0ZSBmcm9tCnRoYXQgb2YgaXRzIGNvbnRhaW5lci4gSWYgdGhlIG9iamVjdCBkb2VzIG5vdCBzdXBwb3J0IGluLXBsYWNlIGFjdGl2YXRpb24sCnRoaXMgdmVyYiBoYXMgdGhlIHNhbWUgc2VtYW50aWNzIGFzIE9MRUlWRVJCX1NIT1cuPC9saT4KCjxsaT5PTEUuT0xFSVZFUkJfSElERSAtIENhdXNlcyBhbiBvYmplY3QgdG8gcmVtb3ZlIGl0cyB1c2VyIGludGVyZmFjZSBmcm9tIHRoZQp2aWV3LiBBcHBsaWVzIG9ubHkgdG8gb2JqZWN0cyB0aGF0IGFyZSBhY3RpdmF0ZWQgaW4tcGxhY2UuPC9saT4KCjxsaT5PTEUuT0xFSVZFUkJfSU5QTEFDRUFDVElWQVRFIC0gQWN0aXZhdGVzIGFuIG9iamVjdCBpbiBwbGFjZSB3aXRob3V0IGRpc3BsYXlpbmcKdG9vbHMsIHN1Y2ggYXMgbWVudXMgYW5kIHRvb2xiYXJzLCB0aGF0IGVuZCB1c2VycyBuZWVkIHRvIGNoYW5nZSB0aGUgYmVoYXZpb3IKb3IgYXBwZWFyYW5jZSBvZiB0aGUgb2JqZWN0LiBTaW5nbGUtY2xpY2tpbmcgc3VjaCBhbiBvYmplY3QgY2F1c2VzIGl0IHRvCm5lZ290aWF0ZSB0aGUgZGlzcGxheSBvZiBpdHMgdXNlci1pbnRlcmZhY2UgdG9vbHMgd2l0aCBpdHMgY29udGFpbmVyLiBJZgp0aGUgY29udGFpbmVyIHJlZnVzZXMsIHRoZSBvYmplY3QgcmVtYWlucyBhY3RpdmUgYnV0IHdpdGhvdXQgaXRzIHRvb2xzCmRpc3BsYXllZC48L2xpPgoKPGxpPk9MRS5PTEVJVkVSQl9VSUFDVElWQVRFIC0gQWN0aXZhdGVzIGFuIG9iamVjdCBpbiBwbGFjZSwgYWxvbmcgd2l0aCBpdHMgZnVsbApzZXQgb2YgdXNlci1pbnRlcmZhY2UgdG9vbHMsIGluY2x1ZGluZyBtZW51cywgdG9vbGJhcnMsIGFuZCBpdHMgbmFtZSBpbgp0aGUgdGl0bGUgYmFyIG9mIHRoZSBjb250YWluZXIgd2luZG93LjwvbGk+Cgo8bGk+T0xFLk9MRUlWRVJCX0RJU0NBUkRVTkRPU1RBVEUgLSBVc2VkIHRvIHRlbGwgb2JqZWN0cyB0byBkaXNjYXJkIGFueSB1bmRvIHN0YXRlCnRoYXQgdGhleSBtYXkgYmUgbWFpbnRhaW5pbmcgd2l0aG91dCBkZWFjdGl2YXRpbmcgdGhlIG9iamVjdC48L2xpPgo8L3VsPgoKPGxpPgo8Yj5yZXR1cm4gdmFsdWU8L2I+IJYgT0xFLlNfT0sgaWYgdGhlIGRvVmVyYiBjb21tYW5kIHdhcyBzdWNjZXNzZnVsLjwvbGk+CjwvdWw+Cgo8Yj5GdXJ0aGVyIFJlYWRpbmc8L2I+IG9uIJNkb1ZlcmKUOiBNU0ROIExpYnJhcnk6IFdpbmRvd3MgQ0UKICAgICAgICBEb2N1bWVudGF0aW9uLSZndDtBcHBsaWNhdGlvbiBEZXZlbG9wbWVudC0mZ3Q7QVBJIFJlZmVyZW5jZS0mZ3Q7Q29yZQogICAgICAgIC0mZ3Q7SW50ZXJmYWNlcy0mZ3Q7SU9sZU9iamVjdDo6SVVua25vd24tJmd0O0lPbGVPYmplY3Q6OkRvVmVyYgoKPGgzPlNhdmluZyBjaGFuZ2VzIHRvIGFuIE9MRSBEb2N1bWVudDwvaDM+CgpUaGUgY2hhbmdlcyBtYWRlIHRvIHRoZSBPTEUgRG9jdW1lbnQgY2FuIGJlIHNhdmVkIHRvIGEgU3RvcmFnZSBmaWxlIG9yIGFuIG9yZGluYXJ5IGZpbGUuIApBcyBkZXNjcmliZWQgYWJvdmUsIGEgU3RvcmFnZSBmaWxlIGNvbnRhaW5zIGluZm9ybWF0aW9uIGluIHRoZSBoZWFkZXIgdGhhdCBpcyBzcGVjaWZpYwp0byBPTEUuIAoKPHA+QXBwbGljYXRpb25zIGxpa2UgV29yZCBzYXZlIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gaW4gdGhlIFN0b3JhZ2UgZmlsZSBzdWNoIGFzCnBhcmFncmFwaCBmb3JtYXRzLCBBdXRob3IncyBuYW1lIGFuZCBDb21wYW55LiAgSWYgeW91IHNhdmUgYSBXb3JkIERvY3VtZW50IHRvIGFuCm9yZGluYXJ5IGZpbGUsIG9ubHkgdGhlIHRleHQgd2lsbCBiZSBzYXZlZC4KCjxwPlNvbWUgYXBwbGljYXRpb25zIGVkaXQgcmVzb3VyY2VzIHdoaWNoIGFyZSBub3QgT0xFIHNwZWNpZmljIGFuZCB0aGVyZWZvcmUgY2FuIG5vdCBzYXZlCnRoZWlyIGNvbnRlbnRzIGludG8gYSBTdG9yYWdlIGZpbGUgYmVjYXVzZSB0aGVuIG90aGVyIGFwcGxpY2F0aW9ucyB3aWxsIG5vdCB1bmRlcnN0YW5kIHRoZSBjb250ZW50cy4gIApGb3IgZXhhbXBsZSwgYSBiaXRtYXAgY2FuIGJlIGVkaXRlZCB3aXRoIE1pY3Jvc29mdCdzIFBhaW50IGFwcGxpY2F0aW9uIHdoaWNoIGNhbiBiZSBlbWJlZGRlZCBhcyAKYW4gT0xFIERvY3VtZW50LiAgQSBiaXRtYXAsIGhvd2V2ZXIsIGhhcyBhIGZvcm1hdCB0aGF0IGRvZXMgbm90IGluY2x1ZGUgYW4gT0xFIGhlYWRlci4gIEluIHRoaXMKY2FzZSwgdGhlIGNvbnRlbnRzIG11c3QgYmUgc2F2ZWQgdG8gYW4gb3JkaW5hcnkgZmlsZS4KCjxwPkJlZm9yZSBzYXZpbmcgdGhlIGZpbGUsIGNoZWNrIHRoYXQgYSBzYXZlIGlzIG5lY2Vzc2FyeSB1c2luZyB0aGUgbWV0aG9kIDx0dD5pc0RpcnR5KCk8L3R0PiBvbiB0aGUKPGk+T2xlQ2xpZW50U2l0ZTwvaT4uCklmIGEgc2F2ZSBpcyByZXF1aXJlZCwgaW52b2tlIHRoZSBtZXRob2QgPHR0PnNhdmUoRmlsZSBmaWxlLCBib29sZWFuIGluY2x1ZGVPbGVJbmZvKTwvdHQ+IG9uIHRoZQo8aT5PbGVDbGllbnRTaXRlPC9pPi4gIApUaGUgYm9vbGVhbiA8dHQ+aW5jbHVkZU9sZUluZm88L3R0PiBzaG91bGQgYmUgc2V0IHRvIDxiPiB0cnVlPC9iPiB0byBzYXZlIHRvIGEgU3RvcmFnZSBmaWxlIGFuZAo8Yj4gZmFsc2U8L2I+IHRvIHNhdmUgdG8gYW4gb3JkaW5hcnkgZmlsZS4KPHByZT4KCUZpbGUgZmlsZSA9IG5ldyBGaWxlKCZxdW90O0M6XFxPbGVEb2N1bWVudGF0aW9uLmRvYyZxdW90Oyk7CglPbGVDbGllbnRTaXRlIGNsaWVudFNpdGUgPSBuZXcgT2xlQ2xpZW50U2l0ZShmcmFtZSwgU1dULk5PTkUsIGZpbGUpOwoKCS8vIC4uLiBlZGl0IHRoZSBkb2N1bWVudCAuLi4KCglpZiAoY2xpZW50U2l0ZS5pc0RpcnR5KCkpIHsKCQlGaWxlIHRlbXBGaWxlID0gbmV3IEZpbGUoZmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSArICZxdW90Oy50bXAmcXVvdDspOwoJCWZpbGUucmVuYW1lVG8odGVtcEZpbGUpOwoJCWlmIChjbGllbnRTaXRlLnNhdmUoZmlsZSwgdHJ1ZSkpewoJCQkvLyBzYXZlIHdhcyBzdWNjZXNzZnVsIHNvIGRpc2NhcmQgdGhlIGJhY2t1cAoJCQl0ZW1wRmlsZS5kZWxldGUoKTsKCQl9IGVsc2UgewoJCQkvLyBzYXZlIGZhaWxlZCBzbyByZXN0b3JlIHRoZSBiYWNrdXAKCQkJdGVtcEZpbGUucmVuYW1lVG8oZmlsZSk7CgkJfQoJfQoKPC9wcmU+Cgo8aDM+RGVhY3RpdmF0aW5nIHRoZSBPTEUgT2JqZWN0PC9oMz4KCklmIHNldmVyYWwgT0xFIERvY3VtZW50cyBvciBBY3RpdmVYIENvbnRyb2xzIGFyZSBlbWJlZGRlZCBpbiBhbiBhcHBsaWNhdGlvbiwgCml0IG1heSBiZSBwcmVmZXJhYmxlIHRvIGhhdmUgb25seSBvbmUgT0xFIE9iamVjdCAiYWN0aXZlIiBhdCBhIHRpbWUuClRoZSBPTEUgT2JqZWN0IHRoYXQgaXMgbm90IGN1cnJlbnRseSBiZWluZyB1c2VkIGNhbiBiZSBkZWFjdGl2YXRlZC4KV2hlbiB0aGUgT0xFIE9iamVjdCBpcyBkZWFjdGl2YXRlZCwgaXQgaXMgcGxhY2VkIGluIGEgk1J1bm5pbmeUIHN0YXRlIAqWIGl0cyBjb250ZW50cyBhcmUgdmlzaWJsZSBidXQgdGhlIHRvb2xiYXIgYW5kIG1lbnUgYmFyIGhhdmUgYmVlbiByZW1vdmVkIGFuZCB0aGUKY29udGVudCBkb2VzIG5vdCByZXNwb25kIHRvIG1vdXNlIG9yIGtleWJvYXJkIGFjdGlvbnMuCkluIHRoaXMgc3RhdGUsIHRoZSBvYmplY3QgaXMgc3RpbGwgYWxpdmUuICBJZiBtb2RpZmljYXRpb25zIGhhdmUgYmVlbiBtYWRlIHRvIHRoZSBvYmplY3QsIHdoZW4KdGhlIG9iamVjdCBpcyByZXR1cm5lZCB0byB0aGUgYWN0aXZlIHN0YXRlLCB0aG9zZSBjaGFuZ2VzIHdpbGwgc3RpbGwgYmUgcHJlc2VudC4KCjxwPk5PVEU6IEluIHRoZSBjYXNlIG9mIE9MRSBEb2N1bWVudHMsIHRoZSBvcmRlciBvZiBhY3RpdmF0aW5nIGFuZCBkZWFjdGl2YXRpbmcgaXMgdmVyeSBpbXBvcnRhbnQgliBmaXJzdCAKZGVhY3RpdmF0ZSB0aGUgb2xkIGRvY3VtZW50IGFuZCB0aGVuIGFjdGl2YXRlIHRoZSBuZXcgZG9jdW1lbnQgb3RoZXJ3aXNlIHRoZSBtZW51IGJhcgp3aWxsIG5vdCBhcHBlYXIgY29ycmVjdGx5LiAKCjxwPkRlYWN0aXZhdGluZyBhbiBPTEUgRG9jdW1lbnQgb3IgQWN0aXZlWCBDb250cm9sIGlzIGRvbmUgYnkgY2FsbGluZyA8dHQ+ZGVhY3RpdmF0ZUluUGxhY2VDbGllbnQ8L3R0PgpvbiB0aGUgPGk+IE9sZUNsaWVudFNpdGU8L2k+IG9yIDxpPk9sZUNvbnRyb2xTaXRlPC9pPjoKPHByZT4KCWN1cnJlbnRTaXRlLmRlYWN0aXZhdGVJblBsYWNlQ2xpZW50KCk7CjwvcHJlPgoKPGgzPkRpc3Bvc2luZyB0aGUgT0xFIE9iamVjdDwvaDM+CgpCZWNhdXNlIDxpPiBPbGVGcmFtZTwvaT4sIDxpPiBPbGVDbGllbnRTaXRlPC9pPiBhbmQgPGk+IE9sZUNvbnRyb2xTaXRlPC9pPiBhcmUgU1dUIFdpZGdldHMsIHdoZW4KdGhlIHBhcmVudCBpcyBkaXNwb3NlZCwgdGhlIGNoaWxkcmVuIHdpbGwgYmUgZGlzcG9zZWQgYXV0b21hdGljYWxseS4KVG8gdGVybWluYXRlIGFuIE9MRSBEb2N1bWVudCBvciBBY3RpdmVYIENvbnRyb2wgd2hpbGUgb3RoZXIgT0xFIE9iamVjdHMgCmFyZSBzdGlsbCBydW5uaW5nIGluIHRoZSBzYW1lIDxpPiBPbGVGcmFtZTwvaT4sIGRpcmVjdGx5IGRpc3Bvc2Ugb2YgdGhlIG9iamVjdDoKPHByZT4KCW15Q2xpZW50U2l0ZS5kaXNwb3NlKCk7CjwvcHJlPgpvcgo8cHJlPgoJbXlDb250cm9sU2l0ZS5kaXNwb3NlKCk7CjwvcHJlPgoKPHA+Tm90ZTogV2hlbiBhbiBPTEUgT2JqZWN0IGlzIHRlcm1pbmF0ZWQsIHNhdmluZyBpcyBub3QgcGVyZm9ybWVkIGF1dG9tYXRpY2FsbHksCm5vciB3aWxsIHRoZXJlIGJlIGFueSBjaGVja2luZyBmb3IgYSCTZGlydHmUIHN0YXRlIChubyBjaGVja2luZyBmb3IgdW5zYXZlZApjaGFuZ2VzIGJlZm9yZSBjbG9zaW5nKS4gVGhlIGFwcGxpY2F0aW9uIG11c3Qgd3JpdGUgdGhpcyBjb2RlLgoKPGgyPlVzaW5nIEN1c3RvbWl6ZWQgQmVoYXZpb3I8L2gyPgoKQWN0aXZlWCBDb250cm9scyBhbmQgT0xFIERvY3VtZW50cyBjYW4gcHJvdmlkZSBjdXN0b21pemVkIGJlaGF2aW9yLiBUbyBzZWUKd2hhdCBraW5kcyBvZiBjdXN0b21pemVkIGJlaGF2aW9yIGFyZSBhdmFpbGFibGUgcmVmZXIgdG8gdGhlIHR5cGUKbGlicmFyeSBhc3NvY2lhdGVkIHdpdGggdGhlIE9MRSBPYmplY3QuIFNXVCBwcm92aWRlcyBhY2Nlc3MgdG8gc2V2ZXJhbCBkaWZmZXJlbnQKdHlwZXMgb2YgY3VzdG9taXplZCBiZWhhdmlvciCWIHRoZSCTRXhlYyBDb21tYW5klCwgdGhlIJNJRGlzcGF0Y2ggaW50ZXJmYWNllCwKRXZlbnRzIGFuZCBQcm9wZXJ0eSBDaGFuZ2UgTm90aWZpY2F0aW9uLgoKPGgzPkV4ZWMgQ29tbWFuZDwvaDM+ClRoZSCTZXhlY5QgY29tbWFuZCBpcyBhIGdlbmVyaWMgd2F5IG9mIHNlbmRpbmcgYSBwcmVkZWZpbmVkIHNldCBvZiBjb21tYW5kcwp0byBlaXRoZXIgYW4gT0xFIERvY3VtZW50IG9yIGFuIEFjdGl2ZVggQ29udHJvbC4gVGhlIGNvbW1hbmQgc3ludGF4IGlzIGFzIGZvbGxvd3M6CjxwcmU+CglpbnQgT2xlQ2xpZW50U2l0ZS5leGVjKGludCBjbWRJRCwgaW50IG9wdGlvbnMsIFZhcmlhbnQgaW4sIFZhcmlhbnQgb3V0KQo8L3ByZT4KCndoZXJlCjx1bD4KPGxpPgo8Yj5jbWRJRDwvYj4gliBhbiBpZGVudGlmaWVyIGZvciB0aGUgY29tbWFuZCBzdWNoIGFzIE9MRS5PTEVDTURJRF9PUEVOLApPTEUuT0xFQ01ESURfTkVXLCBPTEUuT0xFQ01ESURfU0FWRTwvbGk+Cgo8bGk+PGI+b3B0aW9uczwvYj4gliB0aGUgYmVoYXZpb3Igb2YgdGhlIGNvbW1hbmQgY2FuIGJlIG1vZGlmaWVkIHRocm91Z2ggdGhlCnVzZSBvZiBvcHRpb25zIHN1Y2ggYXMgT0xFLk9MRUNNREVYRUNPUFRfRE9ERUZBVUxULCBPTEUuT0xFQ01ERVhFQ09QVF9QUk9NUFRVU0VSLApPTEUuT0xFQ01ERVhFQ09QVF9ET05UUFJPTVBUVVNFUiBvciBPTEUuT0xFQ01ERVhFQ09QVF9TSE9XSEVMUDwvbGk+CjxsaT48Yj5pbjwvYj4gliBwYXJhbWV0ZXJzIHRvIGJlIHBhc3NlZCBpbnRvIHRoZSBjb21tYW5kPC9saT4KPGxpPjxiPm91dDwvYj4gliB2YWx1ZXMgcmV0dXJuIGZyb20gdGhlIGNvbW1hbmQ8L2xpPgo8bGk+PGI+cmV0dXJuIHZhbHVlPC9iPiCWIHRoZSByZXR1cm4gdmFsdWUgd2lsbCBiZSBPTEUuU19PSyBpZiB0aGUgYWN0aW9uIHdhcyBzdWNjZXNzZnVsLjwvbGk+CjwvdWw+Cgo8cD5JbiBhbmQgb3V0IHBhcmFtZXRlcnMgYXJlIGRlZmluZWQgdXNpbmcgYSBWYXJpYW50LCB3aGljaCBpcyB0aGUgT0xFIG1lY2hhbmlzbQpmb3IgZ2VuZXJpY2FsbHkgcGFzc2luZyBhcm91bmQgYW55IHR5cGUgb2YgZGF0YS4gQSBWYXJpYW50IG1heSBjb250YWluCmFuIGludGVnZXIsIGEgYm9vbGVhbiwgYSBzdHJpbmcgb3IgbWFueSBvdGhlciBkaWZmZXJlbnQgdHlwZXMgb2Ygb2JqZWN0cy4KCjxwPlRoZSBPTEUgT2JqZWN0IG1heSBvciBtYXkgbm90IHJlY29nbml6ZSB0aGUgY29tbWFuZC4gQmVmb3JlIHNlbmRpbmcKYSBjb21tYW5kLCB5b3UgY2FuIGFzayBhbiBPTEUgT2JqZWN0IGlmIGl0IHJlY29nbml6ZXMgdGhlIGNvbW1hbmQgdXNpbmcgT2xlQ2xpZW50U2l0ZS5xdWVyeVN0YXR1cyhpbnQKY21kSUQpLiBUaGlzIHdpbGwgcmV0dXJuIHNvbWUgY29tYmluYXRpb24gb2YgdGhlIGZvbGxvd2luZyB2YWx1ZXM6Cjx1bD4KPGxpPk9MRS5PTEVDTURGX1NVUFBPUlRFRCCWIFRoZSBjb21tYW5kIGlzIHN1cHBvcnRlZCBieSB0aGlzIG9iamVjdC48L2xpPgo8bGk+T0xFLk9MRUNNREZfRU5BQkxFRCCWIFRoZSBjb21tYW5kIGlzIGF2YWlsYWJsZSBhbmQgZW5hYmxlZC48L2xpPgo8bGk+T0xFLk9MRUNNREZfTEFUQ0hFRCCWIFRoZSBjb21tYW5kIGlzIGFuIG9uLW9mZiB0b2dnbGUgYW5kIGlzIGN1cnJlbnRseSBvbi48L2xpPgo8L3VsPgoKPHA+SGVyZSBpcyBhbiBleGFtcGxlIG9mIGhvdyB0aGUgRXhlYyBjb21tYW5kIGlzIHVzZWQ6CjxwcmU+CglpbnQgcmVzdWx0ID0gY29udHJvbFNpdGUucXVlcnlTdGF0dXMoT0xFLk9MRUNNRElEX1BSSU5UKTsKCWlmICgocmVzdWx0ICZhbXA7IE9MRS5PTEVDTURGX0VOQUJMRUQpID09IE9MRS5PTEVDTURGX0VOQUJMRUQpIHsKCQljb250cm9sU2l0ZS5leGVjKE9MRS5PTEVDTURJRF9QUklOVCwgT0xFLk9MRUNNREVYRUNPUFRfUFJPTVBUVVNFUiwgbnVsbCwgbnVsbCk7Cgl9CjwvcHJlPgoKPHA+PGI+RnVydGhlciBSZWFkaW5nPC9iPiBvbiCTZXhlY5Q6IE1TRE4gTGlicmFyeTogUGxhdGZvcm0gU0RLLT5Db21wb25lbnQKU2VydmljZXMgLT5DT00gLT5PTEUgYW5kIERhdGEgVHJhbnNmZXItPlJlZmVyZW5jZSAtPkludGVyZmFjZXMtPklPbGVDb21tYW5kVGFyZ2V0Cgo8aDM+SURpc3BhdGNoIG9yIE9MRSBBdXRvbWF0aW9uPC9oMz4KCkFuIE9MRSBEb2N1bWVudCBvciBBY3RpdmVYIENvbnRyb2wgY2FuIGFsc28gcHJvdmlkZSBhIG11Y2ggcmljaGVyIHNldCBvZiBjb21tYW5kcwp0aGFuIHRoZSBnZW5lcmljIHNldCBkZWZpbmVkIGZvciB0aGUgk2V4ZWOUIGNvbW1hbmQuIFRvIGFjY2VzcyB0aGVzZSwKdXNlIHRoZSBJRGlzcGF0Y2ggaW50ZXJmYWNlLiBJRGlzcGF0Y2ggcHJvdmlkZXMgYWNjZXNzIHRvIGdldCBhbmQgc2V0IHByb3BlcnR5CnZhbHVlcyBhbmQgaW52b2tlIG1ldGhvZHMuIEZvciBleGFtcGxlLCBXb3JkIHByb3ZpZGVzIHRoZSBlbnRpcmUgV29yZCBCYXNpYwppbnRlcmZhY2UgdGhhdCBnaXZlcyB5b3UgYWNjZXNzIHRvIGFsbCBzb3J0cyBvZiBjb21tYW5kcyBhbmQgcHJvcGVydGllcwpsaWtlIGN1dC9jb3B5L3Bhc3RlLCBwcmludCwgc3BlbGwgY2hlY2ssIHNlbGVjdCB0ZXh0LCBjaGFuZ2UgcGFyYWdyYXBoCmZvcm1hdCwgZXRjLiBJbiBTV1QgdGhlIElEaXNwYXRjaCBjYXBhYmlsaXRpZXMgYXJlIGFjY2Vzc2VkIHVzaW5nIHRoZSA8aT4gT2xlQXV0b21hdGlvbjwvaT4Kb2JqZWN0LgoKPGg0PkNyZWF0aW5nIHRoZSBBdXRvbWF0aW9uIG9iamVjdDo8L2g0PgoKQW4gPGk+IE9sZUF1dG9tYXRpb248L2k+IG9iamVjdCBjYW4gYmUgY3JlYXRlZCBmcm9tIGEgY2xpZW50IG9yIGNvbnRyb2wgc2l0ZSBvcgppdCBjYW4gYmUgb2J0YWluZWQgYXMgdGhlIHJldHVybiB2YWx1ZSBmcm9tIGEgbWV0aG9kIGludm9jYXRpb24uCgo8cD5BIHNpbXBsZSBjYXNlIGlzIHRoZSBXZWIgQnJvd3Nlci4gSXQgcHJvdmlkZXMgY29tbWFuZHMgbGlrZSBuYXZpZ2F0ZSwKYmFjaywgZm9yd2FyZCwgaG9tZSB3aGljaCB5b3UgY2FuIGFjY2VzcyBsaWtlIHRoaXM6CjxwcmU+CglPbGVDb250cm9sU2l0ZSBjb250cm9sU2l0ZSA9IG5ldyBPbGVDb250cm9sU2l0ZShmcmFtZSwgU1dULk5PTkUsICZxdW90O1NoZWxsLkV4cGxvcmVyJnF1b3Q7KTsKCU9sZUF1dG9tYXRpb24gYXV0b21hdGlvbiA9IG5ldyBPbGVBdXRvbWF0aW9uKGNvbnRyb2xTaXRlICk7CjwvcHJlPgoKPGg0PkdldCBhIFByb3BlcnR5PC9oND4KCUEgUHJvcGVydHkgaXMgb2J0YWluZWQgZnJvbSBhbiBPTEUgT2JqZWN0IHVzaW5nIHRoZSA8aT4gT2xlQXV0b21hdGlvbjwvaT4gbWV0aG9kIDx0dD48Yj5nZXRQcm9wZXJ0eTwvYj48L3R0PjoKPHByZT4JCglWYXJpYW50IGdldFByb3BlcnR5KGludCBkaXNwSWRNZW1iZXIpCjwvcHJlPgoKd2hlcmUKPHVsPgo8bGk+PGI+ZGlzcElETWVtYmVyPC9iPiAtIGlkZW50aWZpZXMgdGhlIFByb3BlcnR5IGluIHdoaWNoIHlvdSBhcmUgaW50ZXJlc3RlZC4KWW91IG1heSBhbHJlYWR5IGtub3cgdGhlIHZhbHVlIG9mIHRoZSBkaXNwSURNZW1iZXIgZnJvbSBsb29raW5nIGluIHRoZQp0eXBlIGxpYnJhcnkgb3IgeW91IG1heSBqdXN0IGtub3cgdGhlIHN0cmluZyBpZGVudGlmaWVyIChhbHNvIGF2YWlsYWJsZQppbiB0aGUgdHlwZSBsaWJyYXJ5KS4gWW91IGNhbiBnZXQgdGhlIGludGVnZXIgdmFsdWUgZnJvbSB0aGUgc3RyaW5nIGlkZW50aWZpZXIKdXNpbmcgPHR0Pk9sZUF1dG9tYXRpb24uR2V0SURzT2ZOYW1lcyhTdHJpbmdbXSBuYW1lcyk8L3R0Pi4gVGhlIG1ldGhvZCBnZXRQcm9wZXJ0eQpyZXR1cm5zIGEgVmFyaWFudCCWIGFzIGRpc2N1c3NlZCBhYm92ZSwgdGhpcyBpcyB0aGUgT0xFIG1lY2hhbmlzbSBmb3IgYmVpbmcKYWJsZSB0byBnZW5lcmljYWxseSBwYXNzIGFyb3VuZCBhbnkgdHlwZSBvZiBkYXRhLiBZb3UgYXNrIHRoZSBWYXJpYW50IHRvCnByb3ZpZGUgdGhlIHZhbHVlIGl0IGNvbnRhaW5zIGluIHRoZSBmb3JtYXQgdGhhdCB5b3UgcmVxdWlyZS48L2xpPgoKPGxpPjxiPnJldHVybiB2YWx1ZTwvYj4gLSB0aGlzIGlzIGEgVmFyaWFudCBjb250YWluaW5nIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCkEgVmFyaWFudCBpcyBhIGdlbmVyaWMgd2F5IG9mIHBhc3NpbmcgYXJvdW5kIGRhdGEuIFlvdSBjYW4gYXNrIHRoZSBWYXJpYW50CmZvciB0aGUgZGF0YSBpbiB0aGUgZm9ybWF0IHRoYXQgeW91IHByZWZlci48L2xpPgo8L3VsPgoKRm9yIGV4YW1wbGU6CjxwcmU+CglPbGVDb250cm9sU2l0ZSBjb250cm9sU2l0ZSA9IG5ldyBPbGVDb250cm9sU2l0ZShmcmFtZSwgU1dULk5PTkUsICZxdW90O1NoZWxsLkV4cGxvcmVyJnF1b3Q7KTsKCU9sZUF1dG9tYXRpb24gYXV0b21hdGlvbiA9IG5ldyBPbGVBdXRvbWF0aW9uKGNvbnRyb2xTaXRlKTsKCWludFtdIHJnZGlzcGlkID0gYXV0b21hdGlvbi5nZXRJRHNPZk5hbWVzKG5ldyBTdHJpbmdbXXsmcXVvdDtMb2NhdGlvbk5hbWUmcXVvdDt9KTsKCWludCBkaXNwSWRNZW1iZXIgPSByZ2Rpc3BpZFswXTsKCVZhcmlhbnQgcmVzdWx0ID0gYXV0b21hdGlvbi5nZXRQcm9wZXJ0eShkaXNwSWRNZW1iZXIpOwoJU3lzdGVtLm91dC5wcmludGxuKCZxdW90O1RoZSBXZWIgQnJvd3NlciBpcyBjdXJyZW50bHkgdmlld2luZyB0aGUgVVJMICZxdW90OytyZXN1bHQuZ2V0U3RyaW5nKCkpOwo8L3ByZT4KCk1hdGNoaW5nIHR5cGUgbGlicmFyeSByZWNvcmQ6CjxwcmU+aW50ZXJmYWNlIElXZWJCcm93c2VyIDogSURpc3BhdGNoIHsKCYUKCVtpZCgweDAwMDAwMGQyKSwgcHJvcGdldCwgaGVscHN0cmluZygmcXVvdDtHZXRzIHRoZSBzaG9ydCAoVUktZnJpZW5kbHkpIG5hbWUgb2YgdGhlIFVSTC9maWxlIGN1cnJlbnRseSB2aWV3ZWQuJnF1b3Q7KV0KCUhSRVNVTFQgTG9jYXRpb25OYW1lKFtvdXQsIHJldHZhbF0gQlNUUiogTG9jYXRpb25OYW1lKTsKCYUKfQo8L3ByZT4KCjxoND5TZXQgYSBQcm9wZXJ0eTwvaDQ+CgpUaGlzIGlzIHZlcnkgc2ltaWxhciB0byCTR2V0IGEgUHJvcGVydHmULiBJbiB0aGlzIGNhc2UgdGhlIG1ldGhvZCBpczoKPHByZT4KCWJvb2xlYW4gT2xlQXV0b21hdGlvbi5zZXRQcm9wZXJ0eShpbnQgZGlzcElkTWVtYmVyLCBWYXJpYW50IHJndmFyZykuPC9wcmU+CndoZXJlCjx1bD4KPGxpPjxiPmRpc3BJZE1lbWJlcjwvYj4gliBhcyBhYm92ZTwvbGk+CjxsaT48Yj5yZ3Zhcmc8L2I+IC0gY29udGFpbnMgdGhlIHZhbHVlIHRvIHdoaWNoIHlvdSB3YW50IHRoZSBwcm9wZXJ0eSBzZXQuPC9saT4KPGxpPjxiPnJldHVybiB2YWx1ZTwvYj4gliB0cnVlIGlmIHByb3BlcnR5IHdhcyBzZXQuPC9saT4KPC91bD4KCkZvciBleGFtcGxlOgo8cHJlPgoJLy8gQWxsb3cgbXVsdGlwbGUgc2VsZWN0aW9uIGluIGFuIGVtYmVkZGVkIENhbGVuZGFyIENvbnRyb2wKCU9sZUNvbnRyb2xTaXRlIGNvbnRyb2xTaXRlID0gbmV3IE9sZUNvbnRyb2xTaXRlKGZyYW1lLCBTV1QuTk9ORSwgJnF1b3Q7TVNDb21DdGwyLk1vbnRoVmlldyZxdW90Oyk7CglPbGVBdXRvbWF0aW9uIGF1dG9tYXRpb24gPSBuZXcgT2xlQXV0b21hdGlvbihjb250cm9sU2l0ZSk7CglpbnRbXSByZ2Rpc3BpZCA9IGF1dG9tYXRpb24uZ2V0SURzT2ZOYW1lcyhuZXcgU3RyaW5nW117JnF1b3Q7TXVsdGlTZWxlY3QmcXVvdDt9KTsKCWludCBkaXNwSWRNZW1iZXIgPSByZ2Rpc3BpZFswXTsKCVZhcmlhbnQgbXVsdGlTZWxlY3QgPSBuZXcgVmFyaWFudCgoc2hvcnQpMSk7IC8vIHNldCB0byB0cnVlICgwID0gZmFsc2UpCglhdXRvbWF0aW9uLnNldFByb3BlcnR5KGRpc3BJZE1lbWJlciwgbXVsdGlTZWxlY3QpOwoKPC9wcmU+CgpNYXRjaGluZyB0eXBlIGxpYnJhcnkgcmVjb3JkOgo8cHJlPgppbnRlcmZhY2UgSU1vbnRoVmlldyA6IElEaXNwYXRjaCB7CgmFCglbaWQoMHgwMDAwMDAwMTMpLCBwcm9wcHV0LCBoZWxwc3RyaW5nKCZxdW90O0FsbG93IG11bHRpcGxlIHNlbGVjdGlvbi4mcXVvdDspLCBoZWxwY29udGV4dCgweDAwMDMwZGE4KV0KCUhSRVNVTFQgTXVsdGlTZWxlY3QoW2luXSBCU1RSIHBiTXVsdGlTZWxlY3QpOwoJhQp9CjwvcHJlPgoKPGg0Pkludm9rZSBhIENvbW1hbmQ8L2g0PgoKSW52b2tpbmcgYSBjb21tYW5kIGlzIGEgYml0IG1vcmUgY29tcGxpY2F0ZWQgYmVjYXVzZSB5b3UgY2FuIHBhc3MgaW4gbXVsdGlwbGUKcGFyYW1ldGVycyBhbmQgYmVjYXVzZSBzb21lIG9mIHRoZXNlIHBhcmFtZXRlcnMgbWF5IGJlIG9wdGlvbmFsLCB5b3UgbXVzdApwYXNzIGFuIGlkZW50aWZpZXIgZm9yIHRoZSBwYXJhbWV0ZXIgYXMgd2VsbCBhcyB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlci4KVGhlcmUgYXJlIHRocmVlIHZhcmlhbnRzIG9uIHRoZSBPbGVBdXRvbWF0aW9uLmludm9rZSBtZXRob2QgdG8gYWNjb21tb2RhdGUKdGhpczoKPHVsPgo8bGk+PHR0PlZhcmlhbnQgaW52b2tlKGludCBkaXNwSWRNZW1iZXIpPC90dD4gliBDb21tYW5kIHRha2VzIG5vIHBhcmFtZXRlcnM8L2xpPgoKPGxpPjx0dD5WYXJpYW50IGludm9rZShpbnQgZGlzcElkTWVtYmVyLCBWYXJpYW50W10gcmd2YXJnKTwvdHQ+IJYgQWxsIHBhcmFtZXRlcnMKYXJlIG1hbmRhdG9yeSBhbmQgdGhlcmVmb3JlIG5vbmUgYXJlIG5hbWVkPC9saT4KCjxsaT48dHQ+VmFyaWFudCBpbnZva2UoaW50IGRpc3BJZE1lbWJlciwgVmFyaWFudFtdIHJndmFyZywgaW50W10KICByZ2Rpc3BpZE5hbWVkQXJncyk8L3R0PiCWIFNvbWUgcGFyYW1ldGVycyBhcmUgb3B0aW9uYWwgYW5kIHRoZXJlZm9yZSBhbGwgdGhlIHBhcmFtZXRlcnMgYXJlIG5hbWVkPC9saT4KPC91bD4KCldoZXJlCjx1bD4KPGxpPjxiPmRpc3BJZE1lbWJlcjwvYj4gliB0aGUgaWRlbnRpZmllciBvZiB0aGUgY29tbWFuZDwvbGk+Cgo8bGk+PGI+cmd2YXJnPC9iPiCWIGFuIGFycmF5IG9mIFZhcmlhbnRzIGhvbGRpbmcgdGhlIHZhbHVlcyBvZiB0aGUgcGFyYW1ldGVycwp5b3UgYXJlIHBhc3NpbmcgaW4uPC9saT4KCjxsaT48Yj5yZ2Rpc3BpZE5hbWVkQXJnczwvYj4gliBhbiBhcnJheSBvZiB0aGUgaWRlbnRpZmllcnMgZm9yIHRoZSBhcmd1bWVudHMuPC9saT4KCjxsaT48Yj5yZXR1cm4gdmFsdWU8L2I+IJYgYSBWYXJpYW50IGNvbnRhaW5pbmcgdGhlIHJlc3VsdCB0aGF0IHdhcyBwYXNzZWQgYmFjawpieSB0aGUgY29tbWFuZC4gRGVwZW5kaW5nIG9uIHRoZSBjb21tYW5kLCB0aGlzIG1heSBiZSBudWxsLjwvbGk+CjwvdWw+CgpFeGFtcGxlIDE6CjxwPlRoZSCTR29Gb3J3YXJklCBjb21tYW5kIG9uIHRoZSBXZWIgQnJvd3NlciB0YWtlcyBubyBwYXJhbWV0ZXJzOgo8cHJlPgoJT2xlQ29udHJvbFNpdGUgd2ViU2l0ZSA9IG5ldyBPbGVDb250cm9sU2l0ZShmcmFtZSwgU1dULk5PTkUsICZxdW90O1NoZWxsLkV4cGxvcmVyJnF1b3Q7KTsKCU9sZUF1dG9tYXRpb24gYXV0b21hdGlvbiA9IG5ldyBPbGVBdXRvbWF0aW9uKHdlYlNpdGUpOwoJaW50W10gcmdkaXNwaWQgPSBhdXRvbWF0aW9uLmdldElEc09mTmFtZXMobmV3IFN0cmluZ1tdeyZxdW90O0dvRm9yd2FyZCZxdW90O30pOwoJaW50IGRpc3BJZE1lbWJlciA9IHJnZGlzcGlkWzBdOwoJVmFyaWFudCBwVmFyUmVzdWx0ID0gYXV0b21hdGlvbi5pbnZva2UoZGlzcElkTWVtYmVyKTsKPC9wcmU+CgpOb3RlOiBDYWxsIDxiPiBnZXRJRHNPZk5hbWVzPC9iPiB0byBnZXQgdGhlIElEIG9mIHRoZSBjb21tYW5kCgo8cD5NYXRjaGluZyB0eXBlIGxpYnJhcnkgcmVjb3JkOgo8cHJlPgppbnRlcmZhY2UgSVdlYkJyb3dzZXIgOiBJRGlzcGF0Y2ggewoJhQoJW2lkKDB4MDAwMDAwNjUpLCBoZWxwc3RyaW5nKCZxdW90O05hdmlnYXRlcyB0byB0aGUgbmV4dCBpdGVtIGluIHRoZSBoaXN0b3J5IGxpc3QuJnF1b3Q7KV0KCUhSRVNVTFQgR29Gb3J3YXJkKCk7CgmFCn0KPC9wcmU+CgpFeGFtcGxlIDI6CjxwPlRoZSCTTmF2aWdhdGWUIGNvbW1hbmQgb2YgdGhlIFdlYiBCcm93c2VyIHRha2VzIHNldmVyYWwgYXJndW1lbnRzIGJ1dAp0aGVyZSBpcyBvbmx5IG9uZSBtYW5kYXRvcnkgcGFyYW1ldGVyIGFuZCB0aGF0IGlzIHRoZSCTVVJMlC4gSW4gdGhpcyBleGFtcGxlCndlIGFyZSBub3QgZ29pbmcgdG8gc2VuZCBhbnkgb2YgdGhlIG9wdGlvbmFsIGFyZ3VtZW50czoKPHByZT4KCU9sZUNvbnRyb2xTaXRlIGNvbnRyb2xTaXRlID0gbmV3IE9sZUNvbnRyb2xTaXRlKGZyYW1lLCBTV1QuTk9ORSwgJnF1b3Q7U2hlbGwuRXhwbG9yZXImcXVvdDspOwoJT2xlQXV0b21hdGlvbiBhdXRvbWF0aW9uID0gbmV3IE9sZUF1dG9tYXRpb24oY29udHJvbFNpdGUpOwoJaW50W10gcmdkaXNwaWQgPSBhdXRvbWF0aW9uLmdldElEc09mTmFtZXMobmV3IFN0cmluZ1tdeyZxdW90O05hdmlnYXRlJnF1b3Q7fSk7CglpbnQgZGlzcElkTWVtYmVyID0gcmdkaXNwaWRbMF07CglWYXJpYW50W10gcmd2YXJnID0gbmV3IFZhcmlhbnRbMV07IC8vIHRoaXMgaXMgdGhlIFVSTCBwYXJhbWV0ZXIKCXJndmFyZ1swXSA9IG5ldyBWYXJpYW50KCZxdW90O3d3dy5pYm0uY29tJnF1b3Q7KTsKCVZhcmlhbnQgcFZhclJlc3VsdCA9IGF1dG9tYXRpb24uaW52b2tlKGRpc3BJZE1lbWJlciwgcmd2YXJnKTsKPC9wcmU+CgpNYXRjaGluZyB0eXBlIGxpYnJhcnkgcmVjb3JkOgo8cHJlPgppbnRlcmZhY2UgSVdlYkJyb3dzZXIgOiBJRGlzcGF0Y2ggewoJhQoJW2lkKDB4MDAwMDAwNjgpLCBoZWxwc3RyaW5nKCZxdW90O05hdmlnYXRlcyB0byBhIFVSTCBvciBmaWxlLiZxdW90OyldCglIUkVTVUxUIE5hdmlnYXRlKAoJCVtpbl0gQlNUUiBVUkwsJm5ic3A7CgkJW2luLCBvcHRpb25hbF0gVkFSSUFOVCogRmxhZ3MsCgkJW2luLCBvcHRpb25hbF0gVkFSSUFOVCogVGFyZ2V0RnJhbWVOYW1lLCZuYnNwOwoJCVtpbiwgb3B0aW9uYWxdIFZBUklBTlQqIFBvc3REYXRhLCZuYnNwOwoJCVtpbiwgb3B0aW9uYWxdIFZBUklBTlQqIEhlYWRlcnMpOwoJhQp9CjwvcHJlPgoKRXhhbXBsZSAzOgo8cD5UaGUgk0Zvcm1hdEZvbnSUIGNvbW1hbmQgaW4gV29yZCBCYXNpYyB0YWtlcyBzZXZlcmFsIG9wdGlvbmFsIHBhcmFtZXRlcnMKYW5kIHdlIGFyZSBpbnRlcmVzdGVkIGluIGp1c3QgYSBmZXcgb2YgdGhlbToKPHByZT4KCS8vIFRoaXMgaXMgYSBoZWxwZXIgbWV0aG9kIGZvciBnZXR0aW5nIGFjY2VzcyB0byBXb3JkJ3MgV29yZEJhc2ljIElEaXNwYXRjaCBpbnRlcmZhY2UKCS8vIGJlY2F1c2UgaXQgaXMgcmF0aGVyIGNvbXBsaWNhdGVkCglwcml2YXRlIE9sZUF1dG9tYXRpb24gZ2V0V29yZEJhc2ljKE9sZUNsaWVudFNpdGUgY2xpZW50U2l0ZSkgewoJCS8vIEdldCBnZW5lcmljIElEaXNwYXRjaCBpbnRlcmZhY2UKCQlPbGVBdXRvbWF0aW9uIGRpc3BJbnRlcmZhY2UgPSBuZXcgT2xlQXV0b21hdGlvbihjbGllbnRTaXRlKTsKCQoJCS8vIEdldCBBcHBsaWNhdGlvbgoJCWludFtdIGFwcElkID0gZGlzcEludGVyZmFjZS5nZXRJRHNPZk5hbWVzKG5ldyBTdHJpbmdbXXsmcXVvdDtBcHBsaWNhdGlvbiZxdW90O30pOyAKCQlpZiAoYXBwSWQgPT0gbnVsbCkgT0xFLmVycm9yKE9MRS5FUlJPUl9BUFBMSUNBVElPTl9OT1RfRk9VTkQpOwoJCVZhcmlhbnQgcFZhclJlc3VsdCA9IGRpc3BJbnRlcmZhY2UuZ2V0UHJvcGVydHkoYXBwSWRbMF0pOwoJCWlmIChwVmFyUmVzdWx0ID09IG51bGwpIE9MRS5lcnJvcihPTEUuRVJST1JfQVBQTElDQVRJT05fTk9UX0ZPVU5EKTsKCQlPbGVBdXRvbWF0aW9uIGFwcGxpY2F0aW9uID0gcFZhclJlc3VsdC5nZXRBdXRvbWF0aW9uKCk7CgoJCS8vIEdldCBXb3JkIEJhc2ljCgkJaW50W10gd2JJZCA9IGFwcGxpY2F0aW9uLmdldElEc09mTmFtZXMobmV3IFN0cmluZ1tdeyZxdW90O1dvcmRCYXNpYyZxdW90O30pOwoJCWlmICh3YklkID09IG51bGwpIE9MRS5lcnJvcihPTEUuRVJST1JfQVBQTElDQVRJT05fTk9UX0ZPVU5EKTsKCQlWYXJpYW50IHBWYXJSZXN1bHQyID0gYXBwbGljYXRpb24uZ2V0UHJvcGVydHkod2JJZFswXSk7CgkJaWYgKHBWYXJSZXN1bHQyID09IG51bGwpIE9MRS5lcnJvcihPTEUuRVJST1JfQVBQTElDQVRJT05fTk9UX0ZPVU5EKTsKCQlyZXR1cm4gcFZhclJlc3VsdDIuZ2V0QXV0b21hdGlvbigpOwoJfQoKCU9sZUNsaWVudFNpdGUgY2xpZW50U2l0ZSA9IG5ldyBPbGVDbGllbnRTaXRlKGZyYW1lLCBTV1QuTk9ORSwgJnF1b3Q7V29yZC5Eb2N1bWVudCZxdW90Oyk7CglPbGVBdXRvbWF0aW9uIGF1dG9tYXRpb24gPSBnZXRXb3JkQmFzaWMoY2xpZW50U2l0ZSk7CgkvLyBzZXQgdGhlIGZvbnQgdG8gMTIgcG9pbnQsIEl0YWxpYywgQm9sZCAtIGlnbm9yZSBDb2xvciBhbmQgRm9udCBuYW1lCglpbnRbXSByZ2Rpc3BpZCA9IGF1dG9tYXRpb24uZ2V0SURzT2ZOYW1lcyhuZXcgU3RyaW5nW117JnF1b3Q7Rm9ybWF0Rm9udCZxdW90OywgJnF1b3Q7UG9pbnRzJnF1b3Q7LCAmcXVvdDtDb2xvciZxdW90OywgJnF1b3Q7Rm9udCZxdW90OywgJnF1b3Q7Qm9sZCZxdW90OywgJnF1b3Q7SXRhbGljJnF1b3Q7fSk7CglpbnQgZGlzcElkTWVtYmVyID0gcmdkaXNwaWRbMF07CglWYXJpYW50W10gcmd2YXJnID0gbmV3IFZhcmlhbnRbM107CglpbnRbXSByZ2Rpc3BpZE5hbWVkQXJncyA9IG5ldyBpbnRbM107CglyZ3ZhcmdbMF0gPSBuZXcgVmFyaWFudCgxMik7IC8vIHRoaXMgaXMgdGhlIFBvaW50cyBwYXJhbWV0ZXIKCXJnZGlzcGlkTmFtZWRBcmdzWzBdID0gcmdkaXNwaWRbMV07CglyZ3ZhcmdbMV0gPSBuZXcgVmFyaWFudCgxKTsgLy8gdGhpcyBpcyB0aGUgQm9sZCBwYXJhbWV0ZXIKCXJnZGlzcGlkTmFtZWRBcmdzWzFdID0gcmdkaXNwaWRbNF07CglyZ3ZhcmdbMl0gPSBuZXcgVmFyaWFudCgxKTsgLy8gdGhpcyBpcyB0aGUgSXRhbGljCglyZ2Rpc3BpZE5hbWVkQXJnc1syXSA9IHJnZGlzcGlkWzVdOwoJYXV0b21hdGlvbi5pbnZva2VOb1JlcGx5KGRpc3BJZE1lbWJlciwgcmd2YXJnLCByZ2Rpc3BpZE5hbWVkQXJncyk7CjwvcHJlPgoKICAgICAgICA8cD5Ob3RlOiBIZXJlIHdlIGhhdmUgdXNlZCA8Yj5pbnZva2VOb1JlcGx5PC9iPiBpbnN0ZWFkIG9mIDxiPmludm9rZTwvYj4uIFdvcmQgd2FzIHRoZQpmaXJzdCBPTEUgRG9jdW1lbnQgZXZlciB3cml0dGVuIGFuZCBhcyBzdWNoIGl0IGlzIHdyaXR0ZW4gc2xpZ2h0bHkgZGlmZmVyZW50bHkKdGhhbiBvdGhlciBPTEUgRG9jdW1lbnRzLiBJZiBhIFdvcmQgY29tbWFuZCBkb2VzIG5vdCByZXR1cm4gYSB2YWx1ZSwgeW91CnNob3VsZCB1c2UgdGhlIJNJbnZva2VOb1JlcGx5lCB2YXJpYXRpb25zIG9mIGludm9rZS4gRm9yIG1vc3Qgb3RoZXIgT0xFCk9iamVjdHMsIHlvdSBjYW4gYWx3YXlzIHVzZSCTaW52b2tllCBldmVuIGlmIHRoZXJlIGlzIG5vIHZhbHVlIHJldHVybmVkLgoKPHA+PGI+RnVydGhlciBSZWFkaW5nPC9iPjogTVNETiBMaWJyYXJ5OiBCb29rcy0mZ3Q7SW5zaWRlIE9MRS0mZ3Q7Q2hhcHRlciAxNC0+VGhlIE1lY2hhbmljcwpvZiBPTEUgQXV0b21hdGlvbi0+VGhlIElEaXNwYXRjaCBJbnRlcmZhY2UKCjxoMz5FdmVudHMgYW5kIFByb3BlcnR5IGNoYW5nZXMgaW4gQ29udHJvbHM8L2gzPgoKPGI+YWRkRXZlbnRMaXN0ZW5lcjwvYj4gliBhbGxvd3MgdGhlIHVzZXIgdG8gbGlzdGVuIGZvciBFdmVudHMgb24gdGhlIENvbnRyb2wuCjxwPkV4YW1wbGU6CjxwcmU+CgkvLyBSZXNwb25kIHRvIFByb2dyZXNzQ2hhbmdlIGV2ZW50cyBpbiB0aGUgV2ViIEJyb3dzZXIgYnkgdXBkYXRpbmcgdGhlIGFwcGxpY2F0aW9ucyBQcm9ncmVzcyBiYXIKCU9sZUNvbnRyb2xTaXRlIGNvbnRyb2xTaXRlID0gbmV3IE9sZUNvbnRyb2xTaXRlKGZyYW1lLCBTV1QuTk9ORSwgJnF1b3Q7U2hlbGwuRXhwbG9yZXImcXVvdDspOwoJT2xlQXV0b21hdGlvbiBhdXRvbWF0aW9uID0gbmV3IE9sZUF1dG9tYXRpb24oY29udHJvbFNpdGUpOwoJaW50IFByb2dyZXNzQ2hhbmdlID0gMTA4OyAvLzB4NkMgLSBvYnRhaW5lZCBmcm9tIHRoZSB0eXBlIGxpYnJhcnkKCVByb2dyZXNzQmFyIHByb2dyZXNzQmFyID0gbmV3IFByb2dyZXNzQmFyKHNoZWxsLCBTV1QuQk9SREVSKTsKCWNvbnRyb2xTaXRlLmFkZEV2ZW50TGlzdGVuZXIoUHJvZ3Jlc3NDaGFuZ2UsIG5ldyBPbGVMaXN0ZW5lcigpIHsKCQlwdWJsaWMgdm9pZCBoYW5kbGVFdmVudChPbGVFdmVudCBldmVudCkgewoJCQlpZiAoZXZlbnQuZGV0YWlsICE9IFByb2dyZXNzQ2hhbmdlKSByZXR1cm47CgkJCVZhcmlhbnQgcHJvZ3Jlc3MgPSBldmVudC5hcmd1bWVudHNbMF07CgkJCVZhcmlhbnQgbWF4UHJvZ3Jlc3MgPSBldmVudC5hcmd1bWVudHNbMV07CgkJCWlmIChwcm9ncmVzcyA9PSBudWxsIHx8IG1heFByb2dyZXNzID09IG51bGwpIHJldHVybjsKCQkJCgkJCXByb2dyZXNzQmFyLnNldE1heGltdW0obWF4UHJvZ3Jlc3MuZ2V0SW50KCkpOwoJCQlwcm9ncmVzc0Jhci5zZXRTZWxlY3Rpb24ocHJvZ3Jlc3MuZ2V0SW50KCkpOwoJCX0KCX0pOwo8L3ByZT4KCk5vdGU6IFRoZSBhcHBsaWNhdGlvbiBtdXN0IGtub3cgdGhlIGlkZW50aWZpZXIgZm9yIHRoZSBldmVudCAoUHJvZ3Jlc3NDaGFuZ2UpCmFuZCB3aGF0IGtpbmQgb2YgZGF0YSBpdCBpcyBiZWluZyBnaXZlbiBpbiB0aGUgPHR0PmV2ZW50LmFyZ3VtZW50PC90dD4gKEluIG91ciBleGFtcGxlIAo8dHQ+ZXZlbnQuYXJndW1lbnRzWzBdPC90dD4gaXMgdGhlIGN1cnJlbnQgcHJvZ3Jlc3MgdmFsdWUgYW5kCjx0dD5ldmVudC5hcmd1bWVudHNbMV08L3R0PiBpcyB0aGUgbWF4aW11bSBwcm9ncmVzcyB2YWx1ZSmWIFlvdSBjYW4gZmluZCB0aGlzIG91dCBmcm9tIHRoZQogICAgICAgIHR5cGUgbGlicmFyeToKCjxwcmU+CmRpc3BpbnRlcmZhY2UgRFdlYkJyb3dzZXJFdmVudHMgewoJhQoKCVtpZCgweDAwMDAwMDZjKSwgaGVscHN0cmluZygmcXVvdDtGaXJlZCB3aGVuIGRvd25sb2FkIHByb2dyZXNzIGlzIHVwZGF0ZWQuJnF1b3Q7KV0KCQl2b2lkIFByb2dyZXNzQ2hhbmdlKAoJCQlbaW5dIGxvbmcgUHJvZ3Jlc3MsJm5ic3A7CgkJCVtpbl0gbG9uZyBQcm9ncmVzc01heCk7CgmFCn0KPC9wcmU+Cgo8Yj5hZGRQcm9wZXJ0eUxpc3RlbmVyPC9iPiCWIGFsbG93cyB0aGUgdXNlciB0byBiZSBub3RpZmllZCBiZWZvcmUgcHJvcGVydHkKY2hhbmdlcyBvY2N1ciCWIHdpdGggdGhlIG9wdGlvbiB0byB2ZXRvIHRoZSBjaGFuZ2UgliBhbmQgYWZ0ZXIgcHJvcGVydHkKY2hhbmdlIGhhcyBvY2N1cnJlZC4KPHA+RXhhbXBsZToKPHByZT4KCQoJT2xlQ29udHJvbFNpdGUgY29udHJvbFNpdGUgPSBuZXcgT2xlQ29udHJvbFNpdGUoZnJhbWUsIFNXVC5OT05FLCAmcXVvdDtTaGVsbC5FeHBsb3JlciZxdW90Oyk7CglPbGVBdXRvbWF0aW9uIGF1dG9tYXRpb24gPSBuZXcgT2xlQXV0b21hdGlvbihjb250cm9sU2l0ZSk7CglpbnRbXSByZ2Rpc3BpZCA9IGF1dG9tYXRpb24uZ2V0SURzT2ZOYW1lcyhuZXcgU3RyaW5nW117JnF1b3Q7UmVhZHlTdGF0ZSZxdW90O30pOwoJaW50IFJFQURZU1RBVEUgPSByZ2Rpc3BpZFswXTsKCQoJLy8gTGlzdGVuIGZvciBjaGFuZ2VzIHRvIHRoZSByZWFkeSBzdGF0ZSBhbmQgcHJpbnQgb3V0IHRoZSBjdXJyZW50IHN0YXRlCgljb250cm9sU2l0ZS5hZGRQcm9wZXJ0eUxpc3RlbmVyKFJFQURZU1RBVEUsIG5ldyBPbGVMaXN0ZW5lcigpIHsKCQlwdWJsaWMgdm9pZCBoYW5kbGVFdmVudChPbGVFdmVudCBldmVudCkgewoJCQlpZiAoZXZlbnQuZGV0YWlsID09IE9MRS5QUk9QRVJUWV9DSEFOR0lORykgewoJCQkJLy8gUHJpbnQgb3V0IHRoZSBvbGQgc3RhdGUKCQkJCVZhcmlhbnQgc3RhdGUgPSBhdXRvbWF0aW9uLmdldFByb3BlcnR5KFJFQURZU1RBVEUpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCZxdW90O1dlYiBTdGF0ZSBjaGFuZ2luZyBmcm9tICZxdW90OyArIHN0YXRlLmdldEludCgpKTsKCQkJCWV2ZW50LmRvaXQgPSB0cnVlOyAvLyBhbGxvdyBwcm9wZXJ0eSBjaGFuZ2UgdG8gaGFwcGVuCgoJCQl9CgkJCWlmIChldmVudC5kZXRhaWwgPT0gT0xFLlBST1BFUlRZX0NIQU5HRUQpIHsKCQkJCVZhcmlhbnQgc3RhdGUgPSBhdXRvbWF0aW9uLmdldFByb3BlcnR5KFJFQURZU1RBVEUpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCZxdW90O1dlYiBTdGF0ZSBjaGFuZ2VkIHRvICZxdW90OyArIHN0YXRlLmdldEludCgpKTsKCQkJfQoJCX0KCX0pOwo8L3ByZT4KCjxwPllvdSBjYW4gbGlzdGVuIGZvciBhIGNoYW5nZSB0byBhbnkgcHJvcGVydHkgZGVmaW5lZCBpbiB0aGUgdHlwZSBsaWJyYXJ5LgoKPHA+VGhlIHR5cGUgbGlicmFyeSBhbHNvIGNvbnRhaW5zIGVudW1lcmF0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIHRvIGludGVycHJldAp0aGUgcHJvcGVydHkgdmFsdWVzLiBGb3IgZXhhbXBsZSB0aGUgk1JlYWR5U3RhdGWUIHZhbHVlcyBpbiB0aGUgcHJldmlvdXMKZXhhbXBsZSBhcmUgaW50ZWdlciB2YWx1ZXMgYmVsb25naW5nIHRvIHRoZSBmb2xsb3dpbmcgZW51bWVyYXRpb246CjxwcmU+Cgl0eXBlZGVmIGVudW0gewoJCVJFQURZU1RBVEVfVU5JTklUSUFMSVpFRCA9IDAsCgkJUkVBRFlTVEFURV9MT0FESU5HID0gMSwKCQlSRUFEWVNUQVRFX0xPQURFRCA9IDIsCgkJUkVBRFlTVEFURV9JTlRFUkFDVElWRSA9IDMsCgkJUkVBRFlTVEFURV9DT01QTEVURSA9IDQKCX0gdGFnUkVBRFlTVEFURTsKPC9wcmU+CgogICAgICAgIDxoMz5TdW1tYXJ5PC9oMz4KICAgICAgICA8cD5PbiB0aGUgV2luZG93cyBwbGF0Zm9ybSwgYWRkaW5nIE9MRSBPYmplY3RzIHRvIHlvdXIgYXBwbGljYXRpb24KICAgICAgICBleHBhbmRzIHRoZSB1c2VyIGV4cGVyaWVuY2UuIFNXVCBtYWtlcyB0aGlzIGVhc3kgdG8gZG8gYnkgYWxsb3dpbmcgT0xFCiAgICAgICAgT2JqZWN0cyB0byBiZSBlbWJlZGRlZCBpbiBTV1QgPGk+Q29udGFpbmVyPC9pPiB3aWRnZXRzLCBtYWtpbmcgdGhlCiAgICAgICAgT2JqZWN0J3MgaW50ZXJmYWNlIGF2YWlsYWJsZSB0byB5b3VyIGFwcGxpY2F0aW9uLCBhbmQgdGhlcmVmb3JlIHRvIHlvdXIKICAgICAgICB1c2Vycy48L3A+Cgo8cD48c21hbGw+TWljcm9zb2Z0LCBXaW5kb3dzLCBXaW5kb3dzIE5ULCBhbmQgdGhlIFdpbmRvd3MgbG9nbyBhcmUgdHJhZGVtYXJrcyBvZiBNaWNyb3NvZnQgQ29ycG9yYXRpb24gaW4gdGhlIFVuaXRlZCBTdGF0ZXMsIG90aGVyIGNvdW50cmllcywgb3IgYm90aC48L3NtYWxsPjwvcD4KCQkKPC9ib2R5Pgo8L2h0bWw+