ZGlmZiAtLWdpdCBhL2J1aWxkL3Nkay5hdHJlZSBiL2J1aWxkL3Nkay5hdHJlZQppbmRleCBmNmJhMzAwLi5lMjc2MWQ0IDEwMDY0NAotLS0gYS9idWlsZC9zZGsuYXRyZWUKKysrIGIvYnVpbGQvc2RrLmF0cmVlCkBAIC04Niw2ICs4Niw3IEBACiAjIChzZWUgd2ViX2RvY3Nfc2FtcGxlX2NvZGVfZmxhZ3MgaW4gZnJhbWV3b3Jrcy9iYXNlL0FuZHJvaWQubWspCiBkZXZlbG9wbWVudC9zYW1wbGVzL3NvdXJjZS5wcm9wZXJ0aWVzICAgICAgICBzYW1wbGVzLyR7UExBVEZPUk1fTkFNRX0vc291cmNlLnByb3BlcnRpZXMKIGRldmVsb3BtZW50L2FwcHMvR2VzdHVyZUJ1aWxkZXIgICAgICAgICAgICAgIHNhbXBsZXMvJHtQTEFURk9STV9OQU1FfS9HZXN0dXJlQnVpbGRlcgorZGV2ZWxvcG1lbnQvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZSAgICAgc2FtcGxlcy8ke1BMQVRGT1JNX05BTUV9L0FjY2Vzc2liaWxpdHlTZXJ2aWNlCiBkZXZlbG9wbWVudC9zYW1wbGVzL0JsdWV0b290aENoYXQgICAgICAgICAgICBzYW1wbGVzLyR7UExBVEZPUk1fTkFNRX0vQmx1ZXRvb3RoQ2hhdAogZGV2ZWxvcG1lbnQvc2FtcGxlcy9Ib21lICAgICAgICAgICAgICAgICAgICAgc2FtcGxlcy8ke1BMQVRGT1JNX05BTUV9L0hvbWUKIGRldmVsb3BtZW50L3NhbXBsZXMvTHVuYXJMYW5kZXIgICAgICAgICAgICAgIHNhbXBsZXMvJHtQTEFURk9STV9OQU1FfS9MdW5hckxhbmRlcgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BY2NlbGVyb21ldGVyUGxheS9BbmRyb2lkLm1rIGIvc2FtcGxlcy9BY2NlbGVyb21ldGVyUGxheS9BbmRyb2lkLm1rCmluZGV4IDQ3NjcyNzEuLmU0YjBhYjkgMTAwNjQ0Ci0tLSBhL3NhbXBsZXMvQWNjZWxlcm9tZXRlclBsYXkvQW5kcm9pZC5taworKysgYi9zYW1wbGVzL0FjY2VsZXJvbWV0ZXJQbGF5L0FuZHJvaWQubWsKQEAgLTI1LDYgKzI1LDggQEAKIAogTE9DQUxfU0RLX1ZFUlNJT04gOj0gY3VycmVudAogCitMT0NBTF9BQVBUX0ZMQUdTID0gLWMgMTIwZHBpIC1jIDI0MGRwaSAtYyAxNjBkcGkKKwogaW5jbHVkZSAkKEJVSUxEX1BBQ0tBR0UpCiAKICMgVXNlIHRoZSBmb2xsb3dpbmcgaW5jbHVkZSB0byBtYWtlIG91ciB0ZXN0IGFway4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvQWNjZWxlcm9tZXRlclBsYXkvc3JjL2NvbS9leGFtcGxlL2FuZHJvaWQvYWNjZWxlcm9tZXRlcnBsYXkvQWNjZWxlcm9tZXRlclBsYXlBY3Rpdml0eS5qYXZhIGIvc2FtcGxlcy9BY2NlbGVyb21ldGVyUGxheS9zcmMvY29tL2V4YW1wbGUvYW5kcm9pZC9hY2NlbGVyb21ldGVycGxheS9BY2NlbGVyb21ldGVyUGxheUFjdGl2aXR5LmphdmEKaW5kZXggZWQwNjA1Yy4uYzllODQwZiAxMDA2NDQKLS0tIGEvc2FtcGxlcy9BY2NlbGVyb21ldGVyUGxheS9zcmMvY29tL2V4YW1wbGUvYW5kcm9pZC9hY2NlbGVyb21ldGVycGxheS9BY2NlbGVyb21ldGVyUGxheUFjdGl2aXR5LmphdmEKKysrIGIvc2FtcGxlcy9BY2NlbGVyb21ldGVyUGxheS9zcmMvY29tL2V4YW1wbGUvYW5kcm9pZC9hY2NlbGVyb21ldGVycGxheS9BY2NlbGVyb21ldGVyUGxheUFjdGl2aXR5LmphdmEKQEAgLTMwLDcgKzMwLDEwIEBACiBpbXBvcnQgYW5kcm9pZC5vcy5Qb3dlck1hbmFnZXI7CiBpbXBvcnQgYW5kcm9pZC5vcy5Qb3dlck1hbmFnZXIuV2FrZUxvY2s7CiBpbXBvcnQgYW5kcm9pZC51dGlsLkRpc3BsYXlNZXRyaWNzOworaW1wb3J0IGFuZHJvaWQudmlldy5EaXNwbGF5OworaW1wb3J0IGFuZHJvaWQudmlldy5TdXJmYWNlOwogaW1wb3J0IGFuZHJvaWQudmlldy5WaWV3OworaW1wb3J0IGFuZHJvaWQudmlldy5XaW5kb3dNYW5hZ2VyOwogCiAvKioKICAqIFRoaXMgaXMgYW4gZXhhbXBsZSBvZiB1c2luZyB0aGUgYWNjZWxlcm9tZXRlciB0byBpbnRlZ3JhdGUgdGhlIGRldmljZSdzCkBAIC00Niw0MDUgKzQ5LDQxMiBAQAogCiBwdWJsaWMgY2xhc3MgQWNjZWxlcm9tZXRlclBsYXlBY3Rpdml0eSBleHRlbmRzIEFjdGl2aXR5IHsKIAotCXByaXZhdGUgU2ltdWxhdGlvblZpZXcgbVNpbXVsYXRpb25WaWV3OwotCXByaXZhdGUgU2Vuc29yTWFuYWdlciBtU2Vuc29yTWFuYWdlcjsKLQlwcml2YXRlIFBvd2VyTWFuYWdlciBtUG93ZXJNYW5hZ2VyOwotCXByaXZhdGUgV2FrZUxvY2sgbVdha2VMb2NrOworICAgIHByaXZhdGUgU2ltdWxhdGlvblZpZXcgbVNpbXVsYXRpb25WaWV3OworICAgIHByaXZhdGUgU2Vuc29yTWFuYWdlciBtU2Vuc29yTWFuYWdlcjsKKyAgICBwcml2YXRlIFBvd2VyTWFuYWdlciBtUG93ZXJNYW5hZ2VyOworICAgIHByaXZhdGUgV2luZG93TWFuYWdlciBtV2luZG93TWFuYWdlcjsKKyAgICBwcml2YXRlIERpc3BsYXkgbURpc3BsYXk7CisgICAgcHJpdmF0ZSBXYWtlTG9jayBtV2FrZUxvY2s7CiAKLQkvKiogQ2FsbGVkIHdoZW4gdGhlIGFjdGl2aXR5IGlzIGZpcnN0IGNyZWF0ZWQuICovCi0JQE92ZXJyaWRlCi0JcHVibGljIHZvaWQgb25DcmVhdGUoQnVuZGxlIHNhdmVkSW5zdGFuY2VTdGF0ZSkgewotCQlzdXBlci5vbkNyZWF0ZShzYXZlZEluc3RhbmNlU3RhdGUpOworICAgIC8qKiBDYWxsZWQgd2hlbiB0aGUgYWN0aXZpdHkgaXMgZmlyc3QgY3JlYXRlZC4gKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBvbkNyZWF0ZShCdW5kbGUgc2F2ZWRJbnN0YW5jZVN0YXRlKSB7CisgICAgICAgIHN1cGVyLm9uQ3JlYXRlKHNhdmVkSW5zdGFuY2VTdGF0ZSk7CiAKLQkJLy8gR2V0IGFuIGluc3RhbmNlIG9mIHRoZSBTZW5zb3JNYW5hZ2VyCi0JCW1TZW5zb3JNYW5hZ2VyID0gKFNlbnNvck1hbmFnZXIpIGdldFN5c3RlbVNlcnZpY2UoU0VOU09SX1NFUlZJQ0UpOworICAgICAgICAvLyBHZXQgYW4gaW5zdGFuY2Ugb2YgdGhlIFNlbnNvck1hbmFnZXIKKyAgICAgICAgbVNlbnNvck1hbmFnZXIgPSAoU2Vuc29yTWFuYWdlcikgZ2V0U3lzdGVtU2VydmljZShTRU5TT1JfU0VSVklDRSk7CiAKLQkJLy8gR2V0IGFuIGluc3RhbmNlIG9mIHRoZSBQb3dlck1hbmFnZXIKLQkJbVBvd2VyTWFuYWdlciA9IChQb3dlck1hbmFnZXIpIGdldFN5c3RlbVNlcnZpY2UoUE9XRVJfU0VSVklDRSk7CisgICAgICAgIC8vIEdldCBhbiBpbnN0YW5jZSBvZiB0aGUgUG93ZXJNYW5hZ2VyCisgICAgICAgIG1Qb3dlck1hbmFnZXIgPSAoUG93ZXJNYW5hZ2VyKSBnZXRTeXN0ZW1TZXJ2aWNlKFBPV0VSX1NFUlZJQ0UpOwogCi0JCS8vIENyZWF0ZSBhIGJyaWdodCB3YWtlIGxvY2sKLQkJbVdha2VMb2NrID0gbVBvd2VyTWFuYWdlci5uZXdXYWtlTG9jaygKLQkJCQlQb3dlck1hbmFnZXIuU0NSRUVOX0JSSUdIVF9XQUtFX0xPQ0ssIGdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgLy8gR2V0IGFuIGluc3RhbmNlIG9mIHRoZSBXaW5kb3dNYW5hZ2VyCisgICAgICAgIG1XaW5kb3dNYW5hZ2VyID0gKFdpbmRvd01hbmFnZXIpIGdldFN5c3RlbVNlcnZpY2UoV0lORE9XX1NFUlZJQ0UpOworICAgICAgICBtRGlzcGxheSA9IG1XaW5kb3dNYW5hZ2VyLmdldERlZmF1bHREaXNwbGF5KCk7CiAKLQkJLy8gaW5zdGFudGlhdGUgb3VyIHNpbXVsYXRpb24gdmlldyBhbmQgc2V0IGl0IGFzIHRoZSBhY3Rpdml0eSdzIGNvbnRlbnQKLQkJbVNpbXVsYXRpb25WaWV3ID0gbmV3IFNpbXVsYXRpb25WaWV3KHRoaXMpOwotCQlzZXRDb250ZW50VmlldyhtU2ltdWxhdGlvblZpZXcpOwotCX0KKyAgICAgICAgLy8gQ3JlYXRlIGEgYnJpZ2h0IHdha2UgbG9jaworICAgICAgICBtV2FrZUxvY2sgPSBtUG93ZXJNYW5hZ2VyLm5ld1dha2VMb2NrKFBvd2VyTWFuYWdlci5TQ1JFRU5fQlJJR0hUX1dBS0VfTE9DSywgZ2V0Q2xhc3MoKQorICAgICAgICAgICAgICAgIC5nZXROYW1lKCkpOwogCi0JQE92ZXJyaWRlCi0JcHJvdGVjdGVkIHZvaWQgb25SZXN1bWUoKSB7Ci0JCXN1cGVyLm9uUmVzdW1lKCk7Ci0JCS8qCi0JCSAqIHdoZW4gdGhlIGFjdGl2aXR5IGlzIHJlc3VtZWQsIHdlIGFjcXVpcmUgYSB3YWtlLWxvY2sgc28gdGhhdCB0aGUKLQkJICogc2NyZWVuIHN0YXlzIG9uLCBzaW5jZSB0aGUgdXNlciB3aWxsIGxpa2VseSBub3QgYmUgZmlkZGxpbmcgd2l0aCB0aGUKLQkJICogc2NyZWVuIG9yIGJ1dHRvbnMuCi0JCSAqLwotCQltV2FrZUxvY2suYWNxdWlyZSgpOworICAgICAgICAvLyBpbnN0YW50aWF0ZSBvdXIgc2ltdWxhdGlvbiB2aWV3IGFuZCBzZXQgaXQgYXMgdGhlIGFjdGl2aXR5J3MgY29udGVudAorICAgICAgICBtU2ltdWxhdGlvblZpZXcgPSBuZXcgU2ltdWxhdGlvblZpZXcodGhpcyk7CisgICAgICAgIHNldENvbnRlbnRWaWV3KG1TaW11bGF0aW9uVmlldyk7CisgICAgfQogCi0JCS8vIFN0YXJ0IHRoZSBzaW11bGF0aW9uCi0JCW1TaW11bGF0aW9uVmlldy5zdGFydFNpbXVsYXRpb24oKTsKLQl9CisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgb25SZXN1bWUoKSB7CisgICAgICAgIHN1cGVyLm9uUmVzdW1lKCk7CisgICAgICAgIC8qCisgICAgICAgICAqIHdoZW4gdGhlIGFjdGl2aXR5IGlzIHJlc3VtZWQsIHdlIGFjcXVpcmUgYSB3YWtlLWxvY2sgc28gdGhhdCB0aGUKKyAgICAgICAgICogc2NyZWVuIHN0YXlzIG9uLCBzaW5jZSB0aGUgdXNlciB3aWxsIGxpa2VseSBub3QgYmUgZmlkZGxpbmcgd2l0aCB0aGUKKyAgICAgICAgICogc2NyZWVuIG9yIGJ1dHRvbnMuCisgICAgICAgICAqLworICAgICAgICBtV2FrZUxvY2suYWNxdWlyZSgpOwogCi0JQE92ZXJyaWRlCi0JcHJvdGVjdGVkIHZvaWQgb25QYXVzZSgpIHsKLQkJc3VwZXIub25QYXVzZSgpOwotCQkvKgotCQkgKiBXaGVuIHRoZSBhY3Rpdml0eSBpcyBwYXVzZWQsIHdlIG1ha2Ugc3VyZSB0byBzdG9wIHRoZSBzaW11bGF0aW9uLAotCQkgKiByZWxlYXNlIG91ciBzZW5zb3IgcmVzb3VyY2VzIGFuZCB3YWtlIGxvY2tzCi0JCSAqLworICAgICAgICAvLyBTdGFydCB0aGUgc2ltdWxhdGlvbgorICAgICAgICBtU2ltdWxhdGlvblZpZXcuc3RhcnRTaW11bGF0aW9uKCk7CisgICAgfQogCi0JCS8vIFN0b3AgdGhlIHNpbXVsYXRpb24KLQkJbVNpbXVsYXRpb25WaWV3LnN0b3BTaW11bGF0aW9uKCk7CisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgb25QYXVzZSgpIHsKKyAgICAgICAgc3VwZXIub25QYXVzZSgpOworICAgICAgICAvKgorICAgICAgICAgKiBXaGVuIHRoZSBhY3Rpdml0eSBpcyBwYXVzZWQsIHdlIG1ha2Ugc3VyZSB0byBzdG9wIHRoZSBzaW11bGF0aW9uLAorICAgICAgICAgKiByZWxlYXNlIG91ciBzZW5zb3IgcmVzb3VyY2VzIGFuZCB3YWtlIGxvY2tzCisgICAgICAgICAqLwogCi0JCS8vIGFuZCByZWxlYXNlIG91ciB3YWtlLWxvY2sKLQkJbVdha2VMb2NrLnJlbGVhc2UoKTsKLQl9CisgICAgICAgIC8vIFN0b3AgdGhlIHNpbXVsYXRpb24KKyAgICAgICAgbVNpbXVsYXRpb25WaWV3LnN0b3BTaW11bGF0aW9uKCk7CiAKLQljbGFzcyBTaW11bGF0aW9uVmlldyBleHRlbmRzIFZpZXcgaW1wbGVtZW50cyBTZW5zb3JFdmVudExpc3RlbmVyIHsKLQkJLy8gZGlhbWV0ZXIgb2YgdGhlIGJhbGxzIGluIG1ldGVycwotCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBmbG9hdCBzQmFsbERpYW1ldGVyID0gMC4wMDRmOwotCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBmbG9hdCBzQmFsbERpYW1ldGVyMiA9IHNCYWxsRGlhbWV0ZXIKLQkJCQkqIHNCYWxsRGlhbWV0ZXI7CisgICAgICAgIC8vIGFuZCByZWxlYXNlIG91ciB3YWtlLWxvY2sKKyAgICAgICAgbVdha2VMb2NrLnJlbGVhc2UoKTsKKyAgICB9CiAKLQkJLy8gZnJpY3Rpb24gb2YgdGhlIHZpcnR1YWwgdGFibGUgYW5kIGFpcgotCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBmbG9hdCBzRnJpY3Rpb24gPSAwLjFmOworICAgIGNsYXNzIFNpbXVsYXRpb25WaWV3IGV4dGVuZHMgVmlldyBpbXBsZW1lbnRzIFNlbnNvckV2ZW50TGlzdGVuZXIgeworICAgICAgICAvLyBkaWFtZXRlciBvZiB0aGUgYmFsbHMgaW4gbWV0ZXJzCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGZsb2F0IHNCYWxsRGlhbWV0ZXIgPSAwLjAwNGY7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGZsb2F0IHNCYWxsRGlhbWV0ZXIyID0gc0JhbGxEaWFtZXRlciAqIHNCYWxsRGlhbWV0ZXI7CiAKLQkJcHJpdmF0ZSBTZW5zb3IgbUFjY2VsZXJvbWV0ZXI7Ci0JCXByaXZhdGUgbG9uZyBtTGFzdFQ7Ci0JCXByaXZhdGUgZmxvYXQgbUxhc3REZWx0YVQ7CisgICAgICAgIC8vIGZyaWN0aW9uIG9mIHRoZSB2aXJ0dWFsIHRhYmxlIGFuZCBhaXIKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgZmxvYXQgc0ZyaWN0aW9uID0gMC4xZjsKIAotCQlwcml2YXRlIGZsb2F0IG1YRHBpOwotCQlwcml2YXRlIGZsb2F0IG1ZRHBpOwotCQlwcml2YXRlIGZsb2F0IG1NZXRlcnNUb1BpeGVsc1g7Ci0JCXByaXZhdGUgZmxvYXQgbU1ldGVyc1RvUGl4ZWxzWTsKLQkJcHJpdmF0ZSBCaXRtYXAgbUJpdG1hcDsKLQkJcHJpdmF0ZSBCaXRtYXAgbVdvb2Q7Ci0JCXByaXZhdGUgZmxvYXQgbVhPcmlnaW47Ci0JCXByaXZhdGUgZmxvYXQgbVlPcmlnaW47Ci0JCXByaXZhdGUgZmxvYXQgbVNlbnNvclg7Ci0JCXByaXZhdGUgZmxvYXQgbVNlbnNvclk7Ci0JCXByaXZhdGUgbG9uZyBtU2Vuc29yVGltZVN0YW1wOwotCQlwcml2YXRlIGxvbmcgbUNwdVRpbWVTdGFtcDsKLQkJcHJpdmF0ZSBmbG9hdCBtSG9yaXpvbnRhbEJvdW5kOwotCQlwcml2YXRlIGZsb2F0IG1WZXJ0aWNhbEJvdW5kOwotCQlwcml2YXRlIGZpbmFsIFBhcnRpY2xlU3lzdGVtIG1QYXJ0aWNsZVN5c3RlbSA9IG5ldyBQYXJ0aWNsZVN5c3RlbSgpOworICAgICAgICBwcml2YXRlIFNlbnNvciBtQWNjZWxlcm9tZXRlcjsKKyAgICAgICAgcHJpdmF0ZSBsb25nIG1MYXN0VDsKKyAgICAgICAgcHJpdmF0ZSBmbG9hdCBtTGFzdERlbHRhVDsKIAotCQkvKgotCQkgKiBFYWNoIG9mIG91ciBwYXJ0aWNsZSBob2xkcyBpdHMgcHJldmlvdXMgYW5kIGN1cnJlbnQgcG9zaXRpb24sIGl0cwotCQkgKiBhY2NlbGVyYXRpb24uIGZvciBhZGRlZCByZWFsaXNtIGVhY2ggcGFydGljbGUgaGFzIGl0cyBvd24gZnJpY3Rpb24KLQkJICogY29lZmZpY2llbnQuCi0JCSAqLwotCQljbGFzcyBQYXJ0aWNsZSB7Ci0JCQlwcml2YXRlIGZsb2F0IG1Qb3NYOwotCQkJcHJpdmF0ZSBmbG9hdCBtUG9zWTsKLQkJCXByaXZhdGUgZmxvYXQgbUFjY2VsWDsKLQkJCXByaXZhdGUgZmxvYXQgbUFjY2VsWTsKLQkJCXByaXZhdGUgZmxvYXQgbUxhc3RQb3NYOwotCQkJcHJpdmF0ZSBmbG9hdCBtTGFzdFBvc1k7Ci0JCQlwcml2YXRlIGZsb2F0IG1PbmVNaW51c0ZyaWN0aW9uOworICAgICAgICBwcml2YXRlIGZsb2F0IG1YRHBpOworICAgICAgICBwcml2YXRlIGZsb2F0IG1ZRHBpOworICAgICAgICBwcml2YXRlIGZsb2F0IG1NZXRlcnNUb1BpeGVsc1g7CisgICAgICAgIHByaXZhdGUgZmxvYXQgbU1ldGVyc1RvUGl4ZWxzWTsKKyAgICAgICAgcHJpdmF0ZSBCaXRtYXAgbUJpdG1hcDsKKyAgICAgICAgcHJpdmF0ZSBCaXRtYXAgbVdvb2Q7CisgICAgICAgIHByaXZhdGUgZmxvYXQgbVhPcmlnaW47CisgICAgICAgIHByaXZhdGUgZmxvYXQgbVlPcmlnaW47CisgICAgICAgIHByaXZhdGUgZmxvYXQgbVNlbnNvclg7CisgICAgICAgIHByaXZhdGUgZmxvYXQgbVNlbnNvclk7CisgICAgICAgIHByaXZhdGUgbG9uZyBtU2Vuc29yVGltZVN0YW1wOworICAgICAgICBwcml2YXRlIGxvbmcgbUNwdVRpbWVTdGFtcDsKKyAgICAgICAgcHJpdmF0ZSBmbG9hdCBtSG9yaXpvbnRhbEJvdW5kOworICAgICAgICBwcml2YXRlIGZsb2F0IG1WZXJ0aWNhbEJvdW5kOworICAgICAgICBwcml2YXRlIGZpbmFsIFBhcnRpY2xlU3lzdGVtIG1QYXJ0aWNsZVN5c3RlbSA9IG5ldyBQYXJ0aWNsZVN5c3RlbSgpOwogCi0JCQlQYXJ0aWNsZSgpIHsKLQkJCQkvLyBtYWtlIGVhY2ggcGFydGljbGUgYSBiaXQgZGlmZmVyZW50IGJ5IHJhbmRvbWl6aW5nIGl0cwotCQkJCS8vIGNvZWZmaWNpZW50IG9mIGZyaWN0aW9uCi0JCQkJZmluYWwgZmxvYXQgciA9ICgoZmxvYXQpIE1hdGgucmFuZG9tKCkgLSAwLjVmKSAqIDAuMmY7Ci0JCQkJbU9uZU1pbnVzRnJpY3Rpb24gPSAxLjBmIC0gc0ZyaWN0aW9uICsgcjsKLQkJCX0KKyAgICAgICAgLyoKKyAgICAgICAgICogRWFjaCBvZiBvdXIgcGFydGljbGUgaG9sZHMgaXRzIHByZXZpb3VzIGFuZCBjdXJyZW50IHBvc2l0aW9uLCBpdHMKKyAgICAgICAgICogYWNjZWxlcmF0aW9uLiBmb3IgYWRkZWQgcmVhbGlzbSBlYWNoIHBhcnRpY2xlIGhhcyBpdHMgb3duIGZyaWN0aW9uCisgICAgICAgICAqIGNvZWZmaWNpZW50LgorICAgICAgICAgKi8KKyAgICAgICAgY2xhc3MgUGFydGljbGUgeworICAgICAgICAgICAgcHJpdmF0ZSBmbG9hdCBtUG9zWDsKKyAgICAgICAgICAgIHByaXZhdGUgZmxvYXQgbVBvc1k7CisgICAgICAgICAgICBwcml2YXRlIGZsb2F0IG1BY2NlbFg7CisgICAgICAgICAgICBwcml2YXRlIGZsb2F0IG1BY2NlbFk7CisgICAgICAgICAgICBwcml2YXRlIGZsb2F0IG1MYXN0UG9zWDsKKyAgICAgICAgICAgIHByaXZhdGUgZmxvYXQgbUxhc3RQb3NZOworICAgICAgICAgICAgcHJpdmF0ZSBmbG9hdCBtT25lTWludXNGcmljdGlvbjsKIAotCQkJcHVibGljIHZvaWQgY29tcHV0ZVBoeXNpY3MoZmxvYXQgc3gsIGZsb2F0IHN5LCBmbG9hdCBkVCwgZmxvYXQgZFRDKSB7Ci0JCQkJLy8gRm9yY2Ugb2YgZ3Jhdml0eSBhcHBsaWVkIHRvIG91ciB2aXJ0dWFsIG9iamVjdAotCQkJCWZpbmFsIGZsb2F0IG0gPSAxMDAwLjBmOyAvLyBtYXNzIG9mIG91ciB2aXJ0dWFsIG9iamVjdAotCQkJCWZpbmFsIGZsb2F0IGd4ID0gLXN4ICogbTsKLQkJCQlmaW5hbCBmbG9hdCBneSA9IC1zeSAqIG07CisgICAgICAgICAgICBQYXJ0aWNsZSgpIHsKKyAgICAgICAgICAgICAgICAvLyBtYWtlIGVhY2ggcGFydGljbGUgYSBiaXQgZGlmZmVyZW50IGJ5IHJhbmRvbWl6aW5nIGl0cworICAgICAgICAgICAgICAgIC8vIGNvZWZmaWNpZW50IG9mIGZyaWN0aW9uCisgICAgICAgICAgICAgICAgZmluYWwgZmxvYXQgciA9ICgoZmxvYXQpIE1hdGgucmFuZG9tKCkgLSAwLjVmKSAqIDAuMmY7CisgICAgICAgICAgICAgICAgbU9uZU1pbnVzRnJpY3Rpb24gPSAxLjBmIC0gc0ZyaWN0aW9uICsgcjsKKyAgICAgICAgICAgIH0KIAotCQkJCS8qCi0JCQkJICogt0YgPSBtQSA8PT4gQSA9ILdGIC8gbQotCQkJCSAqIAotCQkJCSAqIFdlIGNvdWxkIHNpbXBsaWZ5IHRoZSBjb2RlIGJ5IGNvbXBsZXRlbHkgZWxpbWluYXRpbmcgIm0iICh0aGUKLQkJCQkgKiBtYXNzKSBmcm9tIGFsbCB0aGUgZXF1YXRpb25zLCBidXQgaXQgd291bGQgaGlkZSB0aGUgY29uY2VwdHMKLQkJCQkgKiBmcm9tIHRoaXMgc2FtcGxlIGNvZGUuCi0JCQkJICovCi0JCQkJZmluYWwgZmxvYXQgaW52bSA9IDEuMGYgLyBtOwotCQkJCWZpbmFsIGZsb2F0IGF4ID0gZ3ggKiBpbnZtOwotCQkJCWZpbmFsIGZsb2F0IGF5ID0gZ3kgKiBpbnZtOworICAgICAgICAgICAgcHVibGljIHZvaWQgY29tcHV0ZVBoeXNpY3MoZmxvYXQgc3gsIGZsb2F0IHN5LCBmbG9hdCBkVCwgZmxvYXQgZFRDKSB7CisgICAgICAgICAgICAgICAgLy8gRm9yY2Ugb2YgZ3Jhdml0eSBhcHBsaWVkIHRvIG91ciB2aXJ0dWFsIG9iamVjdAorICAgICAgICAgICAgICAgIGZpbmFsIGZsb2F0IG0gPSAxMDAwLjBmOyAvLyBtYXNzIG9mIG91ciB2aXJ0dWFsIG9iamVjdAorICAgICAgICAgICAgICAgIGZpbmFsIGZsb2F0IGd4ID0gLXN4ICogbTsKKyAgICAgICAgICAgICAgICBmaW5hbCBmbG9hdCBneSA9IC1zeSAqIG07CiAKLQkJCQkvKgotCQkJCSAqIFRpbWUtY29ycmVjdGVkIFZlcmxldCBpbnRlZ3JhdGlvbgotCQkJCSAqIAotCQkJCSAqIFRoZSBwb3NpdGlvbiBWZXJsZXQgaW50ZWdyYXRvciBpcyBkZWZpbmVkIGFzCi0JCQkJICogCi0JCQkJICogeCh0K8Z0KSA9IHgodCkgKyB4KHQpIC0geCh0LcZ0KSArIGEodCnGdPYyCi0JCQkJICogCi0JCQkJICogSG93ZXZlciwgdGhlIGFib3ZlIGVxdWF0aW9uIGRvZXNuJ3QgaGFuZGxlIHZhcmlhYmxlIMZ0IHZlcnkKLQkJCQkgKiB3ZWxsLCBhIHRpbWUtY29ycmVjdGVkIHZlcnNpb24gaXMgbmVlZGVkOgotCQkJCSAqIAotCQkJCSAqIHgodCvGdCkgPSB4KHQpICsgKHgodCkgLSB4KHQtxnQpKSAqICjGdC/GdF9wcmV2KSArIGEodCnGdPYyCi0JCQkJICogCi0JCQkJICogCi0JCQkJICogV2UgYWxzbyBhZGQgYSBzaW1wbGUgZnJpY3Rpb24gdGVybSAoZikgdG8gdGhlIGVxdWF0aW9uOgotCQkJCSAqIAotCQkJCSAqIHgodCvGdCkgPSB4KHQpICsgKDEtZikgKiAoeCh0KSAtIHgodC3GdCkpICogKMZ0L8Z0X3ByZXYpICsKLQkJCQkgKiBhKHQpxnT2MgotCQkJCSAqLwotCQkJCWZpbmFsIGZsb2F0IGRUZFQgPSBkVCAqIGRUOwotCQkJCWZpbmFsIGZsb2F0IHggPSBtUG9zWCArIG1PbmVNaW51c0ZyaWN0aW9uICogZFRDCi0JCQkJCQkqIChtUG9zWCAtIG1MYXN0UG9zWCkgKyBtQWNjZWxYICogZFRkVDsKLQkJCQlmaW5hbCBmbG9hdCB5ID0gbVBvc1kgKyBtT25lTWludXNGcmljdGlvbiAqIGRUQwotCQkJCQkJKiAobVBvc1kgLSBtTGFzdFBvc1kpICsgbUFjY2VsWSAqIGRUZFQ7Ci0JCQkJbUxhc3RQb3NYID0gbVBvc1g7Ci0JCQkJbUxhc3RQb3NZID0gbVBvc1k7Ci0JCQkJbVBvc1ggPSB4OwotCQkJCW1Qb3NZID0geTsKLQkJCQltQWNjZWxYID0gYXg7Ci0JCQkJbUFjY2VsWSA9IGF5OwotCQkJfQorICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogt0YgPSBtQSA8PT4gQSA9ILdGIC8gbSBXZSBjb3VsZCBzaW1wbGlmeSB0aGUgY29kZSBieQorICAgICAgICAgICAgICAgICAqIGNvbXBsZXRlbHkgZWxpbWluYXRpbmcgIm0iICh0aGUgbWFzcykgZnJvbSBhbGwgdGhlIGVxdWF0aW9ucywKKyAgICAgICAgICAgICAgICAgKiBidXQgaXQgd291bGQgaGlkZSB0aGUgY29uY2VwdHMgZnJvbSB0aGlzIHNhbXBsZSBjb2RlLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGZpbmFsIGZsb2F0IGludm0gPSAxLjBmIC8gbTsKKyAgICAgICAgICAgICAgICBmaW5hbCBmbG9hdCBheCA9IGd4ICogaW52bTsKKyAgICAgICAgICAgICAgICBmaW5hbCBmbG9hdCBheSA9IGd5ICogaW52bTsKIAotCQkJLyoKLQkJCSAqIFJlc29sdmluZyBjb25zdHJhaW50cyBhbmQgY29sbGlzaW9ucyB3aXRoIHRoZSBWZXJsZXQgaW50ZWdyYXRvcgotCQkJICogY2FuIGJlIHZlcnkgc2ltcGxlLCB3ZSBzaW1wbHkgbmVlZCB0byBtb3ZlIGEgY29sbGlkaW5nIG9yCi0JCQkgKiBjb25zdHJhaW5lZCBwYXJ0aWNsZSBpbiBzdWNoIHdheSB0aGF0IHRoZSBjb25zdHJhaW50IGlzCi0JCQkgKiBzYXRpc2ZpZWQuCi0JCQkgKi8KLQkJCXB1YmxpYyB2b2lkIHJlc29sdmVDb2xsaXNpb25XaXRoQm91bmRzKCkgewotCQkJCWZpbmFsIGZsb2F0IHhtYXggPSBtSG9yaXpvbnRhbEJvdW5kOwotCQkJCWZpbmFsIGZsb2F0IHltYXggPSBtVmVydGljYWxCb3VuZDsKLQkJCQlmaW5hbCBmbG9hdCB4ID0gbVBvc1g7Ci0JCQkJZmluYWwgZmxvYXQgeSA9IG1Qb3NZOwotCQkJCWlmICh4ID4geG1heCkgewotCQkJCQltUG9zWCA9IHhtYXg7Ci0JCQkJfSBlbHNlIGlmICh4IDwgLXhtYXgpIHsKLQkJCQkJbVBvc1ggPSAteG1heDsKLQkJCQl9Ci0JCQkJaWYgKHkgPiB5bWF4KSB7Ci0JCQkJCW1Qb3NZID0geW1heDsKLQkJCQl9IGVsc2UgaWYgKHkgPCAteW1heCkgewotCQkJCQltUG9zWSA9IC15bWF4OwotCQkJCX0KLQkJCX0KLQkJfQorICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogVGltZS1jb3JyZWN0ZWQgVmVybGV0IGludGVncmF0aW9uIFRoZSBwb3NpdGlvbiBWZXJsZXQKKyAgICAgICAgICAgICAgICAgKiBpbnRlZ3JhdG9yIGlzIGRlZmluZWQgYXMgeCh0K8Z0KSA9IHgodCkgKyB4KHQpIC0geCh0LcZ0KSArCisgICAgICAgICAgICAgICAgICogYSh0KcZ09jIgSG93ZXZlciwgdGhlIGFib3ZlIGVxdWF0aW9uIGRvZXNuJ3QgaGFuZGxlIHZhcmlhYmxlCisgICAgICAgICAgICAgICAgICogxnQgdmVyeSB3ZWxsLCBhIHRpbWUtY29ycmVjdGVkIHZlcnNpb24gaXMgbmVlZGVkOiB4KHQrxnQpID0KKyAgICAgICAgICAgICAgICAgKiB4KHQpICsgKHgodCkgLSB4KHQtxnQpKSAqICjGdC/GdF9wcmV2KSArIGEodCnGdPYyIFdlIGFsc28gYWRkCisgICAgICAgICAgICAgICAgICogYSBzaW1wbGUgZnJpY3Rpb24gdGVybSAoZikgdG8gdGhlIGVxdWF0aW9uOiB4KHQrxnQpID0geCh0KSArCisgICAgICAgICAgICAgICAgICogKDEtZikgKiAoeCh0KSAtIHgodC3GdCkpICogKMZ0L8Z0X3ByZXYpICsgYSh0KcZ09jIKKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBmaW5hbCBmbG9hdCBkVGRUID0gZFQgKiBkVDsKKyAgICAgICAgICAgICAgICBmaW5hbCBmbG9hdCB4ID0gbVBvc1ggKyBtT25lTWludXNGcmljdGlvbiAqIGRUQyAqIChtUG9zWCAtIG1MYXN0UG9zWCkgKyBtQWNjZWxYCisgICAgICAgICAgICAgICAgICAgICAgICAqIGRUZFQ7CisgICAgICAgICAgICAgICAgZmluYWwgZmxvYXQgeSA9IG1Qb3NZICsgbU9uZU1pbnVzRnJpY3Rpb24gKiBkVEMgKiAobVBvc1kgLSBtTGFzdFBvc1kpICsgbUFjY2VsWQorICAgICAgICAgICAgICAgICAgICAgICAgKiBkVGRUOworICAgICAgICAgICAgICAgIG1MYXN0UG9zWCA9IG1Qb3NYOworICAgICAgICAgICAgICAgIG1MYXN0UG9zWSA9IG1Qb3NZOworICAgICAgICAgICAgICAgIG1Qb3NYID0geDsKKyAgICAgICAgICAgICAgICBtUG9zWSA9IHk7CisgICAgICAgICAgICAgICAgbUFjY2VsWCA9IGF4OworICAgICAgICAgICAgICAgIG1BY2NlbFkgPSBheTsKKyAgICAgICAgICAgIH0KIAotCQkvKgotCQkgKiBBIHBhcnRpY2xlIHN5c3RlbSBpcyBqdXN0IGEgY29sbGVjdGlvbiBvZiBwYXJ0aWNsZXMKLQkJICovCi0JCWNsYXNzIFBhcnRpY2xlU3lzdGVtIHsKLQkJCXN0YXRpYyBmaW5hbCBpbnQgTlVNX1BBUlRJQ0xFUyA9IDE1OwotCQkJcHJpdmF0ZSBQYXJ0aWNsZSBtQmFsbHNbXSA9IG5ldyBQYXJ0aWNsZVtOVU1fUEFSVElDTEVTXTsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBSZXNvbHZpbmcgY29uc3RyYWludHMgYW5kIGNvbGxpc2lvbnMgd2l0aCB0aGUgVmVybGV0IGludGVncmF0b3IKKyAgICAgICAgICAgICAqIGNhbiBiZSB2ZXJ5IHNpbXBsZSwgd2Ugc2ltcGx5IG5lZWQgdG8gbW92ZSBhIGNvbGxpZGluZyBvcgorICAgICAgICAgICAgICogY29uc3RyYWluZWQgcGFydGljbGUgaW4gc3VjaCB3YXkgdGhhdCB0aGUgY29uc3RyYWludCBpcworICAgICAgICAgICAgICogc2F0aXNmaWVkLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBwdWJsaWMgdm9pZCByZXNvbHZlQ29sbGlzaW9uV2l0aEJvdW5kcygpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBmbG9hdCB4bWF4ID0gbUhvcml6b250YWxCb3VuZDsKKyAgICAgICAgICAgICAgICBmaW5hbCBmbG9hdCB5bWF4ID0gbVZlcnRpY2FsQm91bmQ7CisgICAgICAgICAgICAgICAgZmluYWwgZmxvYXQgeCA9IG1Qb3NYOworICAgICAgICAgICAgICAgIGZpbmFsIGZsb2F0IHkgPSBtUG9zWTsKKyAgICAgICAgICAgICAgICBpZiAoeCA+IHhtYXgpIHsKKyAgICAgICAgICAgICAgICAgICAgbVBvc1ggPSB4bWF4OworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeCA8IC14bWF4KSB7CisgICAgICAgICAgICAgICAgICAgIG1Qb3NYID0gLXhtYXg7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICh5ID4geW1heCkgeworICAgICAgICAgICAgICAgICAgICBtUG9zWSA9IHltYXg7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh5IDwgLXltYXgpIHsKKyAgICAgICAgICAgICAgICAgICAgbVBvc1kgPSAteW1heDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KIAotCQkJUGFydGljbGVTeXN0ZW0oKSB7Ci0JCQkJLyoKLQkJCQkgKiBJbml0aWFsbHkgb3VyIHBhcnRpY2xlcyBoYXZlIG5vIHNwZWVkIG9yIGFjY2VsZXJhdGlvbgotCQkJCSAqLwotCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbUJhbGxzLmxlbmd0aDsgaSsrKSB7Ci0JCQkJCW1CYWxsc1tpXSA9IG5ldyBQYXJ0aWNsZSgpOwotCQkJCX0KLQkJCX0KKyAgICAgICAgLyoKKyAgICAgICAgICogQSBwYXJ0aWNsZSBzeXN0ZW0gaXMganVzdCBhIGNvbGxlY3Rpb24gb2YgcGFydGljbGVzCisgICAgICAgICAqLworICAgICAgICBjbGFzcyBQYXJ0aWNsZVN5c3RlbSB7CisgICAgICAgICAgICBzdGF0aWMgZmluYWwgaW50IE5VTV9QQVJUSUNMRVMgPSAxNTsKKyAgICAgICAgICAgIHByaXZhdGUgUGFydGljbGUgbUJhbGxzW10gPSBuZXcgUGFydGljbGVbTlVNX1BBUlRJQ0xFU107CiAKLQkJCS8qCi0JCQkgKiBVcGRhdGUgdGhlIHBvc2l0aW9uIG9mIGVhY2ggcGFydGljbGUgaW4gdGhlIHN5c3RlbSB1c2luZyB0aGUKLQkJCSAqIFZlcmxldCBpbnRlZ3JhdG9yLgotCQkJICovCi0JCQlwcml2YXRlIHZvaWQgdXBkYXRlUG9zaXRpb25zKGZsb2F0IHN4LCBmbG9hdCBzeSwgbG9uZyB0aW1lc3RhbXApIHsKLQkJCQlmaW5hbCBsb25nIHQgPSB0aW1lc3RhbXA7Ci0JCQkJaWYgKG1MYXN0VCAhPSAwKSB7Ci0JCQkJCWZpbmFsIGZsb2F0IGRUID0gKGZsb2F0KSAodCAtIG1MYXN0VCkKLQkJCQkJCQkqICgxLjBmIC8gMTAwMDAwMDAwMC4wZik7Ci0JCQkJCWlmIChtTGFzdERlbHRhVCAhPSAwKSB7Ci0JCQkJCQlmaW5hbCBmbG9hdCBkVEMgPSBkVCAvIG1MYXN0RGVsdGFUOwotCQkJCQkJZmluYWwgaW50IGNvdW50ID0gbUJhbGxzLmxlbmd0aDsKLQkJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotCQkJCQkJCVBhcnRpY2xlIGJhbGwgPSBtQmFsbHNbaV07Ci0JCQkJCQkJYmFsbC5jb21wdXRlUGh5c2ljcyhzeCwgc3ksIGRULCBkVEMpOwotCQkJCQkJfQotCQkJCQl9Ci0JCQkJCW1MYXN0RGVsdGFUID0gZFQ7Ci0JCQkJfQotCQkJCW1MYXN0VCA9IHQ7Ci0JCQl9CisgICAgICAgICAgICBQYXJ0aWNsZVN5c3RlbSgpIHsKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIEluaXRpYWxseSBvdXIgcGFydGljbGVzIGhhdmUgbm8gc3BlZWQgb3IgYWNjZWxlcmF0aW9uCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtQmFsbHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgbUJhbGxzW2ldID0gbmV3IFBhcnRpY2xlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQogCi0JCQkvKgotCQkJICogUGVyZm9ybXMgb25lIGl0ZXJhdGlvbiBvZiB0aGUgc2ltdWxhdGlvbi4gRmlyc3QgdXBkYXRpbmcgdGhlCi0JCQkgKiBwb3NpdGlvbiBvZiBhbGwgdGhlIHBhcnRpY2xlcyBhbmQgcmVzb2x2aW5nIHRoZSBjb25zdHJhaW50cyBhbmQKLQkJCSAqIGNvbGxpc2lvbnMuCi0JCQkgKi8KLQkJCXB1YmxpYyB2b2lkIHVwZGF0ZShmbG9hdCBzeCwgZmxvYXQgc3ksIGxvbmcgbm93KSB7Ci0JCQkJLy8gdXBkYXRlIHRoZSBzeXN0ZW0ncyBwb3NpdGlvbnMKLQkJCQl1cGRhdGVQb3NpdGlvbnMoc3gsIHN5LCBub3cpOworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFVwZGF0ZSB0aGUgcG9zaXRpb24gb2YgZWFjaCBwYXJ0aWNsZSBpbiB0aGUgc3lzdGVtIHVzaW5nIHRoZQorICAgICAgICAgICAgICogVmVybGV0IGludGVncmF0b3IuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHByaXZhdGUgdm9pZCB1cGRhdGVQb3NpdGlvbnMoZmxvYXQgc3gsIGZsb2F0IHN5LCBsb25nIHRpbWVzdGFtcCkgeworICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgdCA9IHRpbWVzdGFtcDsKKyAgICAgICAgICAgICAgICBpZiAobUxhc3RUICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgZmxvYXQgZFQgPSAoZmxvYXQpICh0IC0gbUxhc3RUKSAqICgxLjBmIC8gMTAwMDAwMDAwMC4wZik7CisgICAgICAgICAgICAgICAgICAgIGlmIChtTGFzdERlbHRhVCAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBmbG9hdCBkVEMgPSBkVCAvIG1MYXN0RGVsdGFUOworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGNvdW50ID0gbUJhbGxzLmxlbmd0aDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcnRpY2xlIGJhbGwgPSBtQmFsbHNbaV07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFsbC5jb21wdXRlUGh5c2ljcyhzeCwgc3ksIGRULCBkVEMpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIG1MYXN0RGVsdGFUID0gZFQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG1MYXN0VCA9IHQ7CisgICAgICAgICAgICB9CiAKLQkJCQkvLyBXZSBkbyBubyBtb3JlIHRoYW4gYSBsaW1pdGVkIG51bWJlciBvZiBpdGVyYXRpb25zCi0JCQkJZmluYWwgaW50IE5VTV9NQVhfSVRFUkFUSU9OUyA9IDEwOworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFBlcmZvcm1zIG9uZSBpdGVyYXRpb24gb2YgdGhlIHNpbXVsYXRpb24uIEZpcnN0IHVwZGF0aW5nIHRoZQorICAgICAgICAgICAgICogcG9zaXRpb24gb2YgYWxsIHRoZSBwYXJ0aWNsZXMgYW5kIHJlc29sdmluZyB0aGUgY29uc3RyYWludHMgYW5kCisgICAgICAgICAgICAgKiBjb2xsaXNpb25zLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBwdWJsaWMgdm9pZCB1cGRhdGUoZmxvYXQgc3gsIGZsb2F0IHN5LCBsb25nIG5vdykgeworICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgc3lzdGVtJ3MgcG9zaXRpb25zCisgICAgICAgICAgICAgICAgdXBkYXRlUG9zaXRpb25zKHN4LCBzeSwgbm93KTsKIAotCQkJCS8qCi0JCQkJICogUmVzb2x2ZSBjb2xsaXNpb25zLCBlYWNoIHBhcnRpY2xlIGlzIHRlc3RlZCBhZ2FpbnN0IGV2ZXJ5Ci0JCQkJICogb3RoZXIgcGFydGljbGUgZm9yIGNvbGxpc2lvbi4gSWYgYSBjb2xsaXNpb24gaXMgZGV0ZWN0ZWQgdGhlCi0JCQkJICogcGFydGljbGUgaXMgbW92ZWQgYXdheSB1c2luZyBhIHZpcnR1YWwgc3ByaW5nIG9mIGluZmluaXRlCi0JCQkJICogc3RpZmZuZXNzLgotCQkJCSAqLwotCQkJCWJvb2xlYW4gbW9yZSA9IHRydWU7Ci0JCQkJZmluYWwgaW50IGNvdW50ID0gbUJhbGxzLmxlbmd0aDsKLQkJCQlmb3IgKGludCBrID0gMDsgayA8IE5VTV9NQVhfSVRFUkFUSU9OUyAmJiBtb3JlOyBrKyspIHsKLQkJCQkJbW9yZSA9IGZhbHNlOwotCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLQkJCQkJCVBhcnRpY2xlIGN1cnIgPSBtQmFsbHNbaV07Ci0JCQkJCQlmb3IgKGludCBqID0gaSArIDE7IGogPCBjb3VudDsgaisrKSB7Ci0JCQkJCQkJUGFydGljbGUgYmFsbCA9IG1CYWxsc1tqXTsKLQkJCQkJCQlmbG9hdCBkeCA9IGJhbGwubVBvc1ggLSBjdXJyLm1Qb3NYOwotCQkJCQkJCWZsb2F0IGR5ID0gYmFsbC5tUG9zWSAtIGN1cnIubVBvc1k7Ci0JCQkJCQkJZmxvYXQgZGQgPSBkeCAqIGR4ICsgZHkgKiBkeTsKLQkJCQkJCQkvLyBDaGVjayBmb3IgY29sbGlzaW9ucwotCQkJCQkJCWlmIChkZCA8PSBzQmFsbERpYW1ldGVyMikgewotCQkJCQkJCQkvKgotCQkJCQkJCQkgKiBhZGQgYSBsaXR0bGUgYml0IG9mIGVudHJvcHksIGFmdGVyIG5vdGhpbmcgaXMKLQkJCQkJCQkJICogcGVyZmVjdCBpbiB0aGUgdW5pdmVyc2UuCi0JCQkJCQkJCSAqLwotCQkJCQkJCQlkeCArPSAoKGZsb2F0KSBNYXRoLnJhbmRvbSgpIC0gMC41ZikgKiAwLjAwMDFmOwotCQkJCQkJCQlkeSArPSAoKGZsb2F0KSBNYXRoLnJhbmRvbSgpIC0gMC41ZikgKiAwLjAwMDFmOwotCQkJCQkJCQlkZCA9IGR4ICogZHggKyBkeSAqIGR5OwotCQkJCQkJCQkvLyBzaW11bGF0ZSB0aGUgc3ByaW5nCi0JCQkJCQkJCWZpbmFsIGZsb2F0IGQgPSAoZmxvYXQpIE1hdGguc3FydChkZCk7Ci0JCQkJCQkJCWZpbmFsIGZsb2F0IGMgPSAoMC41ZiAqIChzQmFsbERpYW1ldGVyIC0gZCkpCi0JCQkJCQkJCQkJLyBkOwotCQkJCQkJCQljdXJyLm1Qb3NYIC09IGR4ICogYzsKLQkJCQkJCQkJY3Vyci5tUG9zWSAtPSBkeSAqIGM7Ci0JCQkJCQkJCWJhbGwubVBvc1ggKz0gZHggKiBjOwotCQkJCQkJCQliYWxsLm1Qb3NZICs9IGR5ICogYzsKLQkJCQkJCQkJbW9yZSA9IHRydWU7Ci0JCQkJCQkJfQotCQkJCQkJfQotCQkJCQkJLyoKLQkJCQkJCSAqIEZpbmFsbHkgbWFrZSBzdXJlIHRoZSBwYXJ0aWNsZSBkb2Vzbid0IGludGVyc2VjdHMKLQkJCQkJCSAqIHdpdGggdGhlIHdhbGxzLgotCQkJCQkJICovCi0JCQkJCQljdXJyLnJlc29sdmVDb2xsaXNpb25XaXRoQm91bmRzKCk7Ci0JCQkJCX0KLQkJCQl9Ci0JCQl9CisgICAgICAgICAgICAgICAgLy8gV2UgZG8gbm8gbW9yZSB0aGFuIGEgbGltaXRlZCBudW1iZXIgb2YgaXRlcmF0aW9ucworICAgICAgICAgICAgICAgIGZpbmFsIGludCBOVU1fTUFYX0lURVJBVElPTlMgPSAxMDsKIAotCQkJcHVibGljIGludCBnZXRQYXJ0aWNsZUNvdW50KCkgewotCQkJCXJldHVybiBtQmFsbHMubGVuZ3RoOwotCQkJfQorICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogUmVzb2x2ZSBjb2xsaXNpb25zLCBlYWNoIHBhcnRpY2xlIGlzIHRlc3RlZCBhZ2FpbnN0IGV2ZXJ5CisgICAgICAgICAgICAgICAgICogb3RoZXIgcGFydGljbGUgZm9yIGNvbGxpc2lvbi4gSWYgYSBjb2xsaXNpb24gaXMgZGV0ZWN0ZWQgdGhlCisgICAgICAgICAgICAgICAgICogcGFydGljbGUgaXMgbW92ZWQgYXdheSB1c2luZyBhIHZpcnR1YWwgc3ByaW5nIG9mIGluZmluaXRlCisgICAgICAgICAgICAgICAgICogc3RpZmZuZXNzLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGJvb2xlYW4gbW9yZSA9IHRydWU7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IGNvdW50ID0gbUJhbGxzLmxlbmd0aDsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IE5VTV9NQVhfSVRFUkFUSU9OUyAmJiBtb3JlOyBrKyspIHsKKyAgICAgICAgICAgICAgICAgICAgbW9yZSA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFBhcnRpY2xlIGN1cnIgPSBtQmFsbHNbaV07CisgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gaSArIDE7IGogPCBjb3VudDsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFydGljbGUgYmFsbCA9IG1CYWxsc1tqXTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbG9hdCBkeCA9IGJhbGwubVBvc1ggLSBjdXJyLm1Qb3NYOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IGR5ID0gYmFsbC5tUG9zWSAtIGN1cnIubVBvc1k7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgZGQgPSBkeCAqIGR4ICsgZHkgKiBkeTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgY29sbGlzaW9ucworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZCA8PSBzQmFsbERpYW1ldGVyMikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBhZGQgYSBsaXR0bGUgYml0IG9mIGVudHJvcHksIGFmdGVyIG5vdGhpbmcgaXMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogcGVyZmVjdCBpbiB0aGUgdW5pdmVyc2UuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeCArPSAoKGZsb2F0KSBNYXRoLnJhbmRvbSgpIC0gMC41ZikgKiAwLjAwMDFmOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeSArPSAoKGZsb2F0KSBNYXRoLnJhbmRvbSgpIC0gMC41ZikgKiAwLjAwMDFmOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZCA9IGR4ICogZHggKyBkeSAqIGR5OworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW11bGF0ZSB0aGUgc3ByaW5nCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGZsb2F0IGQgPSAoZmxvYXQpIE1hdGguc3FydChkZCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGZsb2F0IGMgPSAoMC41ZiAqIChzQmFsbERpYW1ldGVyIC0gZCkpIC8gZDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3Vyci5tUG9zWCAtPSBkeCAqIGM7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnIubVBvc1kgLT0gZHkgKiBjOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWxsLm1Qb3NYICs9IGR4ICogYzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFsbC5tUG9zWSArPSBkeSAqIGM7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vcmUgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICAgICAgICAgKiBGaW5hbGx5IG1ha2Ugc3VyZSB0aGUgcGFydGljbGUgZG9lc24ndCBpbnRlcnNlY3RzCisgICAgICAgICAgICAgICAgICAgICAgICAgKiB3aXRoIHRoZSB3YWxscy4KKyAgICAgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICAgICAgY3Vyci5yZXNvbHZlQ29sbGlzaW9uV2l0aEJvdW5kcygpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQogCi0JCQlwdWJsaWMgZmxvYXQgZ2V0UG9zWChpbnQgaSkgewotCQkJCXJldHVybiBtQmFsbHNbaV0ubVBvc1g7Ci0JCQl9CisgICAgICAgICAgICBwdWJsaWMgaW50IGdldFBhcnRpY2xlQ291bnQoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1CYWxscy5sZW5ndGg7CisgICAgICAgICAgICB9CiAKLQkJCXB1YmxpYyBmbG9hdCBnZXRQb3NZKGludCBpKSB7Ci0JCQkJcmV0dXJuIG1CYWxsc1tpXS5tUG9zWTsKLQkJCX0KLQkJfQorICAgICAgICAgICAgcHVibGljIGZsb2F0IGdldFBvc1goaW50IGkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbUJhbGxzW2ldLm1Qb3NYOworICAgICAgICAgICAgfQogCi0JCXB1YmxpYyB2b2lkIHN0YXJ0U2ltdWxhdGlvbigpIHsKLQkJCS8qCi0JCQkgKiBJdCBpcyBub3QgbmVjZXNzYXJ5IHRvIGdldCBhY2NlbGVyb21ldGVyIGV2ZW50cyBhdCBhIHZlcnkgaGlnaAotCQkJICogcmF0ZSwgYnkgdXNpbmcgYSBzbG93ZXIgcmF0ZSAoU0VOU09SX0RFTEFZX1VJKSwgd2UgZ2V0IGFuCi0JCQkgKiBhdXRvbWF0aWMgbG93LXBhc3MgZmlsdGVyLCB3aGljaCAiZXh0cmFjdHMiIHRoZSBncmF2aXR5IGNvbXBvbmVudAotCQkJICogb2YgdGhlIGFjY2VsZXJhdGlvbi4gQXMgYW4gYWRkZWQgYmVuZWZpdCwgd2UgdXNlIGxlc3MgcG93ZXIgYW5kCi0JCQkgKiBDUFUgcmVzb3VyY2VzLgotCQkJICovCi0JCQltU2Vuc29yTWFuYWdlci5yZWdpc3Rlckxpc3RlbmVyKHRoaXMsIG1BY2NlbGVyb21ldGVyLAotCQkJCQlTZW5zb3JNYW5hZ2VyLlNFTlNPUl9ERUxBWV9VSSk7Ci0JCX0KKyAgICAgICAgICAgIHB1YmxpYyBmbG9hdCBnZXRQb3NZKGludCBpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1CYWxsc1tpXS5tUG9zWTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQogCi0JCXB1YmxpYyB2b2lkIHN0b3BTaW11bGF0aW9uKCkgewotCQkJbVNlbnNvck1hbmFnZXIudW5yZWdpc3Rlckxpc3RlbmVyKHRoaXMpOwotCQl9CisgICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0U2ltdWxhdGlvbigpIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBJdCBpcyBub3QgbmVjZXNzYXJ5IHRvIGdldCBhY2NlbGVyb21ldGVyIGV2ZW50cyBhdCBhIHZlcnkgaGlnaAorICAgICAgICAgICAgICogcmF0ZSwgYnkgdXNpbmcgYSBzbG93ZXIgcmF0ZSAoU0VOU09SX0RFTEFZX1VJKSwgd2UgZ2V0IGFuCisgICAgICAgICAgICAgKiBhdXRvbWF0aWMgbG93LXBhc3MgZmlsdGVyLCB3aGljaCAiZXh0cmFjdHMiIHRoZSBncmF2aXR5IGNvbXBvbmVudAorICAgICAgICAgICAgICogb2YgdGhlIGFjY2VsZXJhdGlvbi4gQXMgYW4gYWRkZWQgYmVuZWZpdCwgd2UgdXNlIGxlc3MgcG93ZXIgYW5kCisgICAgICAgICAgICAgKiBDUFUgcmVzb3VyY2VzLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBtU2Vuc29yTWFuYWdlci5yZWdpc3Rlckxpc3RlbmVyKHRoaXMsIG1BY2NlbGVyb21ldGVyLCBTZW5zb3JNYW5hZ2VyLlNFTlNPUl9ERUxBWV9VSSk7CisgICAgICAgIH0KIAotCQlwdWJsaWMgU2ltdWxhdGlvblZpZXcoQ29udGV4dCBjb250ZXh0KSB7Ci0JCQlzdXBlcihjb250ZXh0KTsKLQkJCW1BY2NlbGVyb21ldGVyID0gbVNlbnNvck1hbmFnZXIKLQkJCQkJLmdldERlZmF1bHRTZW5zb3IoU2Vuc29yLlRZUEVfQUNDRUxFUk9NRVRFUik7CisgICAgICAgIHB1YmxpYyB2b2lkIHN0b3BTaW11bGF0aW9uKCkgeworICAgICAgICAgICAgbVNlbnNvck1hbmFnZXIudW5yZWdpc3Rlckxpc3RlbmVyKHRoaXMpOworICAgICAgICB9CiAKLQkJCURpc3BsYXlNZXRyaWNzIG1ldHJpY3MgPSBuZXcgRGlzcGxheU1ldHJpY3MoKTsKLQkJCWdldFdpbmRvd01hbmFnZXIoKS5nZXREZWZhdWx0RGlzcGxheSgpLmdldE1ldHJpY3MobWV0cmljcyk7Ci0JCQltWERwaSA9IG1ldHJpY3MueGRwaTsKLQkJCW1ZRHBpID0gbWV0cmljcy55ZHBpOwotCQkJbU1ldGVyc1RvUGl4ZWxzWCA9IG1YRHBpIC8gMC4wMjU0ZjsKLQkJCW1NZXRlcnNUb1BpeGVsc1kgPSBtWURwaSAvIDAuMDI1NGY7CisgICAgICAgIHB1YmxpYyBTaW11bGF0aW9uVmlldyhDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgICAgIHN1cGVyKGNvbnRleHQpOworICAgICAgICAgICAgbUFjY2VsZXJvbWV0ZXIgPSBtU2Vuc29yTWFuYWdlci5nZXREZWZhdWx0U2Vuc29yKFNlbnNvci5UWVBFX0FDQ0VMRVJPTUVURVIpOwogCi0JCQkvLyByZXNjYWxlIHRoZSBiYWxsIHNvIGl0J3MgYWJvdXQgMC41IGNtIG9uIHNjcmVlbgotCQkJQml0bWFwIGJhbGwgPSBCaXRtYXBGYWN0b3J5LmRlY29kZVJlc291cmNlKGdldFJlc291cmNlcygpLAotCQkJCQlSLmRyYXdhYmxlLmJhbGwpOwotCQkJZmluYWwgaW50IGRzdFdpZHRoID0gKGludCkgKHNCYWxsRGlhbWV0ZXIgKiBtTWV0ZXJzVG9QaXhlbHNYICsgMC41Zik7Ci0JCQlmaW5hbCBpbnQgZHN0SGVpZ2h0ID0gKGludCkgKHNCYWxsRGlhbWV0ZXIgKiBtTWV0ZXJzVG9QaXhlbHNZICsgMC41Zik7Ci0JCQltQml0bWFwID0gQml0bWFwCi0JCQkJCS5jcmVhdGVTY2FsZWRCaXRtYXAoYmFsbCwgZHN0V2lkdGgsIGRzdEhlaWdodCwgdHJ1ZSk7CisgICAgICAgICAgICBEaXNwbGF5TWV0cmljcyBtZXRyaWNzID0gbmV3IERpc3BsYXlNZXRyaWNzKCk7CisgICAgICAgICAgICBnZXRXaW5kb3dNYW5hZ2VyKCkuZ2V0RGVmYXVsdERpc3BsYXkoKS5nZXRNZXRyaWNzKG1ldHJpY3MpOworICAgICAgICAgICAgbVhEcGkgPSBtZXRyaWNzLnhkcGk7CisgICAgICAgICAgICBtWURwaSA9IG1ldHJpY3MueWRwaTsKKyAgICAgICAgICAgIG1NZXRlcnNUb1BpeGVsc1ggPSBtWERwaSAvIDAuMDI1NGY7CisgICAgICAgICAgICBtTWV0ZXJzVG9QaXhlbHNZID0gbVlEcGkgLyAwLjAyNTRmOwogCi0JCQlPcHRpb25zIG9wdHMgPSBuZXcgT3B0aW9ucygpOwotCQkJb3B0cy5pbkRpdGhlciA9IHRydWU7Ci0JCQlvcHRzLmluUHJlZmVycmVkQ29uZmlnID0gQml0bWFwLkNvbmZpZy5SR0JfNTY1OwotCQkJbVdvb2QgPSBCaXRtYXBGYWN0b3J5LmRlY29kZVJlc291cmNlKGdldFJlc291cmNlcygpLAotCQkJCQlSLmRyYXdhYmxlLndvb2QsIG9wdHMpOwotCQl9CisgICAgICAgICAgICAvLyByZXNjYWxlIHRoZSBiYWxsIHNvIGl0J3MgYWJvdXQgMC41IGNtIG9uIHNjcmVlbgorICAgICAgICAgICAgQml0bWFwIGJhbGwgPSBCaXRtYXBGYWN0b3J5LmRlY29kZVJlc291cmNlKGdldFJlc291cmNlcygpLCBSLmRyYXdhYmxlLmJhbGwpOworICAgICAgICAgICAgZmluYWwgaW50IGRzdFdpZHRoID0gKGludCkgKHNCYWxsRGlhbWV0ZXIgKiBtTWV0ZXJzVG9QaXhlbHNYICsgMC41Zik7CisgICAgICAgICAgICBmaW5hbCBpbnQgZHN0SGVpZ2h0ID0gKGludCkgKHNCYWxsRGlhbWV0ZXIgKiBtTWV0ZXJzVG9QaXhlbHNZICsgMC41Zik7CisgICAgICAgICAgICBtQml0bWFwID0gQml0bWFwLmNyZWF0ZVNjYWxlZEJpdG1hcChiYWxsLCBkc3RXaWR0aCwgZHN0SGVpZ2h0LCB0cnVlKTsKIAotCQlAT3ZlcnJpZGUKLQkJcHJvdGVjdGVkIHZvaWQgb25TaXplQ2hhbmdlZChpbnQgdywgaW50IGgsIGludCBvbGR3LCBpbnQgb2xkaCkgewotCQkJLy8gY29tcHV0ZSB0aGUgb3JpZ2luIG9mIHRoZSBzY3JlZW4gcmVsYXRpdmUgdG8gdGhlIG9yaWdpbiBvZgotCQkJLy8gdGhlIGJpdG1hcAotCQkJbVhPcmlnaW4gPSAodyAtIG1CaXRtYXAuZ2V0V2lkdGgoKSkgKiAwLjVmOwotCQkJbVlPcmlnaW4gPSAoaCAtIG1CaXRtYXAuZ2V0SGVpZ2h0KCkpICogMC41ZjsKLQkJCW1Ib3Jpem9udGFsQm91bmQgPSAoKHcgLyBtTWV0ZXJzVG9QaXhlbHNYIC0gc0JhbGxEaWFtZXRlcikgKiAwLjVmKTsKLQkJCW1WZXJ0aWNhbEJvdW5kID0gKChoIC8gbU1ldGVyc1RvUGl4ZWxzWSAtIHNCYWxsRGlhbWV0ZXIpICogMC41Zik7Ci0JCX0KKyAgICAgICAgICAgIE9wdGlvbnMgb3B0cyA9IG5ldyBPcHRpb25zKCk7CisgICAgICAgICAgICBvcHRzLmluRGl0aGVyID0gdHJ1ZTsKKyAgICAgICAgICAgIG9wdHMuaW5QcmVmZXJyZWRDb25maWcgPSBCaXRtYXAuQ29uZmlnLlJHQl81NjU7CisgICAgICAgICAgICBtV29vZCA9IEJpdG1hcEZhY3RvcnkuZGVjb2RlUmVzb3VyY2UoZ2V0UmVzb3VyY2VzKCksIFIuZHJhd2FibGUud29vZCwgb3B0cyk7CisgICAgICAgIH0KIAotCQlAT3ZlcnJpZGUKLQkJcHVibGljIHZvaWQgb25TZW5zb3JDaGFuZ2VkKFNlbnNvckV2ZW50IGV2ZW50KSB7Ci0JCQlpZiAoZXZlbnQuc2Vuc29yLmdldFR5cGUoKSAhPSBTZW5zb3IuVFlQRV9BQ0NFTEVST01FVEVSKQotCQkJCXJldHVybjsKLQkJCS8qCi0JCQkgKiByZWNvcmQgdGhlIGFjY2VsZXJvbWV0ZXIgZGF0YSwgdGhlIGV2ZW50J3MgdGltZXN0YW1wIGFzIHdlbGwgYXMKLQkJCSAqIHRoZSBjdXJyZW50IHRpbWUuIFRoZSBsYXR0ZXIgaXMgbmVlZGVkIHNvIHdlIGNhbiBjYWxjdWxhdGUgdGhlCi0JCQkgKiAicHJlc2VudCIgdGltZSBkdXJpbmcgcmVuZGVyaW5nLgotCQkJICovCi0JCQltU2Vuc29yWCA9IGV2ZW50LnZhbHVlc1swXTsKLQkJCW1TZW5zb3JZID0gZXZlbnQudmFsdWVzWzFdOwotCQkJbVNlbnNvclRpbWVTdGFtcCA9IGV2ZW50LnRpbWVzdGFtcDsKLQkJCW1DcHVUaW1lU3RhbXAgPSBTeXN0ZW0ubmFub1RpbWUoKTsKLQkJfQorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgb25TaXplQ2hhbmdlZChpbnQgdywgaW50IGgsIGludCBvbGR3LCBpbnQgb2xkaCkgeworICAgICAgICAgICAgLy8gY29tcHV0ZSB0aGUgb3JpZ2luIG9mIHRoZSBzY3JlZW4gcmVsYXRpdmUgdG8gdGhlIG9yaWdpbiBvZgorICAgICAgICAgICAgLy8gdGhlIGJpdG1hcAorICAgICAgICAgICAgbVhPcmlnaW4gPSAodyAtIG1CaXRtYXAuZ2V0V2lkdGgoKSkgKiAwLjVmOworICAgICAgICAgICAgbVlPcmlnaW4gPSAoaCAtIG1CaXRtYXAuZ2V0SGVpZ2h0KCkpICogMC41ZjsKKyAgICAgICAgICAgIG1Ib3Jpem9udGFsQm91bmQgPSAoKHcgLyBtTWV0ZXJzVG9QaXhlbHNYIC0gc0JhbGxEaWFtZXRlcikgKiAwLjVmKTsKKyAgICAgICAgICAgIG1WZXJ0aWNhbEJvdW5kID0gKChoIC8gbU1ldGVyc1RvUGl4ZWxzWSAtIHNCYWxsRGlhbWV0ZXIpICogMC41Zik7CisgICAgICAgIH0KIAotCQlAT3ZlcnJpZGUKLQkJcHJvdGVjdGVkIHZvaWQgb25EcmF3KENhbnZhcyBjYW52YXMpIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIG9uU2Vuc29yQ2hhbmdlZChTZW5zb3JFdmVudCBldmVudCkgeworICAgICAgICAgICAgaWYgKGV2ZW50LnNlbnNvci5nZXRUeXBlKCkgIT0gU2Vuc29yLlRZUEVfQUNDRUxFUk9NRVRFUikKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogcmVjb3JkIHRoZSBhY2NlbGVyb21ldGVyIGRhdGEsIHRoZSBldmVudCdzIHRpbWVzdGFtcCBhcyB3ZWxsIGFzCisgICAgICAgICAgICAgKiB0aGUgY3VycmVudCB0aW1lLiBUaGUgbGF0dGVyIGlzIG5lZWRlZCBzbyB3ZSBjYW4gY2FsY3VsYXRlIHRoZQorICAgICAgICAgICAgICogInByZXNlbnQiIHRpbWUgZHVyaW5nIHJlbmRlcmluZy4gSW4gdGhpcyBhcHBsaWNhdGlvbiwgd2UgbmVlZCB0bworICAgICAgICAgICAgICogdGFrZSBpbnRvIGFjY291bnQgaG93IHRoZSBzY3JlZW4gaXMgcm90YXRlZCB3aXRoIHJlc3BlY3QgdG8gdGhlCisgICAgICAgICAgICAgKiBzZW5zb3JzICh3aGljaCBhbHdheXMgcmV0dXJuIGRhdGEgaW4gYSBjb29yZGluYXRlIHNwYWNlIGFsaWduZWQKKyAgICAgICAgICAgICAqIHRvIHdpdGggdGhlIHNjcmVlbiBpbiBpdHMgbmF0aXZlIG9yaWVudGF0aW9uKS4KKyAgICAgICAgICAgICAqLwogCi0JCQkvKgotCQkJICogZHJhdyB0aGUgYmFja2dyb3VuZAotCQkJICovCisgICAgICAgICAgICBzd2l0Y2ggKG1EaXNwbGF5LmdldFJvdGF0aW9uKCkpIHsKKyAgICAgICAgICAgICAgICBjYXNlIFN1cmZhY2UuUk9UQVRJT05fMDoKKyAgICAgICAgICAgICAgICAgICAgbVNlbnNvclggPSBldmVudC52YWx1ZXNbMF07CisgICAgICAgICAgICAgICAgICAgIG1TZW5zb3JZID0gZXZlbnQudmFsdWVzWzFdOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIFN1cmZhY2UuUk9UQVRJT05fOTA6CisgICAgICAgICAgICAgICAgICAgIG1TZW5zb3JYID0gLWV2ZW50LnZhbHVlc1sxXTsKKyAgICAgICAgICAgICAgICAgICAgbVNlbnNvclkgPSBldmVudC52YWx1ZXNbMF07CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgU3VyZmFjZS5ST1RBVElPTl8xODA6CisgICAgICAgICAgICAgICAgICAgIG1TZW5zb3JYID0gLWV2ZW50LnZhbHVlc1swXTsKKyAgICAgICAgICAgICAgICAgICAgbVNlbnNvclkgPSAtZXZlbnQudmFsdWVzWzFdOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIFN1cmZhY2UuUk9UQVRJT05fMjcwOgorICAgICAgICAgICAgICAgICAgICBtU2Vuc29yWCA9IGV2ZW50LnZhbHVlc1sxXTsKKyAgICAgICAgICAgICAgICAgICAgbVNlbnNvclkgPSAtZXZlbnQudmFsdWVzWzBdOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KIAotCQkJY2FudmFzLmRyYXdCaXRtYXAobVdvb2QsIDAsIDAsIG51bGwpOworICAgICAgICAgICAgbVNlbnNvclRpbWVTdGFtcCA9IGV2ZW50LnRpbWVzdGFtcDsKKyAgICAgICAgICAgIG1DcHVUaW1lU3RhbXAgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICAgICAgfQogCi0JCQkvKgotCQkJICogY29tcHV0ZSB0aGUgbmV3IHBvc2l0aW9uIG9mIG91ciBvYmplY3QsIGJhc2VkIG9uIGFjY2VsZXJvbWV0ZXIKLQkJCSAqIGRhdGEgYW5kIHByZXNlbnQgdGltZS4KLQkJCSAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgb25EcmF3KENhbnZhcyBjYW52YXMpIHsKIAotCQkJZmluYWwgUGFydGljbGVTeXN0ZW0gcGFydGljbGVTeXN0ZW0gPSBtUGFydGljbGVTeXN0ZW07Ci0JCQlmaW5hbCBsb25nIG5vdyA9IG1TZW5zb3JUaW1lU3RhbXAKLQkJCQkJKyAoU3lzdGVtLm5hbm9UaW1lKCkgLSBtQ3B1VGltZVN0YW1wKTsKLQkJCWZpbmFsIGZsb2F0IHN4ID0gbVNlbnNvclg7Ci0JCQlmaW5hbCBmbG9hdCBzeSA9IG1TZW5zb3JZOworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIGRyYXcgdGhlIGJhY2tncm91bmQKKyAgICAgICAgICAgICAqLwogCi0JCQlwYXJ0aWNsZVN5c3RlbS51cGRhdGUoc3gsIHN5LCBub3cpOworICAgICAgICAgICAgY2FudmFzLmRyYXdCaXRtYXAobVdvb2QsIDAsIDAsIG51bGwpOwogCi0JCQlmaW5hbCBmbG9hdCB4YyA9IG1YT3JpZ2luOwotCQkJZmluYWwgZmxvYXQgeWMgPSBtWU9yaWdpbjsKLQkJCWZpbmFsIGZsb2F0IHhzID0gbU1ldGVyc1RvUGl4ZWxzWDsKLQkJCWZpbmFsIGZsb2F0IHlzID0gbU1ldGVyc1RvUGl4ZWxzWTsKLQkJCWZpbmFsIEJpdG1hcCBiaXRtYXAgPSBtQml0bWFwOwotCQkJZmluYWwgaW50IGNvdW50ID0gcGFydGljbGVTeXN0ZW0uZ2V0UGFydGljbGVDb3VudCgpOwotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0JCQkJLyoKLQkJCQkgKiBXZSB0cmFuc2Zvcm0gdGhlIGNhbnZhcyBzbyB0aGF0IHRoZSBjb29yZGluYXRlIHN5c3RlbSBtYXRjaGVzCi0JCQkJICogdGhlIHNlbnNvcnMgY29vcmRpbmF0ZSBzeXN0ZW0gd2l0aCB0aGUgb3JpZ2luIGluIHRoZSBjZW50ZXIKLQkJCQkgKiBvZiB0aGUgc2NyZWVuIGFuZCB0aGUgdW5pdCBpcyB0aGUgbWV0ZXIuCi0JCQkJICovCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogY29tcHV0ZSB0aGUgbmV3IHBvc2l0aW9uIG9mIG91ciBvYmplY3QsIGJhc2VkIG9uIGFjY2VsZXJvbWV0ZXIKKyAgICAgICAgICAgICAqIGRhdGEgYW5kIHByZXNlbnQgdGltZS4KKyAgICAgICAgICAgICAqLwogCi0JCQkJZmluYWwgZmxvYXQgeCA9IHhjICsgcGFydGljbGVTeXN0ZW0uZ2V0UG9zWChpKSAqIHhzOwotCQkJCWZpbmFsIGZsb2F0IHkgPSB5YyAtIHBhcnRpY2xlU3lzdGVtLmdldFBvc1koaSkgKiB5czsKLQkJCQljYW52YXMuZHJhd0JpdG1hcChiaXRtYXAsIHgsIHksIG51bGwpOwotCQkJfQorICAgICAgICAgICAgZmluYWwgUGFydGljbGVTeXN0ZW0gcGFydGljbGVTeXN0ZW0gPSBtUGFydGljbGVTeXN0ZW07CisgICAgICAgICAgICBmaW5hbCBsb25nIG5vdyA9IG1TZW5zb3JUaW1lU3RhbXAgKyAoU3lzdGVtLm5hbm9UaW1lKCkgLSBtQ3B1VGltZVN0YW1wKTsKKyAgICAgICAgICAgIGZpbmFsIGZsb2F0IHN4ID0gbVNlbnNvclg7CisgICAgICAgICAgICBmaW5hbCBmbG9hdCBzeSA9IG1TZW5zb3JZOwogCi0JCQkvLyBhbmQgbWFrZSBzdXJlIHRvIHJlZHJhdyBhc2FwCi0JCQlpbnZhbGlkYXRlKCk7Ci0JCX0KKyAgICAgICAgICAgIHBhcnRpY2xlU3lzdGVtLnVwZGF0ZShzeCwgc3ksIG5vdyk7CiAKLQkJQE92ZXJyaWRlCi0JCXB1YmxpYyB2b2lkIG9uQWNjdXJhY3lDaGFuZ2VkKFNlbnNvciBzZW5zb3IsIGludCBhY2N1cmFjeSkgewotCQl9Ci0JfQorICAgICAgICAgICAgZmluYWwgZmxvYXQgeGMgPSBtWE9yaWdpbjsKKyAgICAgICAgICAgIGZpbmFsIGZsb2F0IHljID0gbVlPcmlnaW47CisgICAgICAgICAgICBmaW5hbCBmbG9hdCB4cyA9IG1NZXRlcnNUb1BpeGVsc1g7CisgICAgICAgICAgICBmaW5hbCBmbG9hdCB5cyA9IG1NZXRlcnNUb1BpeGVsc1k7CisgICAgICAgICAgICBmaW5hbCBCaXRtYXAgYml0bWFwID0gbUJpdG1hcDsKKyAgICAgICAgICAgIGZpbmFsIGludCBjb3VudCA9IHBhcnRpY2xlU3lzdGVtLmdldFBhcnRpY2xlQ291bnQoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogV2UgdHJhbnNmb3JtIHRoZSBjYW52YXMgc28gdGhhdCB0aGUgY29vcmRpbmF0ZSBzeXN0ZW0gbWF0Y2hlcworICAgICAgICAgICAgICAgICAqIHRoZSBzZW5zb3JzIGNvb3JkaW5hdGUgc3lzdGVtIHdpdGggdGhlIG9yaWdpbiBpbiB0aGUgY2VudGVyCisgICAgICAgICAgICAgICAgICogb2YgdGhlIHNjcmVlbiBhbmQgdGhlIHVuaXQgaXMgdGhlIG1ldGVyLgorICAgICAgICAgICAgICAgICAqLworCisgICAgICAgICAgICAgICAgZmluYWwgZmxvYXQgeCA9IHhjICsgcGFydGljbGVTeXN0ZW0uZ2V0UG9zWChpKSAqIHhzOworICAgICAgICAgICAgICAgIGZpbmFsIGZsb2F0IHkgPSB5YyAtIHBhcnRpY2xlU3lzdGVtLmdldFBvc1koaSkgKiB5czsKKyAgICAgICAgICAgICAgICBjYW52YXMuZHJhd0JpdG1hcChiaXRtYXAsIHgsIHksIG51bGwpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBhbmQgbWFrZSBzdXJlIHRvIHJlZHJhdyBhc2FwCisgICAgICAgICAgICBpbnZhbGlkYXRlKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgb25BY2N1cmFjeUNoYW5nZWQoU2Vuc29yIHNlbnNvciwgaW50IGFjY3VyYWN5KSB7CisgICAgICAgIH0KKyAgICB9CiB9CmRpZmYgLS1naXQgYS9zYW1wbGVzL0FjY2Vzc2liaWxpdHlTZXJ2aWNlL0FuZHJvaWQubWsgYi9zYW1wbGVzL0FjY2Vzc2liaWxpdHlTZXJ2aWNlL0FuZHJvaWQubWsKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTQ3YjZmNgotLS0gL2Rldi9udWxsCisrKyBiL3NhbXBsZXMvQWNjZXNzaWJpbGl0eVNlcnZpY2UvQW5kcm9pZC5tawpAQCAtMCwwICsxLDEyIEBACitMT0NBTF9QQVRIOj0gJChjYWxsIG15LWRpcikKK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCitMT0NBTF9NT0RVTEVfVEFHUyA6PSBzYW1wbGVzCisKK0xPQ0FMX1NSQ19GSUxFUyA6PSAkKGNhbGwgYWxsLXN1YmRpci1qYXZhLWZpbGVzKQorCitMT0NBTF9QQUNLQUdFX05BTUUgOj0gQWNjZXNzaWJpbGl0eVNlcnZpY2UKKworTE9DQUxfU0RLX1ZFUlNJT04gOj0gY3VycmVudAorCitpbmNsdWRlICQoQlVJTERfUEFDS0FHRSkKZGlmZiAtLWdpdCBhL3NhbXBsZXMvQWNjZXNzaWJpbGl0eVNlcnZpY2UvQW5kcm9pZE1hbmlmZXN0LnhtbCBiL3NhbXBsZXMvQWNjZXNzaWJpbGl0eVNlcnZpY2UvQW5kcm9pZE1hbmlmZXN0LnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYjVmNzk0Ci0tLSAvZGV2L251bGwKKysrIGIvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9BbmRyb2lkTWFuaWZlc3QueG1sCkBAIC0wLDAgKzEsNDAgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9InV0Zi04Ij8+CisKKzwhLS0gQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKworICAgICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAgICAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICAgICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKworPG1hbmlmZXN0IHhtbG5zOmFuZHJvaWQ9Imh0dHA6Ly9zY2hlbWFzLmFuZHJvaWQuY29tL2Fway9yZXMvYW5kcm9pZCIKKyAgICAgIHBhY2thZ2U9ImNvbS5leGFtcGxlLmFuZHJvaWQuY2xvY2tiYWNrIgorICAgICAgYW5kcm9pZDp2ZXJzaW9uQ29kZT0iMSIKKyAgICAgIGFuZHJvaWQ6dmVyc2lvbk5hbWU9IjEuMCI+CisKKyAgICA8dXNlcy1wZXJtaXNzaW9uIGFuZHJvaWQ6bmFtZT0iYW5kcm9pZC5wZXJtaXNzaW9uLlZJQlJBVEUiIC8+CisKKyAgICA8YXBwbGljYXRpb24gYW5kcm9pZDpsYWJlbD0iQHN0cmluZy9jbG9ja2JhY2tfc2V0dXBfdGl0bGUiPgorCisgICAgICAgIDwhLS0gV2UgZGVjbGFyZSBvdXIgc2VydmljZSBoZXJlIC0tPgorICAgICAgICA8c2VydmljZSBhbmRyb2lkOm5hbWU9Ii5DbG9ja0JhY2tTZXJ2aWNlIj4KKyAgICAgICAgICAgIDwhLS0gVGhpcyBpbnRlbnQgZmlsdGVyIGlzIGEgY2x1ZSBmb3IgdGhlIHN5c3RlbSB0aGF0IHRoaXMgaXMgYW4gYWNjZXNzaWJpbGl0eSBzZXJ2aWNlIC0tPgorICAgICAgICAgICAgPGludGVudC1maWx0ZXI+CisgICAgICAgICAgICAgICAgPGFjdGlvbiBhbmRyb2lkOm5hbWU9ImFuZHJvaWQuYWNjZXNzaWJpbGl0eXNlcnZpY2UuQWNjZXNzaWJpbGl0eVNlcnZpY2UiIC8+CisgICAgICAgICAgICA8L2ludGVudC1maWx0ZXI+CisgICAgICAgIDwvc2VydmljZT4KKworICAgIDwvYXBwbGljYXRpb24+CisKKyAgICA8IS0tIEFjY2Vzc2liaWxpdHkgQVBJIGFwcGVhcmVkIGluIFNESyB2ZXJzaW9uIDQgKEFuZHJvaWQgMS42KSAtLT4KKyAgICA8dXNlcy1zZGsgYW5kcm9pZDptaW5TZGtWZXJzaW9uPSI0IiAvPgorCis8L21hbmlmZXN0PgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9faW5kZXguaHRtbCBiL3NhbXBsZXMvQWNjZXNzaWJpbGl0eVNlcnZpY2UvX2luZGV4Lmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDZhZGJmMgotLS0gL2Rldi9udWxsCisrKyBiL3NhbXBsZXMvQWNjZXNzaWJpbGl0eVNlcnZpY2UvX2luZGV4Lmh0bWwKQEAgLTAsMCArMSwxMjAgQEAKKzxwPgorICBUaGlzIGlzIGFuIGV4YW1wbGUgb2YgYW4gYWNjZXNzaWJpbGl0eSBzZXJ2aWNlIHRoYXQgcHJvdmlkZXMgY3VzdG9tIGZlZWRiYWNrIGZvciB0aGUgQ2xvY2sgYXBwbGljYXRpb24gd2hpY2ggY29tZXMgYnkgZGVmYXVsdCB3aXRoIEFuZHJvaWQgZGV2aWNlcy4gSXQgZGVtb25zdHJhdGVzIHRoZSBmb2xsb3dpbmcga2V5IGZlYXR1cmVzIG9mIHRoZSBBbmRyb2lkIGFjY2Vzc2liaWxpdHkgQVBJczoKKzwvcD4KKzxvbD4KKyAgPGxpPgorICAgIFNpbXBsZSBkZW1vbnN0cmF0aW9uIG9mIGhvdyB0byB1c2UgdGhlIGFjY2Vzc2liaWxpdHkgQVBJcy4KKyAgPC9saT4KKyAgPGxpPgorICAgIEhhbmRzLW9uIGV4YW1wbGUgb2YgdmFyaW91cyB3YXlzIHRvIHV0aWxpemUgdGhlIGFjY2Vzc2liaWxpdHkgQVBJIGZvciBwcm92aWRpbmcgYWx0ZXJuYXRpdmUgYW5kIGNvbXBsZW1lbnRhcnkgZmVlZGJhY2suCisgIDwvbGk+CisgIDxsaT4KKyAgICBQcm92aWRpbmcgYXBwbGljYXRpb24gc3BlY2lmaWMgZmVlZGJhY2sgJm1kYXNoOyB0aGUgc2VydmljZSBoYW5kbGVzIG9ubHkgYWNjZXNzaWJpbGl0eSBldmVudHMgZnJvbSB0aGUgQ2xvY2sgYXBwbGljYXRpb24uCisgIDwvbGk+CisgIDxsaT4KKyAgICBQcm92aWRpbmcgZHluYW1pYywgY29udGV4dC1kZXBlbmRlbnQgZmVlZGJhY2sgJm1kYXNoOyBmZWVkYmFjayB0eXBlIGNoYW5nZXMgZGVwZW5kaW5nIG9uIHRoZSByaW5nZXIgbW9kZS4KKyAgPC9saT4KKyAgPGxpPgorICAgIEFwcGxpY2F0aW9uIHNwZWNpZmljIFVJIGVuaGFuY2VtZW50ICZtZGFzaDsgYXBwbGljYXRpb24gZG9tYWluIGtub3dsZWRnZSBpcyB1dGlsaXplZCB0byBlbmhhbmNlIHRoZSBwcm92aWRlZCBmZWVkYmFjay4KKyAgPC9saT4KKzwvb2w+Cis8cD4KKyAgPHN0cm9uZz4KKyAgICBOb3RlOiBUaGlzIGNvZGUgc2FtcGxlIHdpbGwgd29yayBvbmx5IG9uIGRldmljZXMgc2hpcHBlZCB3aXRoIHRoZSBkZWZhdWx0IENsb2NrIGFwcGxpY2F0aW9uLiBJZiB5b3UgYXJlCisgICAgcnVubmluZyBBbmRyb2lkIDEuNiBvZiBBbmRyb2lkIDIuMCB5b3Ugc2hvdWxkIGVuYWJsZSBmaXJzdCBDbG9ja0JhY2sgYW5kIHRoZW4gVGFsa0JhY2sgc2luY2UgaW4gdGhlc2UKKyAgICByZWxlYXNlcyBhY2Nlc3NpYmlsaXR5IHNlcnZpY2VzIGFyZSBub3RpZmllZCBpbiB0aGUgb3JkZXIgb2YgcmVnaXN0cmF0aW9uLgorICA8L3N0cm9uZz4KKzwvcD4KKzxwPgorICBTdGVwcyB0byBleGVyY2lzZSB0aGUgQ2xvY2tCYWNrIGV4YW1wbGU6Cis8L3A+Cis8b2w+CisgIDxsaT4KKyAgICA8dWw+CisgICAgICA8bGk+CisgICAgICAgIDxzdHJvbmc+QWN0aW9uOjwvc3Ryb25nPiBFbmFibGUgYWNjZXNzaWJpbGl0eSBhbmQgYWxsIGRlZmF1bHQgYWNjZXNzaWJpbGl0eSBzZXJ2aWNlczo8YnIvPgorICAgICAgICBTZXR0aW5ncyAmcmFycjsgQWNjZXNzaWJpbGl0eSAmcmFycjsgc2VsZWN0IHRoZSBBY2Nlc3NpYmlsaXR5LCBUYWxrQmFjaywgS2lja0JhY2ssIGFuZCBTb3VuZEJhY2sgY2hlY2tib3hlcworICAgICAgPC9saT4KKyAgICAgIDxsaT4KKyAgICAgICAgPHN0cm9uZz5SZXN1bHQ6PC9zdHJvbmc+IFRoZSBzeXN0ZW0gcHJvdmlkZXMgc3Bva2VuLCBhdWRpYmxlLCBhbmQgaGFwdGljIGZlZWRiYWNrLgorICAgICAgPC9saT4KKyAgICA8L3VsPgorICA8L2xpPgorICA8bGk+CisgICAgPHVsPgorICAgICAgPGxpPgorICAgICAgICA8c3Ryb25nPkFjdGlvbjo8L3N0cm9uZz4gRXhwbG9yZSB0aGUgZmVlZGJhY2sgcHJvdmlkZWQgYnkgdGhlIHN5c3RlbTo8YnIvPgorICAgICAgICBQb2tlIGFyb3VuZCB3aXRoIHRoZSB0cmFja2JhbGwuCisgICAgICA8L2xpPgorICAgICAgPGxpPgorICAgICAgICA8c3Ryb25nPlJlc3VsdDo8L3N0cm9uZz4gWW91IGFyZSBzb21laG93IGZhbWlsaWFyIHdpdGggdGhlIHR5cGUgb2YgdGhlIHByb3ZpZGVkIGZlZWRiYWNrLgorICAgICAgPC9saT4KKyAgICA8L3VsPgorICA8L2xpPgorICA8bGk+CisgICAgPHVsPgorICAgICAgPGxpPgorICAgICAgICA8c3Ryb25nPkFjdGlvbjo8L3N0cm9uZz4gR28gdG8gdGhlIENsb2NrIGFwcGxpY2F0aW9uIGFuZCB0cnkgdG8gY2hhbmdlIHRoZSB0aW1lIG9mIGFuIGFsYXJtOjxici8+CisgICAgICAgIEFsbCBhcHBsaWNhdGlvbnMgJnJhcnI7IENsb2NrICZyYXJyOyBBbGFybXMgKGxlZnQgY29ybmVyKSAmcmFycjsgU2VsZWN0IGFuIGFsYXJtICZyYXJyOyBUaW1lICZtZGFzaDsgZXhwbG9yZSB0aGUgcGx1cywgbWludXMgYnV0dG9ucywgaG91ciBhbmQgbWludXRlIGVkaXQgYm94ZXMuCisgICAgICA8L2xpPgorICAgICAgPGxpPgorICAgICAgICA8c3Ryb25nPlJlc3VsdDo8L3N0cm9uZz4gVGhlIGhvdXIgYW5kIG1pbnV0ZSBlZGl0IGJveGVzIGFyZSBhbm5vdW5jZWQgd2l0aG91dCBhbnkgY2x1ZSB3aGljaCBpcyB0aGUgaG91ciBhbmQgd2hpY2ggaXMgdGhlIG1pbnV0ZSBvbmUgKHlvdSBjYW4gZ3Vlc3MgZnJvbSB0aGUgYXJyYW5nZW1lbnQpLgorICAgICAgPC9saT4KKyAgICA8L3VsPgorICA8L2xpPgorICA8bGk+CisgICAgPHVsPgorICAgICAgPGxpPgorICAgICAgICA8c3Ryb25nPkFjdGlvbjo8L3N0cm9uZz4gRW5hYmxlIENsb2NrQmFjazo8YnI+CisgICAgICAgIFNldHRpbmdzICZyYXJyOyBBY2Nlc3NpYmlsaXR5ICZyYXJyOyBDbG9ja0JhY2sgJm1kYXNoOyBzZWxlY3QgdGhlIGNoZWNrYm94IChhc3N1bWluZyB5b3UgaGF2ZSBpbnN0YWxsZWQgdGhlIEFQSykuCisgICAgICA8L2xpPgorICAgICAgPGxpPgorICAgICAgICA8c3Ryb25nPlJlc3VsdDo8L3N0cm9uZz4gV2UgaGF2ZSBhY3RpdmUgYWNjZXNzaWJpbGl0eSBzZXJ2aWNlIGZvciBwcm92aWRpbmcgYXBwbGljYXRpb24gc3BlY2lmaWMgZmVlZGJhY2sgZm9yIHRoZSBDbG9jayBhcHBsaWNhdGlvbi4KKyAgICAgIDwvbGk+CisgICAgPC91bD4KKyAgPC9saT4KKyAgPGxpPgorICAgIDx1bD4KKyAgICAgIDxsaT4KKyAgICAgICAgPHN0cm9uZz5BY3Rpb246PC9zdHJvbmc+IEdvIHRvIHRoZSBDbG9jayBhcHBsaWNhdGlvbiBhbmQgdHJ5IHRvIGNoYW5nZSB0aGUgdGltZSBvZiBhbiBhbGFybTo8YnIvPgorICAgICAgICBBbGwgYXBwbGljYXRpb25zICZyYXJyOyBDbG9jayAmcmFycjsgQWxhcm1zIChsZWZ0IGNvcm5lcikgJnJhcnI7IFNlbGVjdCBhbiBhbGFybSAmcmFycjsgVGltZSAmbWRhc2g7IGV4cGxvcmUgdGhlIGhvdXIgYW5kIG1pbnV0ZSBlZGl0IGJveGVzLgorICAgICAgPC9saT4KKyAgICAgIDxsaT4KKyAgICAgICAgPHN0cm9uZz5SZXN1bHQ6PC9zdHJvbmc+IFRoZSBob3VyIGFuZCBtaW51dGUgZWRpdCBib3hlcyBhcmUgbm93IHNwb2tlbi4gVGhpcyBpcyBhbiBleGFtcGxlIG9mIGFwcGxpY2F0aW9uIHNwZWNpZmljIGZlZWRiYWNrIHRoYXQgdXRpbGl6ZXMgZG9tYWluIGluZm9ybWF0aW9uIHRvIGVuaGFuY2UgdGhlIHVzZXIgZXhwZXJpZW5jZS4KKyAgICAgIDwvbGk+CisgICAgPC91bD4KKyAgPC9saT4KKyAgPGxpPgorICAgIDx1bD4KKyAgICAgIDxsaT4KKyAgICAgICAgPHN0cm9uZz5BY3Rpb246PC9zdHJvbmc+IFNldCB0aGUgcmluZ2VyIHRvIHZpYnJhdGlvbiBtb2RlIGFuZCBleHBsb3JlIHRoZSBwcm92aWRlZCBmZWVkYmFjazo8YnIvPgorICAgICAgICBVc2UgdGhlIGRldmljZSBidXR0b24gZm9yIHJlZHVjaW5nIHRoZSByaW5nZXIgdm9sdW1lIHVudGlsIGl0IGlzIGluIHZpYnJhdGlvbiBtb2RlLiBNb3ZlIGFyb3VuZCB0aGUgQ2xvY2sgYXBwbGljYXRpb24gYW5kIG91dHNpZGUgb2YgdGhhdCBhcHBsaWNhdGlvbi4KKyAgICAgIDwvbGk+CisgICAgICA8bGk+CisgICAgICAgIDxzdHJvbmc+UmVzdWx0Ojwvc3Ryb25nPiBUaGUgQ2xvY2sgYXBwbGljYXRpb24gcHJvdmlkZXMgY3VzdG9tIGF1ZGlibGUgYW5kIGRlZmF1bHQgaGFwdGljIGZlZWRiYWNrLiBUaGUgcmVzdCBvZiB0aGUgc3lzdGVtIHByb3ZpZGVzIHRoZSBkZWZhdWx0IGZlZWRiYWNrLgorICAgICAgPC9saT4KKyAgICA8L3VsPgorICA8L2xpPgorICA8bGk+CisgICAgPHVsPgorICAgICAgPGxpPgorICAgICAgICA8c3Ryb25nPkFjdGlvbjo8L3N0cm9uZz4gU2V0IHRoZSByaW5nZXIgdG8gbXV0ZWQgbW9kZSBhbmQgZXhwbG9yZSB0aGUgcHJvdmlkZWQgZmVlZGJhY2s6PGJyLz4KKyAgICAgICAgVXNlIHRoZSBkZXZpY2UgYnV0dG9uIGZvciByZWR1Y2luZyB0aGUgcmluZ2VyIHZvbHVtZSB1bnRpbCBpdCBpcyBpbiBtdXRlZCBtb2RlLiBNb3ZlIGFyb3VuZCB0aGUgQ2xvY2sgYXBwbGljYXRpb24gYW5kIG91dHNpZGUgb2YgdGhhdCBhcHBsaWNhdGlvbi4KKyAgICAgIDwvbGk+CisgICAgICA8bGk+CisgICAgICAgIDxzdHJvbmc+UmVzdWx0Ojwvc3Ryb25nPiBUaGUgQ2xvY2sgYXBwbGljYXRpb24gcHJvdmlkZXMgb25seSBjdXN0b20gaGFwdGljIGZlZWRiYWNrLiBUaGUgcmVzdCBvZiB0aGUgc3lzdGVtIHByb3ZpZGVzIHRoZSBkZWZhdWx0IGZlZWRiYWNrLiBOb3cgd2UgYXJlIHByb3ZpZGluZyBjdXN0b20gY29udGV4dCBkZXBlbmRlbnQgZmVlZGJhY2sgYmFzZWQgb24gdGhlIGRldmljZSBzdGF0ZSAocmluZ2VyIG1vZGUpLgorICAgICAgPC9saT4KKyAgICA8L3VsPgorICA8L2xpPgorICA8bGk+CisgICAgPHVsPgorICAgICAgPGxpPgorICAgICAgICA8c3Ryb25nPkFjdGlvbjo8L3N0cm9uZz4gV3JpdGUgYW4gYWNjZXNzaWJpbGl0eSBzZXJ2aWNlOjxici8+CisgICAgICAgIFRoZSA8YSBocmVmPSJodHRwOi8vY29kZS5nb29nbGUuY29tL3AvZXllcy1mcmVlLyI+RXllcy1GcmVlIG9wZW4gc291cmNlIHByb2plY3Q8L2E+IGhhcyBtb3JlIGFjY2Vzc2liaWxpdHktcmVsYXRlZCByZXNvdXJjZXMuIFRvIGNvbnRyaWJ1dGUsIHZpc2l0IHRoZSBwcm9qZWN0IHBhZ2Ugb3IgcG9zdCB0byB0aGUgPGEgaHJlZj0iaHR0cDovL2dyb3Vwcy5nb29nbGUuY29tL2dyb3VwL2V5ZXMtZnJlZSI+bWFpbGluZyBsaXN0PC9hPi4KKyAgICAgIDwvbGk+CisgICAgICA8bGk+CisgICAgICAgIDxzdHJvbmc+UmVzdWx0Ojwvc3Ryb25nPiBPbmUgbW9yZSBjb29sIGFwcGxpY2F0aW9uIGhhcyBiZWVuIHdyaXR0ZW4uCisgICAgICA8L2xpPgorICAgIDwvdWw+CisgIDwvbGk+Cis8L29sPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3Jpbmdlcl9ub3JtYWwub2dnIGIvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3Jpbmdlcl9ub3JtYWwub2dnCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk1OWUzOTgKLS0tIC9kZXYvbnVsbAorKysgYi9zYW1wbGVzL0FjY2Vzc2liaWxpdHlTZXJ2aWNlL3Jlcy9yYXcvc291bmRfcmluZ2VyX25vcm1hbC5vZ2cKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3Jpbmdlcl9zaWxlbnQub2dnIGIvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3Jpbmdlcl9zaWxlbnQub2dnCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQzYmIyNWUKLS0tIC9kZXYvbnVsbAorKysgYi9zYW1wbGVzL0FjY2Vzc2liaWxpdHlTZXJ2aWNlL3Jlcy9yYXcvc291bmRfcmluZ2VyX3NpbGVudC5vZ2cKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3Jpbmdlcl92aWJyYXRlLm9nZyBiL3NhbXBsZXMvQWNjZXNzaWJpbGl0eVNlcnZpY2UvcmVzL3Jhdy9zb3VuZF9yaW5nZXJfdmlicmF0ZS5vZ2cKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzYxZTEwZgotLS0gL2Rldi9udWxsCisrKyBiL3NhbXBsZXMvQWNjZXNzaWJpbGl0eVNlcnZpY2UvcmVzL3Jhdy9zb3VuZF9yaW5nZXJfdmlicmF0ZS5vZ2cKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3NjcmVlbl9vZmYub2dnIGIvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3NjcmVlbl9vZmYub2dnCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0MjczM2EKLS0tIC9kZXYvbnVsbAorKysgYi9zYW1wbGVzL0FjY2Vzc2liaWxpdHlTZXJ2aWNlL3Jlcy9yYXcvc291bmRfc2NyZWVuX29mZi5vZ2cKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3NjcmVlbl9vbi5vZ2cgYi9zYW1wbGVzL0FjY2Vzc2liaWxpdHlTZXJ2aWNlL3Jlcy9yYXcvc291bmRfc2NyZWVuX29uLm9nZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZjM2MzJlCi0tLSAvZGV2L251bGwKKysrIGIvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3NjcmVlbl9vbi5vZ2cKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3ZpZXdfY2xpY2tlZC5vZ2cgYi9zYW1wbGVzL0FjY2Vzc2liaWxpdHlTZXJ2aWNlL3Jlcy9yYXcvc291bmRfdmlld19jbGlja2VkLm9nZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZmUyNWNmCi0tLSAvZGV2L251bGwKKysrIGIvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3ZpZXdfY2xpY2tlZC5vZ2cKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3ZpZXdfZm9jdXNlZF9vcl9zZWxlY3RlZC5vZ2cgYi9zYW1wbGVzL0FjY2Vzc2liaWxpdHlTZXJ2aWNlL3Jlcy9yYXcvc291bmRfdmlld19mb2N1c2VkX29yX3NlbGVjdGVkLm9nZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMTAwZDI3Ci0tLSAvZGV2L251bGwKKysrIGIvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3ZpZXdfZm9jdXNlZF9vcl9zZWxlY3RlZC5vZ2cKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvcmF3L3NvdW5kX3dpbmRvd19zdGF0ZV9jaGFuZ2VkLm9nZyBiL3NhbXBsZXMvQWNjZXNzaWJpbGl0eVNlcnZpY2UvcmVzL3Jhdy9zb3VuZF93aW5kb3dfc3RhdGVfY2hhbmdlZC5vZ2cKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGZlYzlkZQotLS0gL2Rldi9udWxsCisrKyBiL3NhbXBsZXMvQWNjZXNzaWJpbGl0eVNlcnZpY2UvcmVzL3Jhdy9zb3VuZF93aW5kb3dfc3RhdGVfY2hhbmdlZC5vZ2cKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvdmFsdWVzL3N0cmluZ3MueG1sIGIvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9yZXMvdmFsdWVzL3N0cmluZ3MueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE5OTEzYzIKLS0tIC9kZXYvbnVsbAorKysgYi9zYW1wbGVzL0FjY2Vzc2liaWxpdHlTZXJ2aWNlL3Jlcy92YWx1ZXMvc3RyaW5ncy54bWwKQEAgLTAsMCArMSw1MCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KKzxyZXNvdXJjZXM+CisKKyAgICA8IS0tIFZBTFVFUyAtLT4KKworICAgIDwhLS0gU2V0dGluZyB1cCB0aGUgdXNlciBpbnRlcmZhY2UgdmlicmF0aW9uIGZlZWRiYWNrIHNlcnZpY2UgLS0+CisgICAgPHN0cmluZyBuYW1lPSJjbG9ja2JhY2tfc2V0dXBfdGl0bGUiPkNsb2NrQmFjazwvc3RyaW5nPgorCisgICAgPCEtLSBTdHJpbmcgdmFsdWUgZm9yIGFubm91bmNpbmcgdGhlIGluY3JlYXNlIGhvdXJzIGJ1dHRvbnMgLS0+CisgICAgPHN0cmluZyBuYW1lPSJ2YWx1ZV9pbmNyZWFzZV9ob3VycyI+SW5jcmVhc2UgaG91cnM8L3N0cmluZz4KKworICAgIDwhLS0gU3RyaW5nIHZhbHVlIGZvciBhbm5vdW5jaW5nIHRoZSBpbmNyZWFzZSBtaW51dGVzIGJ1dHRvbnMgLS0+CisgICAgPHN0cmluZyBuYW1lPSJ2YWx1ZV9pbmNyZWFzZV9taW51dGVzIj5JbmNyZWFzZSBtaW51dGVzPC9zdHJpbmc+CisKKyAgICA8IS0tIFN0cmluZyB2YWx1ZSBmb3IgYW5ub3VuY2luZyB0aGUgZGVjcmVhc2UgaG91cnMgYnV0dG9ucyAtLT4KKyAgICA8c3RyaW5nIG5hbWU9InZhbHVlX2RlY3JlYXNlX2hvdXJzIj5EZWNyZWFzZSBob3Vyczwvc3RyaW5nPgorCisgICAgPCEtLSBTdHJpbmcgdmFsdWUgZm9yIGFubm91bmNpbmcgdGhlIGRlY3JlYXNlIG1pbnV0ZXMgYnV0dG9ucyAtLT4KKyAgICA8c3RyaW5nIG5hbWU9InZhbHVlX2RlY3JlYXNlX21pbnV0ZXMiPkRlY3JlYXNlIG1pbnV0ZXM8L3N0cmluZz4KKworICAgIDwhLS0gU3RyaW5nIHZhbHVlIGZvciBhbm5vdW5jaW5nIG9uZSBob3VyIGlucHV0IC0tPgorICAgIDxzdHJpbmcgbmFtZT0idmFsdWVfaG91ciI+aG91cjwvc3RyaW5nPgorCisgICAgPCEtLSBTdHJpbmcgdmFsdWUgZm9yIGFubm91bmNpbmcgdGhlIGhvdXJzIGlucHV0IC0tPgorICAgIDxzdHJpbmcgbmFtZT0idmFsdWVfaG91cnMiPmhvdXJzPC9zdHJpbmc+CisKKyAgICA8IS0tIFN0cmluZyB2YWx1ZSBmb3IgYW5ub3VuY2luZyBvbmUgbWludXRlIGlucHV0IC0tPgorICAgIDxzdHJpbmcgbmFtZT0idmFsdWVfbWludXRlIj5taW51dGU8L3N0cmluZz4KKworICAgIDwhLS0gU3RyaW5nIHZhbHVlIGZvciBhbm5vdW5jaW5nIHRoZSBtaW51dGVzIGlucHV0IC0tPgorICAgIDxzdHJpbmcgbmFtZT0idmFsdWVfbWludXRlcyI+bWludXRlczwvc3RyaW5nPgorCisgICAgPCEtLSBTdHJpbmcgdmFsdWUgZm9yIGFubm91bmNpbmcgYXVkaWJsZSByaW5nZXIgbW9kZSAtLT4KKyAgICA8c3RyaW5nIG5hbWU9InZhbHVlX3Jpbmdlcl9hdWRpYmxlIj5SaW5nZXIgYXVkaWJsZTwvc3RyaW5nPgorCisgICAgPCEtLSBTdHJpbmcgdmFsdWUgZm9yIGFubm91bmNpbmcgdmlicmF0aW5nIHJpbmdlciBtb2RlIC0tPgorICAgIDxzdHJpbmcgbmFtZT0idmFsdWVfcmluZ2VyX3ZpYnJhdGUiPlJpbmdlciB2aWJyYXRlPC9zdHJpbmc+CisKKyAgICA8IS0tIFN0cmluZyB2YWx1ZSBmb3IgYW5ub3VuY2luZyBzaWxlbnQgcmluZ2VyIG1vZGUtLT4KKyAgICA8c3RyaW5nIG5hbWU9InZhbHVlX3Jpbmdlcl9zaWxlbnQiPlJpbmdlciBzaWxlbnQ8L3N0cmluZz4KKworICAgIDwhLS0gVEVNUExBVEVTIC0tPgorCisgICAgPCEtLSBTdHJpbmcgdGVtcGxhdGUgZm9yIGFubm91bmNpbmcgdGhlIHNjcmVlbiBvbiAtLT4KKyAgICA8c3RyaW5nIG5hbWU9InRlbXBsYXRlX3NjcmVlbl9vbiI+U2NyZWVuIG9uLiBWb2x1bWUgJTEkcyBwZXJjZW50Ljwvc3RyaW5nPgorCisgICAgPCEtLSBTdHJpbmcgdGVtcGxhdGUgZm9yIGFubm91bmNpbmcgdGhlIHNjcmVlbiBvZmYgLS0+CisgICAgPHN0cmluZyBuYW1lPSJ0ZW1wbGF0ZV9zY3JlZW5fb2ZmIj5TY3JlZW4gb2ZmLiBWb2x1bWUgJTEkcyBwZXJjZW50Ljwvc3RyaW5nPgorCis8L3Jlc291cmNlcz4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvQWNjZXNzaWJpbGl0eVNlcnZpY2Uvc3JjL2NvbS9leGFtcGxlL2FuZHJvaWQvY2xvY2tiYWNrL0Nsb2NrQmFja1NlcnZpY2UuamF2YSBiL3NhbXBsZXMvQWNjZXNzaWJpbGl0eVNlcnZpY2Uvc3JjL2NvbS9leGFtcGxlL2FuZHJvaWQvY2xvY2tiYWNrL0Nsb2NrQmFja1NlcnZpY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NzQ2NzE2Ci0tLSAvZGV2L251bGwKKysrIGIvc2FtcGxlcy9BY2Nlc3NpYmlsaXR5U2VydmljZS9zcmMvY29tL2V4YW1wbGUvYW5kcm9pZC9jbG9ja2JhY2svQ2xvY2tCYWNrU2VydmljZS5qYXZhCkBAIC0wLDAgKzEsNzAxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBjb20uZXhhbXBsZS5hbmRyb2lkLmNsb2NrYmFjazsKKworaW1wb3J0IGFuZHJvaWQuYWNjZXNzaWJpbGl0eXNlcnZpY2UuQWNjZXNzaWJpbGl0eVNlcnZpY2U7CitpbXBvcnQgYW5kcm9pZC5hY2Nlc3NpYmlsaXR5c2VydmljZS5BY2Nlc3NpYmlsaXR5U2VydmljZUluZm87CitpbXBvcnQgYW5kcm9pZC5hcHAuU2VydmljZTsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQnJvYWRjYXN0UmVjZWl2ZXI7CitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkludGVudDsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuSW50ZW50RmlsdGVyOworaW1wb3J0IGFuZHJvaWQubWVkaWEuQXVkaW9NYW5hZ2VyOworaW1wb3J0IGFuZHJvaWQub3MuSGFuZGxlcjsKK2ltcG9ydCBhbmRyb2lkLm9zLk1lc3NhZ2U7CitpbXBvcnQgYW5kcm9pZC5vcy5WaWJyYXRvcjsKK2ltcG9ydCBhbmRyb2lkLnNwZWVjaC50dHMuVGV4dFRvU3BlZWNoOworaW1wb3J0IGFuZHJvaWQudXRpbC5Mb2c7CitpbXBvcnQgYW5kcm9pZC51dGlsLlNwYXJzZUFycmF5OworaW1wb3J0IGFuZHJvaWQudmlldy5hY2Nlc3NpYmlsaXR5LkFjY2Vzc2liaWxpdHlFdmVudDsKKworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgYW4ge0BsaW5rIEFjY2Vzc2liaWxpdHlTZXJ2aWNlfSB0aGF0IHByb3ZpZGVzIGN1c3RvbSBmZWVkYmFjaworICogZm9yIHRoZSBDbG9jayBhcHBsaWNhdGlvbiB0aGF0IGNvbWVzIGJ5IGRlZmF1bHQgd2l0aCBBbmRyb2lkIGRldmljZXMuIEl0CisgKiBkZW1vbnN0cmF0ZXMgdGhlIGZvbGxvd2luZyBrZXkgZmVhdHVyZXMgb2YgdGhlIEFuZHJvaWQgYWNjZXNzaWJpbGl0eSBBUElzOgorICogPG9sPgorICogICA8bGk+CisgKiAgICAgU2ltcGxlIGRlbW9uc3RyYXRpb24gb2YgaG93IHRvIHVzZSB0aGUgYWNjZXNzaWJpbGl0eSBBUElzLgorICogICA8L2xpPgorICogICA8bGk+CisgKiAgICAgSGFuZHMtb24gZXhhbXBsZSBvZiB2YXJpb3VzIHdheXMgdG8gdXRpbGl6ZSB0aGUgYWNjZXNzaWJpbGl0eSBBUEkgZm9yCisgKiAgICAgcHJvdmlkaW5nIGFsdGVybmF0aXZlIGFuZCBjb21wbGVtZW50YXJ5IGZlZWRiYWNrLgorICogICA8L2xpPgorICogICA8bGk+CisgKiAgICAgUHJvdmlkaW5nIGFwcGxpY2F0aW9uIHNwZWNpZmljIGZlZWRiYWNrICZtZGFzaDsgdGhlIHNlcnZpY2UgaGFuZGxlcyBvbmx5CisgKiAgICAgYWNjZXNzaWJpbGl0eSBldmVudHMgZnJvbSB0aGUgY2xvY2sgYXBwbGljYXRpb24uCisgKiAgIDwvbGk+CisgKiAgIDxsaT4KKyAqICAgICBQcm92aWRpbmcgZHluYW1pYywgY29udGV4dC1kZXBlbmRlbnQgZmVlZGJhY2sgJm1kYXNoOyBmZWVkYmFjayB0eXBlIGNoYW5nZXMKKyAqICAgICBkZXBlbmRpbmcgb24gdGhlIHJpbmdlciBzdGF0ZS4KKyAqICAgPC9saT4KKyAqICAgPGxpPgorICogICAgIEFwcGxpY2F0aW9uIHNwZWNpZmljIFVJIGVuaGFuY2VtZW50IC0gYXBwbGljYXRpb24gZG9tYWluIGtub3dsZWRnZSBpcworICogICAgIHV0aWxpemVkIHRvIGVuaGFuY2UgdGhlIHByb3ZpZGVkIGZlZWRiYWNrLgorICogICA8L2xpPgorICogPC9vbD4KKyAqIDxwPgorICogICA8c3Ryb25nPgorICogICAgIE5vdGU6IFRoaXMgY29kZSBzYW1wbGUgd2lsbCB3b3JrIG9ubHkgb24gZGV2aWNlcyBzaGlwcGVkIHdpdGggdGhlIGRlZmF1bHQgQ2xvY2sKKyAqICAgICBhcHBsaWNhdGlvbi4gSWYgeW91IGFyZSBydW5uaW5nIEFuZHJvaWQgMS42IG9mIEFuZHJvaWQgMi4wIHlvdSBzaG91bGQgZW5hYmxlIGZpcnN0CisgKiAgICAgQ2xvY2tCYWNrIGFuZCB0aGVuIFRhbGtCYWNrIHNpbmNlIGluIHRoZXNlIHJlbGVhc2VzIGFjY2Vzc2liaWxpdHkgc2VydmljZXMgYXJlCisgKiAgICAgbm90aWZpZWQgaW4gdGhlIG9yZGVyIG9mIHJlZ2lzdHJhdGlvbi4KKyAqICAgPC9zdHJvbmc+CisgKiA8L3A+CisgKi8KK3B1YmxpYyBjbGFzcyBDbG9ja0JhY2tTZXJ2aWNlIGV4dGVuZHMgQWNjZXNzaWJpbGl0eVNlcnZpY2UgeworCisgICAgLyoqIFRhZyBmb3IgbG9nZ2luZyBmcm9tIHRoaXMgc2VydmljZS4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9HX1RBRyA9ICJDbG9ja0JhY2tTZXJ2aWNlIjsKKworICAgIC8vIEZpZWxkcyBmb3IgY29uZmlndXJpbmcgaG93IHRoZSBzeXN0ZW0gaGFuZGxlcyB0aGlzIGFjY2Vzc2liaWxpdHkgc2VydmljZS4KKworICAgIC8qKiBNaW5pbWFsIHRpbWVvdXQgYmV0d2VlbiBhY2Nlc3NpYmlsaXR5IGV2ZW50cyB3ZSB3YW50IHRvIHJlY2VpdmUuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVWRU5UX05PVElGSUNBVElPTl9USU1FT1VUX01JTExJUyA9IDgwOworCisgICAgLyoqIFBhY2thZ2VzIHdlIGFyZSBpbnRlcmVzdGVkIGluLgorICAgICAqIDxwPgorICAgICAqICAgPHN0cm9uZz4KKyAgICAgKiAgIE5vdGU6IFRoaXMgY29kZSBzYW1wbGUgd2lsbCB3b3JrIG9ubHkgb24gZGV2aWNlcyBzaGlwcGVkIHdpdGggdGhlCisgICAgICogICBkZWZhdWx0IENsb2NrIGFwcGxpY2F0aW9uLgorICAgICAqICAgPC9zdHJvbmc+CisgICAgICogPC9wPgorICAgICAqLworICAgIC8vIFRoaXMgd29ya3Mgd2l0aCBBbGFybUNsb2NrIGFuZCBDbG9jayB3aG9zZSBwYWNrYWdlIG5hbWUgY2hhbmdlcyBpbiBkaWZmZXJlbnQgcmVsZWFzZXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBQQUNLQUdFX05BTUVTID0gbmV3IFN0cmluZ1tdIHsKKyAgICAgICAgICAgICJjb20uYW5kcm9pZC5hbGFybWNsb2NrIiwgImNvbS5nb29nbGUuYW5kcm9pZC5kZXNrY2xvY2siLCAiY29tLmFuZHJvaWQuZGVza2Nsb2NrIgorICAgIH07CisKKyAgICAvLyBNZXNzYWdlIHR5cGVzIHdlIGFyZSBwYXNzaW5nIGFyb3VuZC4KKworICAgIC8qKiBTcGVhay4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUVTU0FHRV9TUEVBSyA9IDE7CisKKyAgICAvKiogU3RvcCBzcGVha2luZy4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUVTU0FHRV9TVE9QX1NQRUFLID0gMjsKKworICAgIC8qKiBTdGFydCB0aGUgVFRTIHNlcnZpY2UuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1FU1NBR0VfU1RBUlRfVFRTID0gMzsKKworICAgIC8qKiBTdG9wIHRoZSBUVFMgc2VydmljZS4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUVTU0FHRV9TSFVURE9XTl9UVFMgPSA0OworCisgICAgLyoqIFBsYXkgYW4gZWFyY29uLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1BMQVlfRUFSQ09OID0gNTsKKworICAgIC8qKiBTdG9wIHBsYXlpbmcgYW4gZWFyY29uLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1NUT1BfUExBWV9FQVJDT04gPSA2OworCisgICAgLyoqIFZpYnJhdGUgYSBwYXR0ZXJuLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1ZJQlJBVEUgPSA3OworCisgICAgLyoqIFN0b3AgdmlicmF0aW5nLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1NUT1BfVklCUkFURSA9IDg7CisKKyAgICAvLyBTY3JlZW4gc3RhdGUgYnJvYWRjYXN0IHJlbGF0ZWQgY29uc3RhbnRzLgorCisgICAgLyoqIEZlZWRiYWNrIG1hcHBpbmcgaW5kZXggdXNlZCBhcyBhIGtleSBmb3IgdGhlIHNjcmVlbi1vbiBicm9hZGNhc3QuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOREVYX1NDUkVFTl9PTiA9IDB4MDAwMDAxMDA7CisKKyAgICAvKiogRmVlZGJhY2sgbWFwcGluZyBpbmRleCB1c2VkIGFzIGEga2V5IGZvciB0aGUgc2NyZWVuLW9mZiBicm9hZGNhc3QuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOREVYX1NDUkVFTl9PRkYgPSAweDAwMDAwMjAwOworCisgICAgLy8gUmluZ2VyIG1vZGUgY2hhbmdlIHJlbGF0ZWQgY29uc3RhbnRzLgorCisgICAgLyoqIEZlZWRiYWNrIG1hcHBpbmcgaW5kZXggdXNlZCBhcyBhIGtleSBmb3Igbm9ybWFsIHJpbmdlciBtb2RlLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkRFWF9SSU5HRVJfTk9STUFMID0gMHgwMDAwMDQwMDsKKworICAgIC8qKiBGZWVkYmFjayBtYXBwaW5nIGluZGV4IHVzZWQgYXMgYSBrZXkgZm9yIHZpYnJhdGlvbiByaW5nZXIgbW9kZS4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5ERVhfUklOR0VSX1ZJQlJBVEUgPSAweDAwMDAwODAwOworCisgICAgLyoqIEZlZWRiYWNrIG1hcHBpbmcgaW5kZXggdXNlZCBhcyBhIGtleSBmb3Igc2lsZW50IHJpbmdlciBtb2RlLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkRFWF9SSU5HRVJfU0lMRU5UID0gMHgwMDAwMTAwMDsKKworICAgIC8vIFNwZWVjaCByZWxhdGVkIGNvbnN0YW50cy4KKworICAgIC8qKgorICAgICAqIFRoZSBxdWV1aW5nIG1vZGUgd2UgYXJlIHVzaW5nIC0gaW50ZXJydXB0IGEgc3Bva2VuIHV0dGVyYW5jZSBiZWZvcmUKKyAgICAgKiBzcGVha2luZyBhbm90aGVyIG9uZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUVVFVUlOR19NT0RFX0lOVEVSUlVQVCA9IDI7CisKKyAgICAvKiogVGhlIHNwYWNlIHN0cmluZyBjb25zdGFudC4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1BBQ0UgPSAiICI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2xhc3MgbmFtZSBvZiB0aGUgbnVtYmVyIHBpY2tlciBidXR0b25zIHdpdGggbm8gdGV4dCB3ZSB3YW50IHRvCisgICAgICogYW5ub3VuY2UgaW4gdGhlIENsb2NrIGFwcGxpY2F0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDTEFTU19OQU1FX05VTUJFUl9QSUNLRVJfQlVUVE9OX0NMT0NLID0gImFuZHJvaWQud2lkZ2V0Lk51bWJlclBpY2tlckJ1dHRvbiI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2xhc3MgbmFtZSBvZiB0aGUgbnVtYmVyIHBpY2tlciBidXR0b25zIHdpdGggbm8gdGV4dCB3ZSB3YW50IHRvCisgICAgICogYW5ub3VuY2UgaW4gdGhlIEFsYXJtQ2xvY2sgYXBwbGljYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENMQVNTX05BTUVfTlVNQkVSX1BJQ0tFUl9CVVRUT05fQUxBUk1fQ0xPQ0sgPSAiY29tLmFuZHJvaWQuaW50ZXJuYWwud2lkZ2V0Lk51bWJlclBpY2tlckJ1dHRvbiI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2xhc3MgbmFtZSBvZiB0aGUgZWRpdCB0ZXh0IGJveCBmb3IgaG91cnMgYW5kIG1pbnV0ZXMgd2Ugd2FudCB0bworICAgICAqIGJldHRlciBhbm5vdW5jZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0xBU1NfTkFNRV9FRElUX1RFWFQgPSAiYW5kcm9pZC53aWRnZXQuRWRpdFRleHQiOworCisgICAgLyoqCisgICAgICogTWFwcGluZyBmcm9tIGludGVnZXIgdG8gc3RyaW5nIHJlc291cmNlIGlkIHdoZXJlIHRoZSBrZXlzIGFyZSBnZW5lcmF0ZWQKKyAgICAgKiBmcm9tIHRoZSB7QGxpbmsgQWNjZXNzaWJpbGl0eUV2ZW50I2dldFRleHQoKX0sCisgICAgICoge0BsaW5rIEFjY2Vzc2liaWxpdHlFdmVudCNnZXRJdGVtQ291bnQoKX0gYW5kCisgICAgICoge0BsaW5rIEFjY2Vzc2liaWxpdHlFdmVudCNnZXRDdXJyZW50SXRlbUluZGV4KCl9IHByb3BlcnRpZXMuCisgICAgICogPHA+CisgICAgICogTm90ZTogSW4gZ2VuZXJhbCwgY29tcHV0aW5nIHRoZXNlIG1hcHBpbmdzIGluY2x1ZGVzIHRoZSB3aWRnZXQgcG9zaXRpb24gb24KKyAgICAgKiB0aGUgc2NyZWVuLiBUaGlzIGlzIGZyYWdpbGUgYW5kIHNob3VsZCBiZSB1c2VkIGFzIGEgbGFzdCByZXNvcnQgc2luY2UKKyAgICAgKiBjaGFuZ2luZyB0aGUgbGF5b3V0IGNvdWxkIHBvdGVudGlhbGx5IGNoYW5nZSB0aGUgd2lkZ2V0IHBvc2l0aW9uLiBUaGlzIGlzCisgICAgICogYSB3b3JrYXJvdW5kIHNpbmNlIHRoZSB3aWRnZXRzIG9mIGludGVyZXN0IGFyZSBpbWFnZSBidXR0b25zIHRoYXQgZG8gbm90CisgICAgICogaGF2ZSBjb250ZW50RGVzY3JpcHRpb24gYXR0cmlidXRlIHNldCAocGx1cy9taW51cyBidXR0b25zKSBvciBubyBvdGhlcgorICAgICAqIGluZm9ybWF0aW9uIGluIHRoZSBhY2Nlc3NpYmlsaXR5IGV2ZW50IGlzIGF2YWlsYWJsZSB0byBkaXN0aW5ndWlzaCB0aGVtCisgICAgICogYXNpZGUgb2YgdGhlaXIgcG9zaXRpb25zIG9uIHRoZSBzY3JlZW4gKGhvdXIvbWludXRlIGlucHV0cykuPGJyLz4KKyAgICAgKiBJZiB5b3UgYXJlIG93bmVyIG9mIHRoZSB0YXJnZXQgYXBwbGljYXRpb24gKENsb2NrIGluIHRoaXMgY2FzZSkgeW91CisgICAgICogc2hvdWxkIGFkZCBjb250ZW50RGVzY3JpcHRpb24gYXR0cmlidXRlIHRvIGFsbCBpbWFnZSBidXR0b25zIHN1Y2ggdGhhdCBhCisgICAgICogc2NyZWVuIHJlYWRlciBrbm93cyBob3cgdG8gc3BlYWsgdGhlbS4gRm9yIGlucHV0IGZpZWxkcyAod2hpbGUgbm90CisgICAgICogYXBwbGljYWJsZSBmb3IgdGhlIGhvdXIgYW5kIG1pbnV0ZSBpbnB1dHMgc2luY2UgdGhleSBhcmUgbm90IGVtcHR5KSBhCisgICAgICogaGludCB0ZXh0IHNob3VsZCBiZSBzZXQgdG8gZW5hYmxlIGJldHRlciBhbm5vdW5jZW1lbnQuCisgICAgICogPC9wPgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNwYXJzZUFycmF5PEludGVnZXI+IHNFdmVudERhdGFNYXBwZWRTdHJpbmdSZXNvdXJjZUlkcyA9IG5ldyBTcGFyc2VBcnJheTxJbnRlZ2VyPigpOworICAgIHN0YXRpYyB7CisgICAgICAgIHNFdmVudERhdGFNYXBwZWRTdHJpbmdSZXNvdXJjZUlkcy5wdXQoMTEwLCBSLnN0cmluZy52YWx1ZV9pbmNyZWFzZV9ob3Vycyk7CisgICAgICAgIHNFdmVudERhdGFNYXBwZWRTdHJpbmdSZXNvdXJjZUlkcy5wdXQoMTE0MCwgUi5zdHJpbmcudmFsdWVfaW5jcmVhc2VfbWludXRlcyk7CisgICAgICAgIHNFdmVudERhdGFNYXBwZWRTdHJpbmdSZXNvdXJjZUlkcy5wdXQoMTEyMCwgUi5zdHJpbmcudmFsdWVfZGVjcmVhc2VfaG91cnMpOworICAgICAgICBzRXZlbnREYXRhTWFwcGVkU3RyaW5nUmVzb3VyY2VJZHMucHV0KDExNjAsIFIuc3RyaW5nLnZhbHVlX2RlY3JlYXNlX21pbnV0ZXMpOworICAgICAgICBzRXZlbnREYXRhTWFwcGVkU3RyaW5nUmVzb3VyY2VJZHMucHV0KDExMTEsIFIuc3RyaW5nLnZhbHVlX2hvdXIpOworICAgICAgICBzRXZlbnREYXRhTWFwcGVkU3RyaW5nUmVzb3VyY2VJZHMucHV0KDExMTAsIFIuc3RyaW5nLnZhbHVlX2hvdXJzKTsKKyAgICAgICAgc0V2ZW50RGF0YU1hcHBlZFN0cmluZ1Jlc291cmNlSWRzLnB1dCgxMTUxLCBSLnN0cmluZy52YWx1ZV9taW51dGUpOworICAgICAgICBzRXZlbnREYXRhTWFwcGVkU3RyaW5nUmVzb3VyY2VJZHMucHV0KDExNTAsIFIuc3RyaW5nLnZhbHVlX21pbnV0ZXMpOworICAgIH0KKworICAgIC8qKiBNYXBwaW5nIGZyb20gaW50ZWdlcnMgdG8gdmlicmF0aW9uIHBhdHRlcm5zIGZvciBoYXB0aWMgZmVlZGJhY2suICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3BhcnNlQXJyYXk8bG9uZ1tdPiBzVmlicmF0aW9uUGF0dGVybnMgPSBuZXcgU3BhcnNlQXJyYXk8bG9uZ1tdPigpOworICAgIHN0YXRpYyB7CisgICAgICAgIHNWaWJyYXRpb25QYXR0ZXJucy5wdXQoQWNjZXNzaWJpbGl0eUV2ZW50LlRZUEVfVklFV19DTElDS0VELCBuZXcgbG9uZ1tdIHsKKyAgICAgICAgICAgICAgICAwTCwgMTAwTAorICAgICAgICB9KTsKKyAgICAgICAgc1ZpYnJhdGlvblBhdHRlcm5zLnB1dChBY2Nlc3NpYmlsaXR5RXZlbnQuVFlQRV9WSUVXX0xPTkdfQ0xJQ0tFRCwgbmV3IGxvbmdbXSB7CisgICAgICAgICAgICAgICAgMEwsIDEwMEwKKyAgICAgICAgfSk7CisgICAgICAgIHNWaWJyYXRpb25QYXR0ZXJucy5wdXQoQWNjZXNzaWJpbGl0eUV2ZW50LlRZUEVfVklFV19TRUxFQ1RFRCwgbmV3IGxvbmdbXSB7CisgICAgICAgICAgICAgICAgMEwsIDE1TCwgMTBMLCAxNUwKKyAgICAgICAgfSk7CisgICAgICAgIHNWaWJyYXRpb25QYXR0ZXJucy5wdXQoQWNjZXNzaWJpbGl0eUV2ZW50LlRZUEVfVklFV19GT0NVU0VELCBuZXcgbG9uZ1tdIHsKKyAgICAgICAgICAgICAgICAwTCwgMTVMLCAxMEwsIDE1TAorICAgICAgICB9KTsKKyAgICAgICAgc1ZpYnJhdGlvblBhdHRlcm5zLnB1dChBY2Nlc3NpYmlsaXR5RXZlbnQuVFlQRV9XSU5ET1dfU1RBVEVfQ0hBTkdFRCwgbmV3IGxvbmdbXSB7CisgICAgICAgICAgICAgICAgMEwsIDI1TCwgNTBMLCAyNUwsIDUwTCwgMjVMCisgICAgICAgIH0pOworICAgICAgICBzVmlicmF0aW9uUGF0dGVybnMucHV0KElOREVYX1NDUkVFTl9PTiwgbmV3IGxvbmdbXSB7CisgICAgICAgICAgICAgICAgMEwsIDEwTCwgMTBMLCAyMEwsIDIwTCwgMzBMCisgICAgICAgIH0pOworICAgICAgICBzVmlicmF0aW9uUGF0dGVybnMucHV0KElOREVYX1NDUkVFTl9PRkYsIG5ldyBsb25nW10geworICAgICAgICAgICAgICAgIDBMLCAzMEwsIDIwTCwgMjBMLCAxMEwsIDEwTAorICAgICAgICB9KTsKKyAgICB9CisKKyAgICAvKiogTWFwcGluZyBmcm9tIGludGVnZXJzIHRvIHJhdyBzb3VuZCByZXNvdXJjZSBpZHMuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3BhcnNlQXJyYXk8SW50ZWdlcj4gc1NvdW5kc1Jlc291cmNlSWRzID0gbmV3IFNwYXJzZUFycmF5PEludGVnZXI+KCk7CisgICAgc3RhdGljIHsKKyAgICAgICAgc1NvdW5kc1Jlc291cmNlSWRzLnB1dChBY2Nlc3NpYmlsaXR5RXZlbnQuVFlQRV9WSUVXX0NMSUNLRUQsIFIucmF3LnNvdW5kX3ZpZXdfY2xpY2tlZCk7CisgICAgICAgIHNTb3VuZHNSZXNvdXJjZUlkcy5wdXQoQWNjZXNzaWJpbGl0eUV2ZW50LlRZUEVfVklFV19MT05HX0NMSUNLRUQsIFIucmF3LnNvdW5kX3ZpZXdfY2xpY2tlZCk7CisgICAgICAgIHNTb3VuZHNSZXNvdXJjZUlkcy5wdXQoQWNjZXNzaWJpbGl0eUV2ZW50LlRZUEVfVklFV19TRUxFQ1RFRCwgUi5yYXcuc291bmRfdmlld19mb2N1c2VkX29yX3NlbGVjdGVkKTsKKyAgICAgICAgc1NvdW5kc1Jlc291cmNlSWRzLnB1dChBY2Nlc3NpYmlsaXR5RXZlbnQuVFlQRV9WSUVXX0ZPQ1VTRUQsIFIucmF3LnNvdW5kX3ZpZXdfZm9jdXNlZF9vcl9zZWxlY3RlZCk7CisgICAgICAgIHNTb3VuZHNSZXNvdXJjZUlkcy5wdXQoQWNjZXNzaWJpbGl0eUV2ZW50LlRZUEVfV0lORE9XX1NUQVRFX0NIQU5HRUQsIFIucmF3LnNvdW5kX3dpbmRvd19zdGF0ZV9jaGFuZ2VkKTsKKyAgICAgICAgc1NvdW5kc1Jlc291cmNlSWRzLnB1dChJTkRFWF9TQ1JFRU5fT04sIFIucmF3LnNvdW5kX3NjcmVlbl9vbik7CisgICAgICAgIHNTb3VuZHNSZXNvdXJjZUlkcy5wdXQoSU5ERVhfU0NSRUVOX09GRiwgUi5yYXcuc291bmRfc2NyZWVuX29mZik7CisgICAgICAgIHNTb3VuZHNSZXNvdXJjZUlkcy5wdXQoSU5ERVhfUklOR0VSX1NJTEVOVCwgUi5yYXcuc291bmRfcmluZ2VyX3NpbGVudCk7CisgICAgICAgIHNTb3VuZHNSZXNvdXJjZUlkcy5wdXQoSU5ERVhfUklOR0VSX1ZJQlJBVEUsIFIucmF3LnNvdW5kX3Jpbmdlcl92aWJyYXRlKTsKKyAgICAgICAgc1NvdW5kc1Jlc291cmNlSWRzLnB1dChJTkRFWF9SSU5HRVJfTk9STUFMLCBSLnJhdy5zb3VuZF9yaW5nZXJfbm9ybWFsKTsKKyAgICB9CisKKyAgICAvLyBTb3VuZCBwb29sIHJlbGF0ZWQgbWVtYmVyIGZpZWxkcy4KKworICAgIC8qKiBNYXBwaW5nIGZyb20gaW50ZWdlcnMgdG8gZWFyY29uIG5hbWVzIC0gZHluYW1pY2FsbHkgcG9wdWxhdGVkLiAqLworICAgIHByaXZhdGUgZmluYWwgU3BhcnNlQXJyYXk8U3RyaW5nPiBtRWFyY29uTmFtZXMgPSBuZXcgU3BhcnNlQXJyYXk8U3RyaW5nPigpOworCisgICAgLy8gQXV4aWxpYXJ5IGZpZWxkcy4KKworICAgIC8qKgorICAgICAqIEhhbmRsZSB0byB0aGlzIHNlcnZpY2UgdG8gZW5hYmxlIGlubmVyIGNsYXNzZXMgdG8gYWNjZXNzIHRoZSB7QGxpbmsgQ29udGV4dH0uCisgICAgICovCisgICAgQ29udGV4dCBtQ29udGV4dDsKKworICAgIC8qKiBUaGUgZmVlZGJhY2sgdGhpcyBzZXJ2aWNlIGlzIGN1cnJlbnRseSBwcm92aWRpbmcuICovCisgICAgaW50IG1Qcm92aWRlZEZlZWRiYWNrVHlwZTsKKworICAgIC8qKiBSZXVzYWJsZSBpbnN0YW5jZSBmb3IgYnVpbGRpbmcgdXR0ZXJhbmNlcy4gKi8KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZ0J1aWxkZXIgbVV0dGVyYW5jZSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisKKyAgICAvLyBGZWVkYmFjayBwcm92aWRpbmcgc2VydmljZXMuCisKKyAgICAvKiogVGhlIHtAbGluayBUZXh0VG9TcGVlY2h9IHVzZWQgZm9yIHNwZWFraW5nLiAqLworICAgIHByaXZhdGUgVGV4dFRvU3BlZWNoIG1UdHM7CisKKyAgICAvKiogVGhlIHtAbGluayBBdWRpb01hbmFnZXJ9IGZvciBkZXRlY3RpbmcgcmluZ2VyIHN0YXRlLiAqLworICAgIHByaXZhdGUgQXVkaW9NYW5hZ2VyIG1BdWRpb01hbmFnZXI7CisKKyAgICAvKiogVmlicmF0b3IgZm9yIHByb3ZpZGluZyBoYXB0aWMgZmVlZGJhY2suICovCisgICAgcHJpdmF0ZSBWaWJyYXRvciBtVmlicmF0b3I7CisKKyAgICAvKiogRmxhZyBpZiB0aGUgaW5mcmFzdHJ1Y3R1cmUgaXMgaW5pdGlhbGl6ZWQuICovCisgICAgcHJpdmF0ZSBib29sZWFuIGlzSW5mcmFzdHJ1Y3R1cmVJbml0aWFsaXplZDsKKworICAgIC8qKiB7QGxpbmsgSGFuZGxlcn0gZm9yIGV4ZWN1dGluZyBtZXNzYWdlcyBvbiB0aGUgc2VydmljZSBtYWluIHRocmVhZC4gKi8KKyAgICBIYW5kbGVyIG1IYW5kbGVyID0gbmV3IEhhbmRsZXIoKSB7CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBoYW5kbGVNZXNzYWdlKE1lc3NhZ2UgbWVzc2FnZSkgeworICAgICAgICAgICAgc3dpdGNoIChtZXNzYWdlLndoYXQpIHsKKyAgICAgICAgICAgICAgICBjYXNlIE1FU1NBR0VfU1BFQUs6CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyB1dHRlcmFuY2UgPSAoU3RyaW5nKSBtZXNzYWdlLm9iajsKKyAgICAgICAgICAgICAgICAgICAgbVR0cy5zcGVhayh1dHRlcmFuY2UsIFFVRVVJTkdfTU9ERV9JTlRFUlJVUFQsIG51bGwpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgY2FzZSBNRVNTQUdFX1NUT1BfU1BFQUs6CisgICAgICAgICAgICAgICAgICAgIG1UdHMuc3RvcCgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgY2FzZSBNRVNTQUdFX1NUQVJUX1RUUzoKKyAgICAgICAgICAgICAgICAgICAgbVR0cyA9IG5ldyBUZXh0VG9TcGVlY2gobUNvbnRleHQsIG5ldyBUZXh0VG9TcGVlY2guT25Jbml0TGlzdGVuZXIoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkluaXQoaW50IHN0YXR1cykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlZ2lzdGVyIGhlcmUgc2luY2UgdG8gYWRkIGVhcmNvbnMgdGhlIFRUUyBtdXN0IGJlIGluaXRpYWxpemVkIGFuZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSByZWNlaXZlciBpcyBjYWxsZWQgaW1tZWRpYXRlbHkgd2l0aCB0aGUgY3VycmVudCByaW5nZXIgbW9kZS4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpc3RlckJyb2FkQ2FzdFJlY2VpdmVyKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgY2FzZSBNRVNTQUdFX1NIVVRET1dOX1RUUzoKKyAgICAgICAgICAgICAgICAgICAgbVR0cy5zaHV0ZG93bigpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgY2FzZSBNRVNTQUdFX1BMQVlfRUFSQ09OOgorICAgICAgICAgICAgICAgICAgICBpbnQgcmVzb3VyY2VJZCA9IG1lc3NhZ2UuYXJnMTsKKyAgICAgICAgICAgICAgICAgICAgcGxheUVhcmNvbihyZXNvdXJjZUlkKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIGNhc2UgTUVTU0FHRV9TVE9QX1BMQVlfRUFSQ09OOgorICAgICAgICAgICAgICAgICAgICBtVHRzLnN0b3AoKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIGNhc2UgTUVTU0FHRV9WSUJSQVRFOgorICAgICAgICAgICAgICAgICAgICBpbnQga2V5ID0gbWVzc2FnZS5hcmcxOworICAgICAgICAgICAgICAgICAgICBsb25nW10gcGF0dGVybiA9IHNWaWJyYXRpb25QYXR0ZXJucy5nZXQoa2V5KTsKKyAgICAgICAgICAgICAgICAgICAgbVZpYnJhdG9yLnZpYnJhdGUocGF0dGVybiwgLTEpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgY2FzZSBNRVNTQUdFX1NUT1BfVklCUkFURToKKyAgICAgICAgICAgICAgICAgICAgbVZpYnJhdG9yLmNhbmNlbCgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICoge0BsaW5rIEJyb2FkY2FzdFJlY2VpdmVyfSBmb3IgcmVjZWl2aW5nIHVwZGF0ZXMgZm9yIG91ciBjb250ZXh0IC0gZGV2aWNlCisgICAgICogc3RhdGUuCisgICAgICovCisgICAgcHJpdmF0ZSBCcm9hZGNhc3RSZWNlaXZlciBtQnJvYWRjYXN0UmVjZWl2ZXIgPSBuZXcgQnJvYWRjYXN0UmVjZWl2ZXIoKSB7CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBvblJlY2VpdmUoQ29udGV4dCBjb250ZXh0LCBJbnRlbnQgaW50ZW50KSB7CisgICAgICAgICAgICBTdHJpbmcgYWN0aW9uID0gaW50ZW50LmdldEFjdGlvbigpOworCisgICAgICAgICAgICBpZiAoQXVkaW9NYW5hZ2VyLlJJTkdFUl9NT0RFX0NIQU5HRURfQUNUSU9OLmVxdWFscyhhY3Rpb24pKSB7CisgICAgICAgICAgICAgICAgaW50IHJpbmdlck1vZGUgPSBpbnRlbnQuZ2V0SW50RXh0cmEoQXVkaW9NYW5hZ2VyLkVYVFJBX1JJTkdFUl9NT0RFLAorICAgICAgICAgICAgICAgICAgICAgICAgQXVkaW9NYW5hZ2VyLlJJTkdFUl9NT0RFX05PUk1BTCk7CisgICAgICAgICAgICAgICAgY29uZmlndXJlRm9yUmluZ2VyTW9kZShyaW5nZXJNb2RlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoSW50ZW50LkFDVElPTl9TQ1JFRU5fT04uZXF1YWxzKGFjdGlvbikpIHsKKyAgICAgICAgICAgICAgICBwcm92aWRlU2NyZWVuU3RhdGVDaGFuZ2VGZWVkYmFjayhJTkRFWF9TQ1JFRU5fT04pOworICAgICAgICAgICAgfSBlbHNlIGlmIChJbnRlbnQuQUNUSU9OX1NDUkVFTl9PRkYuZXF1YWxzKGFjdGlvbikpIHsKKyAgICAgICAgICAgICAgICBwcm92aWRlU2NyZWVuU3RhdGVDaGFuZ2VGZWVkYmFjayhJTkRFWF9TQ1JFRU5fT0ZGKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgTG9nLncoTE9HX1RBRywgIlJlZ2lzdGVyZWQgZm9yIGJ1dCBub3QgaGFuZGxpbmcgYWN0aW9uICIgKyBhY3Rpb24pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFByb3ZpZGVzIGZlZWRiYWNrIHRvIGFubm91bmNlIHRoZSBzY3JlZW4gc3RhdGUgY2hhbmdlLiBTdWNoIGEgY2hhbmdlCisgICAgICAgICAqIGlzIHR1cm5pbmcgdGhlIHNjcmVlbiBvbiBvciBvZmYuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBmZWVkYmFja0luZGV4IFRoZSBpbmRleCBvZiB0aGUgZmVlZGJhY2sgaW4gdGhlIHN0YXRpY2FsbHkKKyAgICAgICAgICogICAgICAgICAgICBtYXBwZWQgZmVlZGJhY2sgcmVzb3VyY2VzLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2lkIHByb3ZpZGVTY3JlZW5TdGF0ZUNoYW5nZUZlZWRiYWNrKGludCBmZWVkYmFja0luZGV4KSB7CisgICAgICAgICAgICAvLyBXZSB0YWtlIGEgc3BlY2lmaWMgYWN0aW9uIGRlcGVuZGluZyBvbiB0aGUgZmVlZGJhY2sgd2UgY3VycmVudGx5IHByb3ZpZGUuCisgICAgICAgICAgICBzd2l0Y2ggKG1Qcm92aWRlZEZlZWRiYWNrVHlwZSkgeworICAgICAgICAgICAgICAgIGNhc2UgQWNjZXNzaWJpbGl0eVNlcnZpY2VJbmZvLkZFRURCQUNLX1NQT0tFTjoKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHV0dGVyYW5jZSA9IGdlbmVyYXRlU2NyZWVuT25Pck9mZlV0dGVybmFjZShmZWVkYmFja0luZGV4KTsKKyAgICAgICAgICAgICAgICAgICAgbUhhbmRsZXIub2J0YWluTWVzc2FnZShNRVNTQUdFX1NQRUFLLCB1dHRlcmFuY2UpLnNlbmRUb1RhcmdldCgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgY2FzZSBBY2Nlc3NpYmlsaXR5U2VydmljZUluZm8uRkVFREJBQ0tfQVVESUJMRToKKyAgICAgICAgICAgICAgICAgICAgbUhhbmRsZXIub2J0YWluTWVzc2FnZShNRVNTQUdFX1BMQVlfRUFSQ09OLCBmZWVkYmFja0luZGV4LCAwKS5zZW5kVG9UYXJnZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIGNhc2UgQWNjZXNzaWJpbGl0eVNlcnZpY2VJbmZvLkZFRURCQUNLX0hBUFRJQzoKKyAgICAgICAgICAgICAgICAgICAgbUhhbmRsZXIub2J0YWluTWVzc2FnZShNRVNTQUdFX1ZJQlJBVEUsIGZlZWRiYWNrSW5kZXgsIDApLnNlbmRUb1RhcmdldCgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBmZWVkYmFjayB0eXBlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG1Qcm92aWRlZEZlZWRiYWNrVHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9OworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgb25TZXJ2aWNlQ29ubmVjdGVkKCkgeworICAgICAgICBpZiAoaXNJbmZyYXN0cnVjdHVyZUluaXRpYWxpemVkKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBtQ29udGV4dCA9IHRoaXM7CisKKyAgICAgICAgLy8gU2VuZCBhIG1lc3NhZ2UgdG8gc3RhcnQgdGhlIFRUUy4KKyAgICAgICAgbUhhbmRsZXIuc2VuZEVtcHR5TWVzc2FnZShNRVNTQUdFX1NUQVJUX1RUUyk7CisKKyAgICAgICAgLy8gR2V0IHRoZSB2aWJyYXRvciBzZXJ2aWNlLgorICAgICAgICBtVmlicmF0b3IgPSAoVmlicmF0b3IpIGdldFN5c3RlbVNlcnZpY2UoU2VydmljZS5WSUJSQVRPUl9TRVJWSUNFKTsKKworICAgICAgICAvLyBHZXQgdGhlIEF1ZGlvTWFuYWdlciBhbmQgY29uZmlndXJlIGFjY29yZGluZyB0aGUgY3VycmVudCByaW5nIG1vZGUuCisgICAgICAgIG1BdWRpb01hbmFnZXIgPSAoQXVkaW9NYW5hZ2VyKSBnZXRTeXN0ZW1TZXJ2aWNlKFNlcnZpY2UuQVVESU9fU0VSVklDRSk7CisgICAgICAgIC8vIEluIEZyb3lvIHRoZSBicm9hZGNhc3QgcmVjZWl2ZXIgZm9yIHRoZSByaW5nZXIgbW9kZSBpcyBjYWxsZWQgYmFjayB3aXRoIHRoZQorICAgICAgICAvLyBjdXJyZW50IHN0YXRlIHVwb24gcmVnaXN0ZXJpbmcgYnV0IGluIEVjbGFpciB0aGlzIGlzIG5vdCBkb25lIHNvIHdlIHBvbGwgaGVyZS4KKyAgICAgICAgaW50IHJpbmdlck1vZGUgPSBtQXVkaW9NYW5hZ2VyLmdldFJpbmdlck1vZGUoKTsKKyAgICAgICAgY29uZmlndXJlRm9yUmluZ2VyTW9kZShyaW5nZXJNb2RlKTsKKworICAgICAgICAvLyBXZSBhcmUgaW4gYW4gaW5pdGlhbGl6ZWQgc3RhdGUgbm93LgorICAgICAgICBpc0luZnJhc3RydWN0dXJlSW5pdGlhbGl6ZWQgPSB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG9uVW5iaW5kKEludGVudCBpbnRlbnQpIHsKKyAgICAgICAgaWYgKGlzSW5mcmFzdHJ1Y3R1cmVJbml0aWFsaXplZCkgeworICAgICAgICAgICAgLy8gU3RvcCB0aGUgVFRTIHNlcnZpY2UuCisgICAgICAgICAgICBtSGFuZGxlci5zZW5kRW1wdHlNZXNzYWdlKE1FU1NBR0VfU0hVVERPV05fVFRTKTsKKworICAgICAgICAgICAgLy8gVW5yZWdpc3RlciB0aGUgaW50ZW50IGJyb2FkY2FzdCByZWNlaXZlci4KKyAgICAgICAgICAgIGlmIChtQnJvYWRjYXN0UmVjZWl2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHVucmVnaXN0ZXJSZWNlaXZlcihtQnJvYWRjYXN0UmVjZWl2ZXIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBXZSBhcmUgbm90IGluIGFuIGluaXRpYWxpemVkIHN0YXRlIGFueW1vcmUuCisgICAgICAgICAgICBpc0luZnJhc3RydWN0dXJlSW5pdGlhbGl6ZWQgPSBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVnaXN0ZXJzIHRoZSBwaG9uZSBzdGF0ZSBvYnNlcnZpbmcgYnJvYWRjYXN0IHJlY2VpdmVyLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWdpc3RlckJyb2FkQ2FzdFJlY2VpdmVyKCkgeworICAgICAgICAvLyBDcmVhdGUgYSBmaWx0ZXIgd2l0aCB0aGUgYnJvYWRjYXN0IGludGVudHMgd2UgYXJlIGludGVyZXN0ZWQgaW4uCisgICAgICAgIEludGVudEZpbHRlciBmaWx0ZXIgPSBuZXcgSW50ZW50RmlsdGVyKCk7CisgICAgICAgIGZpbHRlci5hZGRBY3Rpb24oQXVkaW9NYW5hZ2VyLlJJTkdFUl9NT0RFX0NIQU5HRURfQUNUSU9OKTsKKyAgICAgICAgZmlsdGVyLmFkZEFjdGlvbihJbnRlbnQuQUNUSU9OX1NDUkVFTl9PTik7CisgICAgICAgIGZpbHRlci5hZGRBY3Rpb24oSW50ZW50LkFDVElPTl9TQ1JFRU5fT0ZGKTsKKyAgICAgICAgLy8gUmVnaXN0ZXIgZm9yIGJyb2FkY2FzdHMgb2YgaW50ZXJlc3QuCisgICAgICAgIHJlZ2lzdGVyUmVjZWl2ZXIobUJyb2FkY2FzdFJlY2VpdmVyLCBmaWx0ZXIsIG51bGwsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlcyBhbiB1dHRlcmFuY2UgZm9yIGFubm91bmNpbmcgc2NyZWVuIG9uIGFuZCBzY3JlZW4gb2ZmLgorICAgICAqCisgICAgICogQHBhcmFtIGZlZWRiYWNrSW5kZXggVGhlIGZlZWRiYWNrIGluZGV4IGZvciBsb29raW5nIHVwIGZlZWRiYWNrIHZhbHVlLgorICAgICAqIEByZXR1cm4gVGhlIHV0dGVyYW5jZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBnZW5lcmF0ZVNjcmVlbk9uT3JPZmZVdHRlcm5hY2UoaW50IGZlZWRiYWNrSW5kZXgpIHsKKyAgICAgICAgLy8gR2V0IHRoZSBhbm5vdW5jZSB0ZW1wbGF0ZS4KKyAgICAgICAgaW50IHJlc291cmNlSWQgPSAoZmVlZGJhY2tJbmRleCA9PSBJTkRFWF9TQ1JFRU5fT04pID8gUi5zdHJpbmcudGVtcGxhdGVfc2NyZWVuX29uCisgICAgICAgICAgICAgICAgOiBSLnN0cmluZy50ZW1wbGF0ZV9zY3JlZW5fb2ZmOworICAgICAgICBTdHJpbmcgdGVtcGxhdGUgPSBtQ29udGV4dC5nZXRTdHJpbmcocmVzb3VyY2VJZCk7CisKKyAgICAgICAgLy8gRm9ybWF0IHRoZSB0ZW1wbGF0ZSB3aXRoIHRoZSByaW5nZXIgcGVyY2VudGFnZS4KKyAgICAgICAgaW50IGN1cnJlbnRSaW5nZXJWb2x1bWUgPSBtQXVkaW9NYW5hZ2VyLmdldFN0cmVhbVZvbHVtZShBdWRpb01hbmFnZXIuU1RSRUFNX1JJTkcpOworICAgICAgICBpbnQgbWF4UmluZ2VyVm9sdW1lID0gbUF1ZGlvTWFuYWdlci5nZXRTdHJlYW1NYXhWb2x1bWUoQXVkaW9NYW5hZ2VyLlNUUkVBTV9SSU5HKTsKKyAgICAgICAgaW50IHZvbHVtZVBlcmNlbnQgPSAoMTAwIC8gbWF4UmluZ2VyVm9sdW1lKSAqIGN1cnJlbnRSaW5nZXJWb2x1bWU7CisKKyAgICAgICAgLy8gTGV0IHVzIHJvdW5kIHRvIGZpdmUgc28gaXQgc291bmRzIGJldHRlci4KKyAgICAgICAgaW50IGFkanVzdG1lbnQgPSB2b2x1bWVQZXJjZW50ICUgMTA7CisgICAgICAgIGlmIChhZGp1c3RtZW50IDwgNSkgeworICAgICAgICAgICAgdm9sdW1lUGVyY2VudCAtPSBhZGp1c3RtZW50OworICAgICAgICB9IGVsc2UgaWYgKGFkanVzdG1lbnQgPiA1KSB7CisgICAgICAgICAgICB2b2x1bWVQZXJjZW50ICs9ICgxMCAtIGFkanVzdG1lbnQpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQodGVtcGxhdGUsIHZvbHVtZVBlcmNlbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbmZpZ3VyZXMgdGhlIHNlcnZpY2UgYWNjb3JkaW5nIHRvIGEgcmluZ2VyIG1vZGUuIFBvc3NpYmxlCisgICAgICogY29uZmlndXJhdGlvbnM6CisgICAgICogPHA+CisgICAgICogICAxLiB7QGxpbmsgQXVkaW9NYW5hZ2VyI1JJTkdFUl9NT0RFX1NJTEVOVH08YnIvPgorICAgICAqICAgR29hbDogICAgIFByb3ZpZGUgb25seSBjdXN0b20gaGFwdGljIGZlZWRiYWNrLjxici8+CisgICAgICogICBBcHByb2FjaDogVGFrZSBvdmVyIHRoZSBoYXB0aWMgZmVlZGJhY2sgYnkgY29uZmlndXJpbmcgdGhpcyBzZXJ2aWNlIHRvIHByb3ZpZGUKKyAgICAgKiAgICAgICAgICAgICBzdWNoIGFuZCBkbyBzby4gVGhpcyB3YXkgdGhlIHN5c3RlbSB3aWxsIG5vdCBjYWxsIHRoZSBkZWZhdWx0IGhhcHRpYworICAgICAqICAgICAgICAgICAgIGZlZWRiYWNrIHNlcnZpY2UgS2lja0JhY2suPGJyLz4KKyAgICAgKiAgICAgICAgICAgICBUYWtlIG92ZXIgdGhlIGF1ZGlibGUgYW5kIHNwb2tlbiBmZWVkYmFjayBieSBjb25maWd1cmluZyB0aGlzCisgICAgICogICAgICAgICAgICAgc2VydmljZSB0byBwcm92aWRlIHN1Y2ggZmVlZGJhY2sgYnV0IG5vdCBkb2luZyBzby4gVGhpcyB3YXkgdGhlIHN5c3RlbQorICAgICAqICAgICAgICAgICAgIHdpbGwgbm90IGNhbGwgdGhlIGRlZmF1bHQgc3Bva2VuIGZlZWRiYWNrIHNlcnZpY2UgVGFsa0JhY2sgYW5kIHRoZQorICAgICAqICAgICAgICAgICAgIGRlZmF1bHQgYXVkaWJsZSBmZWVkYmFjayBzZXJ2aWNlIFNvdW5kQmFjay4KKyAgICAgKiA8L3A+CisgICAgICogPHA+CisgICAgICogICAyLiB7QGxpbmsgQXVkaW9NYW5hZ2VyI1JJTkdFUl9NT0RFX1ZJQlJBVEV9PGJyLz4KKyAgICAgKiAgIEdvYWw6ICAgICBQcm92aWRlIGN1c3RvbSBhdWRpYmxlIGFuZCBkZWZhdWx0IGhhcHRpYyBmZWVkYmFjay48YnIvPgorICAgICAqICAgQXBwcm9hY2g6IFRha2Ugb3ZlciB0aGUgYXVkaWJsZSBmZWVkYmFjayBhbmQgcHJvdmlkZSBjdXN0b20gb25lLjxici8+CisgICAgICogICAgICAgICAgICAgVGFrZSBvdmVyIHRoZSBzcG9rZW4gZmVlZGJhY2sgYnV0IGRvIG5vdCBwcm92aWRlIHN1Y2guPGJyLz4KKyAgICAgKiAgICAgICAgICAgICBMZXQgc29tZSBvdGhlciBzZXJ2aWNlIHByb3ZpZGUgaGFwdGljIGZlZWRiYWNrIChLaWNrQmFjaykuCisgICAgICogPC9wPgorICAgICAqIDxwPgorICAgICAqICAgMy4ge0BsaW5rIEF1ZGlvTWFuYWdlciNSSU5HRVJfTU9ERV9OT1JNQUx9CisgICAgICogICBHb2FsOiAgICAgUHJvdmlkZSBjdXN0b20gc3Bva2VuLCBkZWZhdWx0IGF1ZGlibGUgYW5kIGRlZmF1bHQgaGFwdGljIGZlZWRiYWNrLjxici8+CisgICAgICogICBBcHByb2FjaDogVGFrZSBvdmVyIHRoZSBzcG9rZW4gZmVlZGJhY2sgYW5kIHByb3ZpZGUgY3VzdG9tIG9uZS48YnIvPgorICAgICAqICAgICAgICAgICAgIExldCBzb21lIG90aGVyIHNlcnZpY2VzIHByb3ZpZGUgYXVkaWJsZSBmZWVkYmFjayAoU291bkJhY2spIGFuZCBoYXB0aWMKKyAgICAgKiAgICAgICAgICAgICBmZWVkYmFjayAoS2lja0JhY2spLgorICAgICAqIDwvcD4KKyAgICAgKiBOb3RlOiBJbiB0aGUgYWJvdmUgZGVzY3JpcHRpb24gYW4gYXNzdW1wdGlvbiBpcyBtYWRlIHRoYXQgYWxsIGRlZmF1bHQgZmVlZGJhY2sKKyAgICAgKiAgICAgICBzZXJ2aWNlcyBhcmUgZW5hYmxlZC4gU3VjaCBzZXJ2aWNlcyBhcmUgVGFsa0JhY2ssIFNvdW5kQmFjaywgYW5kIEtpY2tCYWNrLgorICAgICAqICAgICAgIEFsc28gdGhlIGZlYXR1cmUgb2YgZGVmaW5pbmcgYSBzZXJ2aWNlIGFzIHRoZSBkZWZhdWx0IGZvciBhIGdpdmVuIGZlZWRiYWNrCisgICAgICogICAgICAgdHlwZSB3aWxsIGJlIGF2YWlsYWJsZSBpbiBBbmRyb2lkIDIuMiBhbmQgYWJvdmUuIEZvciBwcmV2aW91cyByZWxlYXNlcyB0aGUgcGFja2FnZQorICAgICAqICAgICAgIHNwZWNpZmljIGFjY2Vzc2liaWxpdHkgc2VydmljZSBtdXN0IGJlIHJlZ2lzdGVyZWQgZmlyc3QgaS5lLiBjaGVja2VkIGluIHRoZQorICAgICAqICAgICAgIHNldHRpbmdzLgorICAgICAqCisgICAgICogQHBhcmFtIHJpbmdlck1vZGUgVGhlIGRldmljZSByaW5nZXIgbW9kZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY29uZmlndXJlRm9yUmluZ2VyTW9kZShpbnQgcmluZ2VyTW9kZSkgeworICAgICAgICBpZiAocmluZ2VyTW9kZSA9PSBBdWRpb01hbmFnZXIuUklOR0VSX01PREVfU0lMRU5UKSB7CisgICAgICAgICAgICAvLyBXaGVuIHRoZSByaW5nZXIgaXMgc2lsZW50IHdlIHdhbnQgdG8gcHJvdmlkZSBvbmx5IGhhcHRpYyBmZWVkYmFjay4KKyAgICAgICAgICAgIG1Qcm92aWRlZEZlZWRiYWNrVHlwZSA9IEFjY2Vzc2liaWxpdHlTZXJ2aWNlSW5mby5GRUVEQkFDS19IQVBUSUM7CisKKyAgICAgICAgICAgIC8vIFRha2Ugb3ZlciB0aGUgc3Bva2VuIGFuZCBzb3VuZCBmZWVkYmFjayBzbyBubyBzdWNoIGZlZWRiYWNrIGlzIHByb3ZpZGVkLgorICAgICAgICAgICAgc2V0U2VydmljZUluZm8oQWNjZXNzaWJpbGl0eVNlcnZpY2VJbmZvLkZFRURCQUNLX0hBUFRJQworICAgICAgICAgICAgICAgICAgICB8IEFjY2Vzc2liaWxpdHlTZXJ2aWNlSW5mby5GRUVEQkFDS19TUE9LRU4KKyAgICAgICAgICAgICAgICAgICAgfCBBY2Nlc3NpYmlsaXR5U2VydmljZUluZm8uRkVFREJBQ0tfQVVESUJMRSk7CisKKyAgICAgICAgICAgIC8vIFVzZSBvbmx5IGFuIGVhcmNvbiB0byBhbm5vdW5jZSByaW5nZXIgc3RhdGUgY2hhbmdlLgorICAgICAgICAgICAgbUhhbmRsZXIub2J0YWluTWVzc2FnZShNRVNTQUdFX1BMQVlfRUFSQ09OLCBJTkRFWF9SSU5HRVJfU0lMRU5ULCAwKS5zZW5kVG9UYXJnZXQoKTsKKyAgICAgICAgfSBlbHNlIGlmIChyaW5nZXJNb2RlID09IEF1ZGlvTWFuYWdlci5SSU5HRVJfTU9ERV9WSUJSQVRFKSB7CisgICAgICAgICAgICAvLyBXaGVuIHRoZSByaW5nZXIgaXMgdmlicmF0aW5nIHdlIHdhbnQgdG8gcHJvdmlkZSBvbmx5IGF1ZGlibGUgZmVlZGJhY2suCisgICAgICAgICAgICBtUHJvdmlkZWRGZWVkYmFja1R5cGUgPSBBY2Nlc3NpYmlsaXR5U2VydmljZUluZm8uRkVFREJBQ0tfQVVESUJMRTsKKworICAgICAgICAgICAgLy8gVGFrZSBvdmVyIHRoZSBzcG9rZW4gZmVlZGJhY2sgc28gbm8gc3Bva2VuIGZlZWRiYWNrIGlzIHByb3ZpZGVkLgorICAgICAgICAgICAgc2V0U2VydmljZUluZm8oQWNjZXNzaWJpbGl0eVNlcnZpY2VJbmZvLkZFRURCQUNLX0FVRElCTEUKKyAgICAgICAgICAgICAgICAgICAgfCBBY2Nlc3NpYmlsaXR5U2VydmljZUluZm8uRkVFREJBQ0tfU1BPS0VOKTsKKworICAgICAgICAgICAgLy8gVXNlIG9ubHkgYW4gZWFyY29uIHRvIGFubm91bmNlIHJpbmdlciBzdGF0ZSBjaGFuZ2UuCisgICAgICAgICAgICBtSGFuZGxlci5vYnRhaW5NZXNzYWdlKE1FU1NBR0VfUExBWV9FQVJDT04sIElOREVYX1JJTkdFUl9WSUJSQVRFLCAwKS5zZW5kVG9UYXJnZXQoKTsKKyAgICAgICAgfSBlbHNlIGlmIChyaW5nZXJNb2RlID09IEF1ZGlvTWFuYWdlci5SSU5HRVJfTU9ERV9OT1JNQUwpIHsKKyAgICAgICAgICAgIC8vIFdoZW4gdGhlIHJpbmdlciBpcyByaW5naW5nIHdlIHdhbnQgdG8gcHJvdmlkZSBzcG9rZW4gZmVlZGJhY2sKKyAgICAgICAgICAgIC8vIG92ZXJyaWRpbmcgdGhlIGRlZmF1bHQgc3Bva2VuIGZlZWRiYWNrLgorICAgICAgICAgICAgbVByb3ZpZGVkRmVlZGJhY2tUeXBlID0gQWNjZXNzaWJpbGl0eVNlcnZpY2VJbmZvLkZFRURCQUNLX1NQT0tFTjsKKyAgICAgICAgICAgIHNldFNlcnZpY2VJbmZvKEFjY2Vzc2liaWxpdHlTZXJ2aWNlSW5mby5GRUVEQkFDS19TUE9LRU4pOworCisgICAgICAgICAgICAvLyBVc2Ugb25seSBhbiBlYXJjb24gdG8gYW5ub3VuY2UgcmluZ2VyIHN0YXRlIGNoYW5nZS4KKyAgICAgICAgICAgIG1IYW5kbGVyLm9idGFpbk1lc3NhZ2UoTUVTU0FHRV9QTEFZX0VBUkNPTiwgSU5ERVhfUklOR0VSX05PUk1BTCwgMCkuc2VuZFRvVGFyZ2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB7QGxpbmsgQWNjZXNzaWJpbGl0eVNlcnZpY2VJbmZvfSB3aGljaCBpbmZvcm1zIHRoZSBzeXN0ZW0gaG93IHRvCisgICAgICogaGFuZGxlIHRoaXMge0BsaW5rIEFjY2Vzc2liaWxpdHlTZXJ2aWNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmZWVkYmFja1R5cGUgVGhlIHR5cGUgb2YgZmVlZGJhY2sgdGhpcyBzZXJ2aWNlIHdpbGwgcHJvdmlkZS4KKyAgICAgKiA8cD4KKyAgICAgKiAgIE5vdGU6IFRoZSBmZWVkYmFja1R5cGUgcGFyYW1ldGVyIGlzIGFuIGJpdHdpc2Ugb3Igb2YgYWxsCisgICAgICogICBmZWVkYmFjayB0eXBlcyB0aGlzIHNlcnZpY2Ugd291bGQgbGlrZSB0byBwcm92aWRlLgorICAgICAqIDwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0U2VydmljZUluZm8oaW50IGZlZWRiYWNrVHlwZSkgeworICAgICAgICBBY2Nlc3NpYmlsaXR5U2VydmljZUluZm8gaW5mbyA9IG5ldyBBY2Nlc3NpYmlsaXR5U2VydmljZUluZm8oKTsKKyAgICAgICAgLy8gV2UgYXJlIGludGVyZXN0ZWQgaW4gYWxsIHR5cGVzIG9mIGFjY2Vzc2liaWxpdHkgZXZlbnRzLgorICAgICAgICBpbmZvLmV2ZW50VHlwZXMgPSBBY2Nlc3NpYmlsaXR5RXZlbnQuVFlQRVNfQUxMX01BU0s7CisgICAgICAgIC8vIFdlIHdhbnQgdG8gcHJvdmlkZSBzcGVjaWZpYyB0eXBlIG9mIGZlZWRiYWNrLgorICAgICAgICBpbmZvLmZlZWRiYWNrVHlwZSA9IGZlZWRiYWNrVHlwZTsKKyAgICAgICAgLy8gV2Ugd2FudCB0byByZWNlaXZlIGV2ZW50cyBpbiBhIGNlcnRhaW4gaW50ZXJ2YWwuCisgICAgICAgIGluZm8ubm90aWZpY2F0aW9uVGltZW91dCA9IEVWRU5UX05PVElGSUNBVElPTl9USU1FT1VUX01JTExJUzsKKyAgICAgICAgLy8gV2Ugd2FudCB0byByZWNlaXZlIGFjY2Vzc2liaWxpdHkgZXZlbnRzIG9ubHkgZnJvbSBjZXJ0YWluIHBhY2thZ2VzLgorICAgICAgICBpbmZvLnBhY2thZ2VOYW1lcyA9IFBBQ0tBR0VfTkFNRVM7CisgICAgICAgIHNldFNlcnZpY2VJbmZvKGluZm8pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIG9uQWNjZXNzaWJpbGl0eUV2ZW50KEFjY2Vzc2liaWxpdHlFdmVudCBldmVudCkgeworICAgICAgICBMb2cuaShMT0dfVEFHLCBtUHJvdmlkZWRGZWVkYmFja1R5cGUgKyAiICIgKyBldmVudC50b1N0cmluZygpKTsKKworICAgICAgICAvLyBIZXJlIHdlIGFjdCBhY2NvcmRpbmcgdG8gdGhlIGZlZWRiYWNrIHR5cGUgd2UgYXJlIGN1cnJlbnRseSBwcm92aWRpbmcuCisgICAgICAgIGlmIChtUHJvdmlkZWRGZWVkYmFja1R5cGUgPT0gQWNjZXNzaWJpbGl0eVNlcnZpY2VJbmZvLkZFRURCQUNLX1NQT0tFTikgeworICAgICAgICAgICAgbUhhbmRsZXIub2J0YWluTWVzc2FnZShNRVNTQUdFX1NQRUFLLCBmb3JtYXRVdHRlcmFuY2UoZXZlbnQpKS5zZW5kVG9UYXJnZXQoKTsKKyAgICAgICAgfSBlbHNlIGlmIChtUHJvdmlkZWRGZWVkYmFja1R5cGUgPT0gQWNjZXNzaWJpbGl0eVNlcnZpY2VJbmZvLkZFRURCQUNLX0FVRElCTEUpIHsKKyAgICAgICAgICAgIG1IYW5kbGVyLm9idGFpbk1lc3NhZ2UoTUVTU0FHRV9QTEFZX0VBUkNPTiwgZXZlbnQuZ2V0RXZlbnRUeXBlKCksIDApLnNlbmRUb1RhcmdldCgpOworICAgICAgICB9IGVsc2UgaWYgKG1Qcm92aWRlZEZlZWRiYWNrVHlwZSA9PSBBY2Nlc3NpYmlsaXR5U2VydmljZUluZm8uRkVFREJBQ0tfSEFQVElDKSB7CisgICAgICAgICAgICBtSGFuZGxlci5vYnRhaW5NZXNzYWdlKE1FU1NBR0VfVklCUkFURSwgZXZlbnQuZ2V0RXZlbnRUeXBlKCksIDApLnNlbmRUb1RhcmdldCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBmZWVkYmFjayB0eXBlICIgKyBtUHJvdmlkZWRGZWVkYmFja1R5cGUpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgb25JbnRlcnJ1cHQoKSB7CisgICAgICAgIC8vIEhlcmUgd2UgYWN0IGFjY29yZGluZyB0byB0aGUgZmVlZGJhY2sgdHlwZSB3ZSBhcmUgY3VycmVudGx5IHByb3ZpZGluZy4KKyAgICAgICAgaWYgKG1Qcm92aWRlZEZlZWRiYWNrVHlwZSA9PSBBY2Nlc3NpYmlsaXR5U2VydmljZUluZm8uRkVFREJBQ0tfU1BPS0VOKSB7CisgICAgICAgICAgICBtSGFuZGxlci5vYnRhaW5NZXNzYWdlKE1FU1NBR0VfU1RPUF9TUEVBSykuc2VuZFRvVGFyZ2V0KCk7CisgICAgICAgIH0gZWxzZSBpZiAobVByb3ZpZGVkRmVlZGJhY2tUeXBlID09IEFjY2Vzc2liaWxpdHlTZXJ2aWNlSW5mby5GRUVEQkFDS19BVURJQkxFKSB7CisgICAgICAgICAgICBtSGFuZGxlci5vYnRhaW5NZXNzYWdlKE1FU1NBR0VfU1RPUF9QTEFZX0VBUkNPTikuc2VuZFRvVGFyZ2V0KCk7CisgICAgICAgIH0gZWxzZSBpZiAobVByb3ZpZGVkRmVlZGJhY2tUeXBlID09IEFjY2Vzc2liaWxpdHlTZXJ2aWNlSW5mby5GRUVEQkFDS19IQVBUSUMpIHsKKyAgICAgICAgICAgIG1IYW5kbGVyLm9idGFpbk1lc3NhZ2UoTUVTU0FHRV9TVE9QX1ZJQlJBVEUpLnNlbmRUb1RhcmdldCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBmZWVkYmFjayB0eXBlICIgKyBtUHJvdmlkZWRGZWVkYmFja1R5cGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9ybWF0cyBhbiB1dHRlcmFuY2UgZnJvbSBhbiB7QGxpbmsgQWNjZXNzaWJpbGl0eUV2ZW50fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgZnJvbSB3aGljaCB0byBmb3JtYXQgYW4gdXR0ZXJhbmNlLgorICAgICAqIEByZXR1cm4gVGhlIGZvcm1hdHRlZCB1dHRlcmFuY2UuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZm9ybWF0VXR0ZXJhbmNlKEFjY2Vzc2liaWxpdHlFdmVudCBldmVudCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHV0dGVyYW5jZSA9IG1VdHRlcmFuY2U7CisKKyAgICAgICAgLy8gQ2xlYXIgdGhlIHV0dGVyYW5jZSBiZWZvcmUgYXBwZW5kaW5nIHRoZSBmb3JtYXR0ZWQgdGV4dC4KKyAgICAgICAgdXR0ZXJhbmNlLnNldExlbmd0aCgwKTsKKworICAgICAgICBMaXN0PENoYXJTZXF1ZW5jZT4gZXZlbnRUZXh0ID0gZXZlbnQuZ2V0VGV4dCgpOworCisgICAgICAgIC8vIFdlIHRyeSB0byBnZXQgdGhlIGV2ZW50IHRleHQgaWYgc3VjaC4KKyAgICAgICAgaWYgKCFldmVudFRleHQuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBmb3IgKENoYXJTZXF1ZW5jZSBzdWJUZXh0IDogZXZlbnRUZXh0KSB7CisgICAgICAgICAgICAgICAgLy8gTWFrZSAwMSBwcm9ub3VuY2VkIGFzIDEKKyAgICAgICAgICAgICAgICBpZiAoc3ViVGV4dC5jaGFyQXQoMCkgPT0nMCcpIHsKKyAgICAgICAgICAgICAgICAgICAgc3ViVGV4dCA9IHN1YlRleHQuc3ViU2VxdWVuY2UoMSwgc3ViVGV4dC5sZW5ndGgoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHV0dGVyYW5jZS5hcHBlbmQoc3ViVGV4dCk7CisgICAgICAgICAgICAgICAgdXR0ZXJhbmNlLmFwcGVuZChTUEFDRSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEhlcmUgd2UgZG8gYSBiaXQgb2YgZW5oYW5jZW1lbnQgb2YgdGhlIFVJIHByZXNlbnRhdGlvbiBieSB1c2luZyB0aGUgc2VtYW50aWMKKyAgICAgICAgICAgIC8vIG9mIHRoZSBldmVudCBzb3VyY2UgaW4gdGhlIGNvbnRleHQgb2YgdGhlIENsb2NrIGFwcGxpY2F0aW9uLgorICAgICAgICAgICAgaWYgKGV2ZW50LmdldEV2ZW50VHlwZSgpID09IEFjY2Vzc2liaWxpdHlFdmVudC5UWVBFX1ZJRVdfRk9DVVNFRAorICAgICAgICAgICAgICAgICAgICAmJiBDTEFTU19OQU1FX0VESVRfVEVYVC5lcXVhbHMoZXZlbnQuZ2V0Q2xhc3NOYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgLy8gSWYgdGhlIHNvdXJjZSBpcyBhbiBlZGl0IHRleHQgYm94IGFuZCB3ZSBoYXZlIGEgbWFwcGluZyBiYXNlZCBvbgorICAgICAgICAgICAgICAgIC8vIGl0cyBwb3NpdGlvbiBpbiB0aGUgaXRlbXMgb2YgdGhlIGNvbnRhaW5lciBwYXJlbnQgb2YgdGhlIGV2ZW50IHNvdXJjZQorICAgICAgICAgICAgICAgIC8vIHdlIGFwcGVuZCB0aGF0IHZhbHVlIGFzIHdlbGwuIFdlIHNheSAiWFggaG91cnMiIGFuZCAiWFggbWludXRlcyIuCisgICAgICAgICAgICAgICAgU3RyaW5nIHJlc291cmNlVmFsdWUgPSBnZXRFdmVudERhdGFNYXBwZWRTdHJpbmdSZXNvdXJjZShldmVudCk7CisgICAgICAgICAgICAgICAgaWYgKHJlc291cmNlVmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB1dHRlcmFuY2UuYXBwZW5kKHJlc291cmNlVmFsdWUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIHV0dGVyYW5jZS50b1N0cmluZygpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVGhlcmUgaXMgbm8gZXZlbnQgdGV4dCBidXQgd2UgdHJ5IHRvIGdldCB0aGUgY29udGVudCBkZXNjcmlwdGlvbiB3aGljaCBpcworICAgICAgICAvLyBhbiBvcHRpb25hbCBhdHRyaWJ1dGUgZm9yIGRlc2NyaWJpbmcgYSB2aWV3ICh0eXBpY2FsbHkgdXNlZCB3aXRoIEltYWdlVmlldykuCisgICAgICAgIENoYXJTZXF1ZW5jZSBjb250ZW50RGVzY3JpcHRpb24gPSBldmVudC5nZXRDb250ZW50RGVzY3JpcHRpb24oKTsKKyAgICAgICAgaWYgKGNvbnRlbnREZXNjcmlwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICB1dHRlcmFuY2UuYXBwZW5kKGNvbnRlbnREZXNjcmlwdGlvbik7CisgICAgICAgICAgICByZXR1cm4gdXR0ZXJhbmNlLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBObyB0ZXh0IGFuZCBjb250ZW50IGRlc2NyaXB0aW9uIGZvciB0aGUgcGx1cyBhbmQgbWludXMgYnV0dG9ucywgc28gd2UgbG9va3VwCisgICAgICAgIC8vIGN1c3RvbSB2YWx1ZXMgYmFzZWQgb24gdGhlIGV2ZW50J3MgaXRlbUNvdW50IGFuZCBjdXJyZW50SXRlbUluZGV4IHByb3BlcnRpZXMuCisgICAgICAgIENoYXJTZXF1ZW5jZSBjbGFzc05hbWUgPSBldmVudC5nZXRDbGFzc05hbWUoKTsKKworICAgICAgICBpZiAoZXZlbnQuZ2V0RXZlbnRUeXBlKCkgPT0gQWNjZXNzaWJpbGl0eUV2ZW50LlRZUEVfVklFV19GT0NVU0VECisgICAgICAgICAgICAgICAgJiYgKENMQVNTX05BTUVfTlVNQkVSX1BJQ0tFUl9CVVRUT05fQUxBUk1fQ0xPQ0suZXF1YWxzKGNsYXNzTmFtZSkKKyAgICAgICAgICAgICAgICB8fCBDTEFTU19OQU1FX05VTUJFUl9QSUNLRVJfQlVUVE9OX0NMT0NLLmVxdWFscyhjbGFzc05hbWUpKSkgeworICAgICAgICAgICAgU3RyaW5nIHJlc291cmNlVmFsdWUgPSBnZXRFdmVudERhdGFNYXBwZWRTdHJpbmdSZXNvdXJjZShldmVudCk7CisgICAgICAgICAgICB1dHRlcmFuY2UuYXBwZW5kKHJlc291cmNlVmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHV0dGVyYW5jZS50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVzb3VyY2UgbWFwcGVkIGJhc2VkIG9uIHRoZSBhY2Nlc3NpYmlsaXR5IGV2ZW50CisgICAgICogZGF0YSwgc3BlY2lmaWNhbGx5IHRoZQorICAgICAqIHtAbGluayBBY2Nlc3NpYmlsaXR5RXZlbnQjZ2V0VGV4dCgpfSwKKyAgICAgKiB7QGxpbmsgQWNjZXNzaWJpbGl0eUV2ZW50I2dldEl0ZW1Db3VudCgpfSwgYW5kCisgICAgICoge0BsaW5rIEFjY2Vzc2liaWxpdHlFdmVudCNnZXRDdXJyZW50SXRlbUluZGV4KCl9IHByb3BlcnRpZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXZlbnQgVGhlIHtAbGluayBBY2Nlc3NpYmlsaXR5RXZlbnR9IHRvIHByb2Nlc3MuCisgICAgICogQHJldHVybiBUaGUgbWFwcGVkIHN0cmluZyBpZiBzdWNoIGV4aXN0cywgbnVsbCBvdGhlcndpc2UuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0RXZlbnREYXRhTWFwcGVkU3RyaW5nUmVzb3VyY2UoQWNjZXNzaWJpbGl0eUV2ZW50IGV2ZW50KSB7CisgICAgICAgIGludCBsb29rdXBJbmRleCA9IGNvbXB1dGVMb29rdXBJbmRleChldmVudCk7CisgICAgICAgIGludCByZXNvdXJjZUlkID0gc0V2ZW50RGF0YU1hcHBlZFN0cmluZ1Jlc291cmNlSWRzLmdldChsb29rdXBJbmRleCk7CisgICAgICAgIHJldHVybiBnZXRTdHJpbmcocmVzb3VyY2VJZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZXMgYW4gaW5kZXggZm9yIGxvb2tpbmcgdXAgdGhlIGN1c3RvbSB0ZXh0IGZvciB2aWV3cyB3aGljaCBlaXRoZXIKKyAgICAgKiBkbyBub3QgaGF2ZSB0ZXh0L2NvbnRlbnQgZGVzY3JpcHRpb24gb3IgdGhlIHBvc2l0aW9uIGluZm9ybWF0aW9uCisgICAgICogaXMgdGhlIG9ubHkgb3JhY2xlIGZvciBkZWNpZGluZyBmcm9tIHdoaWNoIHdpZGdldCB3YXMgYW4gYWNjZXNzaWJpbGl0eQorICAgICAqIGV2ZW50IGdlbmVyYXRlZC4gVGhlIGluZGV4IGlzIGNvbXB1dGVkIGJhc2VkIG9uCisgICAgICoge0BsaW5rIEFjY2Vzc2liaWxpdHlFdmVudCNnZXRUZXh0KCl9LAorICAgICAqIHtAbGluayBBY2Nlc3NpYmlsaXR5RXZlbnQjZ2V0SXRlbUNvdW50KCl9LCBhbmQKKyAgICAgKiB7QGxpbmsgQWNjZXNzaWJpbGl0eUV2ZW50I2dldEN1cnJlbnRJdGVtSW5kZXgoKX0gcHJvcGVydGllcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgZnJvbSB3aGljaCB0byBjb21wdXRlIHRoZSBpbmRleC4KKyAgICAgKiBAcmV0dXJuIFRoZSBsb29rdXAgaW5kZXguCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgY29tcHV0ZUxvb2t1cEluZGV4KEFjY2Vzc2liaWxpdHlFdmVudCBldmVudCkgeworICAgICAgICBpbnQgbG9va3VwSW5kZXggPSBldmVudC5nZXRJdGVtQ291bnQoKTsKKyAgICAgICAgaW50IGRpdmlkZWQgPSBldmVudC5nZXRDdXJyZW50SXRlbUluZGV4KCk7CisKKyAgICAgICAgd2hpbGUgKGRpdmlkZWQgPiAwKSB7CisgICAgICAgICAgICBsb29rdXBJbmRleCAqPSAxMDsKKyAgICAgICAgICAgIGRpdmlkZWQgLz0gMTA7CisgICAgICAgIH0KKworICAgICAgICBsb29rdXBJbmRleCArPSBldmVudC5nZXRDdXJyZW50SXRlbUluZGV4KCk7CisgICAgICAgIGxvb2t1cEluZGV4ICo9IDEwOworCisgICAgICAgIC8vIFRoaXMgaXMgcHJpbWFyaWx5IGZvciBoYW5kbGluZyB0aGUgemVybyBob3VyL3plcm8gbWludXRlcyBjYXNlcworICAgICAgICBpZiAoIWV2ZW50LmdldFRleHQoKS5pc0VtcHR5KCkKKyAgICAgICAgICAgICAgICAmJiAoIjEiLmVxdWFscyhldmVudC5nZXRUZXh0KCkuZ2V0KDApLnRvU3RyaW5nKCkpIHx8ICIwMSIuZXF1YWxzKGV2ZW50LmdldFRleHQoKQorICAgICAgICAgICAgICAgICAgICAgICAgLmdldCgwKS50b1N0cmluZygpKSkpIHsKKyAgICAgICAgICAgIGxvb2t1cEluZGV4Kys7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbG9va3VwSW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGxheXMgYW4gZWFyY29uIGdpdmVuIGl0cyBpZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlYXJjb25JZCBUaGUgaWQgb2YgdGhlIGVhcmNvbiB0byBiZSBwbGF5ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHBsYXlFYXJjb24oaW50IGVhcmNvbklkKSB7CisgICAgICAgIFN0cmluZyBlYXJjb25OYW1lID0gbUVhcmNvbk5hbWVzLmdldChlYXJjb25JZCk7CisgICAgICAgIGlmIChlYXJjb25OYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIFdlIGRvIG5vdCBrbm93IHRoZSBzb3VuZCBpZCwgaGVuY2Ugd2UgbmVlZCB0byBsb2FkIHRoZSBzb3VuZC4KKyAgICAgICAgICAgIGludCByZXNvdXJjZUlkID0gc1NvdW5kc1Jlc291cmNlSWRzLmdldChlYXJjb25JZCk7CisgICAgICAgICAgICBlYXJjb25OYW1lID0gIlsiICsgZWFyY29uSWQgKyAiXSI7CisgICAgICAgICAgICBtVHRzLmFkZEVhcmNvbihlYXJjb25OYW1lLCBnZXRQYWNrYWdlTmFtZSgpLCByZXNvdXJjZUlkKTsKKyAgICAgICAgICAgIG1FYXJjb25OYW1lcy5wdXQoZWFyY29uSWQsIGVhcmNvbk5hbWUpOworICAgICAgICB9CisKKyAgICAgICAgbVR0cy5wbGF5RWFyY29uKGVhcmNvbk5hbWUsIFFVRVVJTkdfTU9ERV9JTlRFUlJVUFQsIG51bGwpOworICAgIH0KK30K