cGFja2FnZSBvcmcuZWNsaXBzZS51aS5pbnRlcm5hbC5kaWFsb2dzOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKQ29weXJpZ2h0IChjKSAyMDAyIElCTSBDb3JwLiBhbmQgb3RoZXJzLgpBbGwgcmlnaHRzIHJlc2VydmVkLiCgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYwLjUKd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjA1Lmh0bWwKoApDb250cmlidXRvcnM6CioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS53aXphcmQuV2l6YXJkUGFnZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWREYXRhOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkTGF5b3V0OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmhlbHAuV29ya2JlbmNoSGVscDsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmludGVybmFsLklIZWxwQ29udGV4dElkczsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmludGVybmFsLldvcmtiZW5jaE1lc3NhZ2VzOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuaW50ZXJuYWwubWlzYy5XaXphcmRTdGVwR3JvdXA7CgovKioKICogVGhpcyBwYWdlIGFsbG93cyB0aGUgdXNlciB0byByZXZpZXcgdGhlIHN0ZXBzIHRvIGJlIGRvbmUuCiAqIDxwPgogKiBFeGFtcGxlIHVzZWFnZToKICogPHByZT4KICogbWFpblBhZ2UgPSBuZXcgTXVsdGlTdGVwUmV2aWV3V2l6YXJkUGFnZSgibXVsdGlTdGVwUmV2aWV3UGFnZSIpOwogKiBtYWluUGFnZS5zZXRUaXRsZSgiUHJvamVjdCIpOwogKiBtYWluUGFnZS5zZXREZXNjcmlwdGlvbigiUmV2aWV3IHByb2plY3QuIik7CiAqIDwvcHJlPgogKiA8L3A+CiAqLwpwdWJsaWMgY2xhc3MgTXVsdGlTdGVwUmV2aWV3V2l6YXJkUGFnZSBleHRlbmRzIFdpemFyZFBhZ2UgewoJcHJpdmF0ZSBUZXh0IGRldGFpbHNGaWVsZDsKCXByaXZhdGUgTGFiZWwgaW5zdHJ1Y3Rpb25MYWJlbDsKCXByaXZhdGUgV2l6YXJkU3RlcEdyb3VwIHN0ZXBHcm91cDsKCXByaXZhdGUgTXVsdGlTdGVwV2l6YXJkIHN0ZXBXaXphcmQ7CgoJLyoqCgkgKiBDcmVhdGVzIGEgbmV3IHN0ZXAgcmV2aWV3IHdpemFyZCBwYWdlLgoJICoKCSAqIEBwYXJhbSBwYWdlTmFtZSB0aGUgbmFtZSBvZiB0aGlzIHBhZ2UKCSAqLwoJcHVibGljIE11bHRpU3RlcFJldmlld1dpemFyZFBhZ2UoU3RyaW5nIHBhZ2VOYW1lLCBNdWx0aVN0ZXBXaXphcmQgc3RlcFdpemFyZCkgewoJCXN1cGVyKHBhZ2VOYW1lKTsKCQl0aGlzLnN0ZXBXaXphcmQgPSBzdGVwV2l6YXJkOwoJfQoKCS8qIChub24tSmF2YWRvYykKCSAqIE1ldGhvZCBkZWNsYXJlZCBvbiBJV2l6YXJkUGFnZQoJICovCglwdWJsaWMgYm9vbGVhbiBjYW5GbGlwVG9OZXh0UGFnZSgpIHsKCQkvLyBBbHJlYWR5IGtub3cgdGhlcmUgaXMgYSBuZXh0IHBhZ2UuLi4KCQlyZXR1cm4gaXNQYWdlQ29tcGxldGUoKSAmJiAhc3RlcFdpemFyZC5jYW5GaW5pc2hPblJldmlld1BhZ2UoKTsKCX0KCgkvKiAobm9uLUphdmFkb2MpCgkgKiBNZXRob2QgZGVjbGFyZWQgb24gSURpYWxvZ1BhZ2UuCgkgKi8KCXB1YmxpYyB2b2lkIGNyZWF0ZUNvbnRyb2woQ29tcG9zaXRlIHBhcmVudCkgewoJCUNvbXBvc2l0ZSBjb21wb3NpdGUgPSBuZXcgQ29tcG9zaXRlKHBhcmVudCwgU1dULk5VTEwpOwoJCUdyaWRMYXlvdXQgbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQubnVtQ29sdW1ucyA9IDI7CgkJY29tcG9zaXRlLnNldExheW91dChsYXlvdXQpOwoJCWNvbXBvc2l0ZS5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0JPVEgpKTsKCgkJV29ya2JlbmNoSGVscC5zZXRIZWxwKGNvbXBvc2l0ZSwgSUhlbHBDb250ZXh0SWRzLk5FV19QUk9KRUNUX1JFVklFV19XSVpBUkRfUEFHRSk7CgoJCWNyZWF0ZVN0ZXBHcm91cChjb21wb3NpdGUpOwoJCWNyZWF0ZURldGFpbHNHcm91cChjb21wb3NpdGUpOwoJCWNyZWF0ZUluc3RydWN0aW9uc0dyb3VwKGNvbXBvc2l0ZSk7CgkJCgkJc2V0Q29udHJvbChjb21wb3NpdGUpOwoJfQoJCgkvKioKCSAqIENyZWF0ZXMgdGhlIGNvbnRyb2wgZm9yIHRoZSBkZXRhaWxzCgkgKi8KCXByaXZhdGUgdm9pZCBjcmVhdGVEZXRhaWxzR3JvdXAoQ29tcG9zaXRlIHBhcmVudCkgewoJCS8vIENyZWF0ZSBhIGNvbXBvc2l0ZSB0byBob2xkIGV2ZXJ5dGhpbmcgdG9nZXRoZXIKCQlDb21wb3NpdGUgY29tcG9zaXRlID0gbmV3IENvbXBvc2l0ZShwYXJlbnQsIFNXVC5OVUxMKTsKCQljb21wb3NpdGUuc2V0TGF5b3V0KG5ldyBHcmlkTGF5b3V0KCkpOwoJCWNvbXBvc2l0ZS5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0JPVEgpKTsKCQkKCQkvLyBBZGQgYSBsYWJlbCB0byBpZGVudGlmeSB0aGUgZGV0YWlscyB0ZXh0IGZpZWxkCgkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwoY29tcG9zaXRlLCBTV1QuTEVGVCk7CgkJbGFiZWwuc2V0VGV4dChXb3JrYmVuY2hNZXNzYWdlcy5nZXRTdHJpbmcoIk11bHRpU3RlcFJldmlld1dpemFyZFBhZ2UuZGV0YWlsc0xhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJR3JpZERhdGEgZGF0YSA9IG5ldyBHcmlkRGF0YSgpOwoJCWRhdGEudmVydGljYWxBbGlnbm1lbnQgPSBTV1QuVE9QOwoJCWxhYmVsLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJLy8gVGV4dCBmaWVsZCB0byBkaXNwbGF5IHRoZSBzdGVwJ3MgZGV0YWlscwoJCWRldGFpbHNGaWVsZCA9IG5ldyBUZXh0KGNvbXBvc2l0ZSwgU1dULldSQVAgfCBTV1QuTVVMVEkgfCBTV1QuVl9TQ1JPTEwgfCBTV1QuQk9SREVSKTsKCQlkZXRhaWxzRmllbGQuc2V0VGV4dCgiXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuIik7IC8vIHByZWZpbGwgdG8gc2hvdyAxNSBsaW5lcyAvLyROT04tTkxTLTEkCgkJZGV0YWlsc0ZpZWxkLnNldEVkaXRhYmxlKGZhbHNlKTsKCQlkZXRhaWxzRmllbGQuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9CT1RIKSk7Cgl9CgkKCS8qKgoJICogQ3JlYXRlcyB0aGUgY29udHJvbCBmb3IgdGhlIGluc3RydWN0aW9ucwoJICovCglwcml2YXRlIHZvaWQgY3JlYXRlSW5zdHJ1Y3Rpb25zR3JvdXAoQ29tcG9zaXRlIHBhcmVudCkgewoJCWluc3RydWN0aW9uTGFiZWwgPSBuZXcgTGFiZWwocGFyZW50LCBTV1QuTEVGVCk7CgkJaW5zdHJ1Y3Rpb25MYWJlbC5zZXRUZXh0KFdvcmtiZW5jaE1lc3NhZ2VzLmdldFN0cmluZygiTXVsdGlTdGVwUmV2aWV3V2l6YXJkUGFnZS5pbnN0cnVjdGlvbkxhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJR3JpZERhdGEgZGF0YSA9IG5ldyBHcmlkRGF0YSgpOwoJCWRhdGEudmVydGljYWxBbGlnbm1lbnQgPSBTV1QuVE9QOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwoJCWluc3RydWN0aW9uTGFiZWwuc2V0TGF5b3V0RGF0YShkYXRhKTsKCX0KCQoJLyoqCgkgKiBDcmVhdGVzIHRoZSBjb250cm9sIGZvciB0aGUgc3RlcCBsaXN0CgkgKi8KCXByaXZhdGUgdm9pZCBjcmVhdGVTdGVwR3JvdXAoQ29tcG9zaXRlIHBhcmVudCkgewoJCXN0ZXBHcm91cCA9IG5ldyBXaXphcmRTdGVwR3JvdXAoKTsKCQlzdGVwR3JvdXAuY3JlYXRlQ29udGVudHMocGFyZW50KTsKCQlzdGVwR3JvdXAuc2V0U2VsZWN0aW9uTGlzdGVuZXIobmV3IElTZWxlY3Rpb25DaGFuZ2VkTGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHNlbGVjdGlvbkNoYW5nZWQoU2VsZWN0aW9uQ2hhbmdlZEV2ZW50IGV2ZW50KSB7CgkJCQlpZiAoZXZlbnQuZ2V0U2VsZWN0aW9uKCkgaW5zdGFuY2VvZiBJU3RydWN0dXJlZFNlbGVjdGlvbikgewoJCQkJCUlTdHJ1Y3R1cmVkU2VsZWN0aW9uIHNlbCA9IChJU3RydWN0dXJlZFNlbGVjdGlvbilldmVudC5nZXRTZWxlY3Rpb24oKTsKCQkJCQlXaXphcmRTdGVwIHN0ZXAgPSAoV2l6YXJkU3RlcClzZWwuZ2V0Rmlyc3RFbGVtZW50KCk7CgkJCQkJaWYgKHN0ZXAgIT0gbnVsbCkKCQkJCQkJZGV0YWlsc0ZpZWxkLnNldFRleHQoc3RlcC5nZXREZXRhaWxzKCkpOwoJCQkJfQoJCQl9CgkJfSk7Cgl9CgkKCS8qKgoJICogUmV0dXJucyB0aGUgc3RlcHMgdG8gYmUgZGlzcGxheWVkLgoJICovCgkvKiBwYWNrYWdlICovIFdpemFyZFN0ZXBbXSBnZXRTdGVwcygpIHsKCQlpZiAoc3RlcEdyb3VwICE9IG51bGwpCgkJCXJldHVybiBzdGVwR3JvdXAuZ2V0U3RlcHMoKTsKCQllbHNlCgkJCXJldHVybiBuZXcgV2l6YXJkU3RlcFswXTsKCX0KCgkvKioKCSAqIFNldHMgdGhlIHN0ZXBzIHRvIGJlIGRpc3BsYXllZC4gSGFzIG5vIGVmZmVjdCBpZgoJICogdGhlIHBhZ2UgaXMgbm90IHlldCBjcmVhdGVkLgoJICogCgkgKiBAcGFyYW0gc3RlcHMgdGhlIGNvbGxlY3Rpb24gb2Ygc3RlcHMKCSAqLwoJLyogcGFja2FnZSAqLyB2b2lkIHNldFN0ZXBzKFdpemFyZFN0ZXBbXSBzdGVwcykgewoJCWlmIChzdGVwR3JvdXAgIT0gbnVsbCkKCQkJc3RlcEdyb3VwLnNldFN0ZXBzKHN0ZXBzKTsKCX0KCQoJLyogKG5vbi1KYXZhZG9jKQoJICogTWV0aG9kIGRlY2xhcmVkIG9uIElEaWFsb2dQYWdlLgoJICovCglwdWJsaWMgdm9pZCBzZXRWaXNpYmxlKGJvb2xlYW4gdmlzaWJsZSkgewoJCXN1cGVyLnNldFZpc2libGUodmlzaWJsZSk7CgkJaWYgKHZpc2libGUpIHsKCQkJaWYgKHN0ZXBXaXphcmQuY2FuRmluaXNoT25SZXZpZXdQYWdlKCkpCgkJCQlpbnN0cnVjdGlvbkxhYmVsLnNldFRleHQoV29ya2JlbmNoTWVzc2FnZXMuZ2V0U3RyaW5nKCJNdWx0aVN0ZXBSZXZpZXdXaXphcmRQYWdlLmluc3RydWN0aW9uRmluaXNoTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQkJZWxzZQoJCQkJaW5zdHJ1Y3Rpb25MYWJlbC5zZXRUZXh0KFdvcmtiZW5jaE1lc3NhZ2VzLmdldFN0cmluZygiTXVsdGlTdGVwUmV2aWV3V2l6YXJkUGFnZS5pbnN0cnVjdGlvbk5leHRMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCQkoKENvbXBvc2l0ZSlnZXRDb250cm9sKCkpLmxheW91dCh0cnVlKTsKCQl9Cgl9Cn0K