LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDE2IEZ1bmRhY2nzbiBUZWNuYWxpYSBSZXNlYXJjaCAmIElubm92YXRpb24uCiAqCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCiAqCiAqIENvbnRyaWJ1dG9yczoKICogICBIdWFzY2FyIEVzcGlub3phIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgQWxlamFuZHJhIFJ17XogLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBJZG95YSBEZWwgUu1vIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgTWFyaSBDYXJtZW4gUGFsYWNpb3MgLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBBbmdlbCBM83BleiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBhbS5wcm9jc3BlYy5wcm9jZXNzLmltcGw7CgppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLm5vdGlmeS5Ob3RpZmljYXRpb25DaGFpbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5jb21tb24udXRpbC5FTGlzdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lY29yZS5FQ2xhc3M7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWNvcmUuSW50ZXJuYWxFT2JqZWN0OwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVjb3JlLnV0aWwuSW50ZXJuYWxFTGlzdDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5hc3N1cmFuY2Vhc3NldHMuYXNzdXJhbmNlYXNzZXQuQXNzdXJhbmNlQXNzZXRFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5hc3N1cmFuY2Vhc3NldHMuYXNzdXJhbmNlYXNzZXQuaW1wbC5NYW5hZ2VhYmxlQXNzdXJhbmNlQXNzZXRJbXBsOwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQuaW5mcmEuZ2VuZXJhbC5nZW5lcmFsLkRlc2NyaWJhYmxlRWxlbWVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmluZnJhLmdlbmVyYWwuZ2VuZXJhbC5HZW5lcmFsUGFja2FnZTsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmluZnJhLmdlbmVyYWwuZ2VuZXJhbC5OYW1lZEVsZW1lbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5ldm0uZXZpZHNwZWMuZXZpZGVuY2UuQXJ0ZWZhY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wYW0ucHJvY3NwZWMucHJvY2Vzcy5BY3Rpdml0eTsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBhbS5wcm9jc3BlYy5wcm9jZXNzLkFjdGl2aXR5UmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGFtLnByb2NzcGVjLnByb2Nlc3MuUGFydGljaXBhbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wYW0ucHJvY3NwZWMucHJvY2Vzcy5Qcm9jZXNzUGFja2FnZTsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBhbS5wcm9jc3BlYy5wcm9jZXNzLlRlY2huaXF1ZTsKCi8qKgogKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgogKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgbW9kZWwgb2JqZWN0ICc8ZW0+PGI+QWN0aXZpdHk8L2I+PC9lbT4nLgogKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KICogPHA+CiAqIFRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgYXJlIGltcGxlbWVudGVkOgogKiA8dWw+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS5vcGVuY2VydC5wYW0ucHJvY3NwZWMucHJvY2Vzcy5pbXBsLkFjdGl2aXR5SW1wbCNnZXRJZCA8ZW0+SWQ8L2VtPn08L2xpPgogKiAgIDxsaT57QGxpbmsgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGFtLnByb2NzcGVjLnByb2Nlc3MuaW1wbC5BY3Rpdml0eUltcGwjZ2V0TmFtZSA8ZW0+TmFtZTwvZW0+fTwvbGk+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS5vcGVuY2VydC5wYW0ucHJvY3NwZWMucHJvY2Vzcy5pbXBsLkFjdGl2aXR5SW1wbCNnZXREZXNjcmlwdGlvbiA8ZW0+RGVzY3JpcHRpb248L2VtPn08L2xpPgogKiAgIDxsaT57QGxpbmsgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGFtLnByb2NzcGVjLnByb2Nlc3MuaW1wbC5BY3Rpdml0eUltcGwjZ2V0U3RhcnRUaW1lIDxlbT5TdGFydCBUaW1lPC9lbT59PC9saT4KICogICA8bGk+e0BsaW5rIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBhbS5wcm9jc3BlYy5wcm9jZXNzLmltcGwuQWN0aXZpdHlJbXBsI2dldEVuZFRpbWUgPGVtPkVuZCBUaW1lPC9lbT59PC9saT4KICogICA8bGk+e0BsaW5rIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBhbS5wcm9jc3BlYy5wcm9jZXNzLmltcGwuQWN0aXZpdHlJbXBsI2dldFN1YkFjdGl2aXR5IDxlbT5TdWIgQWN0aXZpdHk8L2VtPn08L2xpPgogKiAgIDxsaT57QGxpbmsgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGFtLnByb2NzcGVjLnByb2Nlc3MuaW1wbC5BY3Rpdml0eUltcGwjZ2V0UHJlY2VkaW5nQWN0aXZpdHkgPGVtPlByZWNlZGluZyBBY3Rpdml0eTwvZW0+fTwvbGk+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS5vcGVuY2VydC5wYW0ucHJvY3NwZWMucHJvY2Vzcy5pbXBsLkFjdGl2aXR5SW1wbCNnZXRQYXJ0aWNpcGFudCA8ZW0+UGFydGljaXBhbnQ8L2VtPn08L2xpPgogKiAgIDxsaT57QGxpbmsgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGFtLnByb2NzcGVjLnByb2Nlc3MuaW1wbC5BY3Rpdml0eUltcGwjZ2V0VGVjaG5pcXVlIDxlbT5UZWNobmlxdWU8L2VtPn08L2xpPgogKiAgIDxsaT57QGxpbmsgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGFtLnByb2NzcGVjLnByb2Nlc3MuaW1wbC5BY3Rpdml0eUltcGwjZ2V0T3duZWRSZWwgPGVtPk93bmVkIFJlbDwvZW0+fTwvbGk+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS5vcGVuY2VydC5wYW0ucHJvY3NwZWMucHJvY2Vzcy5pbXBsLkFjdGl2aXR5SW1wbCNnZXRSZXF1aXJlZEFydGVmYWN0IDxlbT5SZXF1aXJlZCBBcnRlZmFjdDwvZW0+fTwvbGk+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS5vcGVuY2VydC5wYW0ucHJvY3NwZWMucHJvY2Vzcy5pbXBsLkFjdGl2aXR5SW1wbCNnZXRQcm9kdWNlZEFydGVmYWN0IDxlbT5Qcm9kdWNlZCBBcnRlZmFjdDwvZW0+fTwvbGk+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS5vcGVuY2VydC5wYW0ucHJvY3NwZWMucHJvY2Vzcy5pbXBsLkFjdGl2aXR5SW1wbCNnZXRBc3NldEV2ZW50IDxlbT5Bc3NldCBFdmVudDwvZW0+fTwvbGk+CiAqIDwvdWw+CiAqIDwvcD4KICoKICogQGdlbmVyYXRlZAogKi8KcHVibGljIGNsYXNzIEFjdGl2aXR5SW1wbCBleHRlbmRzIE1hbmFnZWFibGVBc3N1cmFuY2VBc3NldEltcGwgaW1wbGVtZW50cyBBY3Rpdml0eSB7CgkvKioKCSAqIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoZSAne0BsaW5rICNnZXRJZCgpIDxlbT5JZDwvZW0+fScgYXR0cmlidXRlLgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHNlZSAjZ2V0SWQoKQoJICogQGdlbmVyYXRlZAoJICogQG9yZGVyZWQKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgSURfRURFRkFVTFQgPSBudWxsOwoKCS8qKgoJICogVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlICd7QGxpbmsgI2dldE5hbWUoKSA8ZW0+TmFtZTwvZW0+fScgYXR0cmlidXRlLgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHNlZSAjZ2V0TmFtZSgpCgkgKiBAZ2VuZXJhdGVkCgkgKiBAb3JkZXJlZAoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FX0VERUZBVUxUID0gbnVsbDsKCgkvKioKCSAqIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoZSAne0BsaW5rICNnZXREZXNjcmlwdGlvbigpIDxlbT5EZXNjcmlwdGlvbjwvZW0+fScgYXR0cmlidXRlLgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHNlZSAjZ2V0RGVzY3JpcHRpb24oKQoJICogQGdlbmVyYXRlZAoJICogQG9yZGVyZWQKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVTQ1JJUFRJT05fRURFRkFVTFQgPSBudWxsOwoKCS8qKgoJICogVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlICd7QGxpbmsgI2dldFN0YXJ0VGltZSgpIDxlbT5TdGFydCBUaW1lPC9lbT59JyBhdHRyaWJ1dGUuCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAc2VlICNnZXRTdGFydFRpbWUoKQoJICogQGdlbmVyYXRlZAoJICogQG9yZGVyZWQKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBEYXRlIFNUQVJUX1RJTUVfRURFRkFVTFQgPSBudWxsOwoKCS8qKgoJICogVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlICd7QGxpbmsgI2dldEVuZFRpbWUoKSA8ZW0+RW5kIFRpbWU8L2VtPn0nIGF0dHJpYnV0ZS4KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBzZWUgI2dldEVuZFRpbWUoKQoJICogQGdlbmVyYXRlZAoJICogQG9yZGVyZWQKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBEYXRlIEVORF9USU1FX0VERUZBVUxUID0gbnVsbDsKCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJvdGVjdGVkIEFjdGl2aXR5SW1wbCgpIHsKCQlzdXBlcigpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAT3ZlcnJpZGUKCXByb3RlY3RlZCBFQ2xhc3MgZVN0YXRpY0NsYXNzKCkgewoJCXJldHVybiBQcm9jZXNzUGFja2FnZS5MaXRlcmFscy5BQ1RJVklUWTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHVibGljIFN0cmluZyBnZXRJZCgpIHsKCQlyZXR1cm4gKFN0cmluZyllRHluYW1pY0dldChQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fSUQsIEdlbmVyYWxQYWNrYWdlLkxpdGVyYWxzLk5BTUVEX0VMRU1FTlRfX0lELCB0cnVlLCB0cnVlKTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHVibGljIHZvaWQgc2V0SWQoU3RyaW5nIG5ld0lkKSB7CgkJZUR5bmFtaWNTZXQoUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX0lELCBHZW5lcmFsUGFja2FnZS5MaXRlcmFscy5OQU1FRF9FTEVNRU5UX19JRCwgbmV3SWQpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CgkJcmV0dXJuIChTdHJpbmcpZUR5bmFtaWNHZXQoUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX05BTUUsIEdlbmVyYWxQYWNrYWdlLkxpdGVyYWxzLk5BTUVEX0VMRU1FTlRfX05BTUUsIHRydWUsIHRydWUpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuZXdOYW1lKSB7CgkJZUR5bmFtaWNTZXQoUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX05BTUUsIEdlbmVyYWxQYWNrYWdlLkxpdGVyYWxzLk5BTUVEX0VMRU1FTlRfX05BTUUsIG5ld05hbWUpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgU3RyaW5nIGdldERlc2NyaXB0aW9uKCkgewoJCXJldHVybiAoU3RyaW5nKWVEeW5hbWljR2V0KFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19ERVNDUklQVElPTiwgR2VuZXJhbFBhY2thZ2UuTGl0ZXJhbHMuREVTQ1JJQkFCTEVfRUxFTUVOVF9fREVTQ1JJUFRJT04sIHRydWUsIHRydWUpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgdm9pZCBzZXREZXNjcmlwdGlvbihTdHJpbmcgbmV3RGVzY3JpcHRpb24pIHsKCQllRHluYW1pY1NldChQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fREVTQ1JJUFRJT04sIEdlbmVyYWxQYWNrYWdlLkxpdGVyYWxzLkRFU0NSSUJBQkxFX0VMRU1FTlRfX0RFU0NSSVBUSU9OLCBuZXdEZXNjcmlwdGlvbik7Cgl9CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXB1YmxpYyBEYXRlIGdldFN0YXJ0VGltZSgpIHsKCQlyZXR1cm4gKERhdGUpZUR5bmFtaWNHZXQoUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1NUQVJUX1RJTUUsIFByb2Nlc3NQYWNrYWdlLkxpdGVyYWxzLkFDVElWSVRZX19TVEFSVF9USU1FLCB0cnVlLCB0cnVlKTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHVibGljIHZvaWQgc2V0U3RhcnRUaW1lKERhdGUgbmV3U3RhcnRUaW1lKSB7CgkJZUR5bmFtaWNTZXQoUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1NUQVJUX1RJTUUsIFByb2Nlc3NQYWNrYWdlLkxpdGVyYWxzLkFDVElWSVRZX19TVEFSVF9USU1FLCBuZXdTdGFydFRpbWUpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgRGF0ZSBnZXRFbmRUaW1lKCkgewoJCXJldHVybiAoRGF0ZSllRHluYW1pY0dldChQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fRU5EX1RJTUUsIFByb2Nlc3NQYWNrYWdlLkxpdGVyYWxzLkFDVElWSVRZX19FTkRfVElNRSwgdHJ1ZSwgdHJ1ZSk7Cgl9CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXB1YmxpYyB2b2lkIHNldEVuZFRpbWUoRGF0ZSBuZXdFbmRUaW1lKSB7CgkJZUR5bmFtaWNTZXQoUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX0VORF9USU1FLCBQcm9jZXNzUGFja2FnZS5MaXRlcmFscy5BQ1RJVklUWV9fRU5EX1RJTUUsIG5ld0VuZFRpbWUpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKCXB1YmxpYyBFTGlzdDxBY3Rpdml0eT4gZ2V0U3ViQWN0aXZpdHkoKSB7CgkJcmV0dXJuIChFTGlzdDxBY3Rpdml0eT4pZUR5bmFtaWNHZXQoUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1NVQl9BQ1RJVklUWSwgUHJvY2Vzc1BhY2thZ2UuTGl0ZXJhbHMuQUNUSVZJVFlfX1NVQl9BQ1RJVklUWSwgdHJ1ZSwgdHJ1ZSk7Cgl9CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQoJcHVibGljIEVMaXN0PEFjdGl2aXR5PiBnZXRQcmVjZWRpbmdBY3Rpdml0eSgpIHsKCQlyZXR1cm4gKEVMaXN0PEFjdGl2aXR5PillRHluYW1pY0dldChQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fUFJFQ0VESU5HX0FDVElWSVRZLCBQcm9jZXNzUGFja2FnZS5MaXRlcmFscy5BQ1RJVklUWV9fUFJFQ0VESU5HX0FDVElWSVRZLCB0cnVlLCB0cnVlKTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCglwdWJsaWMgRUxpc3Q8UGFydGljaXBhbnQ+IGdldFBhcnRpY2lwYW50KCkgewoJCXJldHVybiAoRUxpc3Q8UGFydGljaXBhbnQ+KWVEeW5hbWljR2V0KFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19QQVJUSUNJUEFOVCwgUHJvY2Vzc1BhY2thZ2UuTGl0ZXJhbHMuQUNUSVZJVFlfX1BBUlRJQ0lQQU5ULCB0cnVlLCB0cnVlKTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCglwdWJsaWMgRUxpc3Q8VGVjaG5pcXVlPiBnZXRUZWNobmlxdWUoKSB7CgkJcmV0dXJuIChFTGlzdDxUZWNobmlxdWU+KWVEeW5hbWljR2V0KFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19URUNITklRVUUsIFByb2Nlc3NQYWNrYWdlLkxpdGVyYWxzLkFDVElWSVRZX19URUNITklRVUUsIHRydWUsIHRydWUpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKCXB1YmxpYyBFTGlzdDxBY3Rpdml0eVJlbD4gZ2V0T3duZWRSZWwoKSB7CgkJcmV0dXJuIChFTGlzdDxBY3Rpdml0eVJlbD4pZUR5bmFtaWNHZXQoUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX09XTkVEX1JFTCwgUHJvY2Vzc1BhY2thZ2UuTGl0ZXJhbHMuQUNUSVZJVFlfX09XTkVEX1JFTCwgdHJ1ZSwgdHJ1ZSk7Cgl9CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQoJcHVibGljIEVMaXN0PEFydGVmYWN0PiBnZXRSZXF1aXJlZEFydGVmYWN0KCkgewoJCXJldHVybiAoRUxpc3Q8QXJ0ZWZhY3Q+KWVEeW5hbWljR2V0KFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19SRVFVSVJFRF9BUlRFRkFDVCwgUHJvY2Vzc1BhY2thZ2UuTGl0ZXJhbHMuQUNUSVZJVFlfX1JFUVVJUkVEX0FSVEVGQUNULCB0cnVlLCB0cnVlKTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCglwdWJsaWMgRUxpc3Q8QXJ0ZWZhY3Q+IGdldFByb2R1Y2VkQXJ0ZWZhY3QoKSB7CgkJcmV0dXJuIChFTGlzdDxBcnRlZmFjdD4pZUR5bmFtaWNHZXQoUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1BST0RVQ0VEX0FSVEVGQUNULCBQcm9jZXNzUGFja2FnZS5MaXRlcmFscy5BQ1RJVklUWV9fUFJPRFVDRURfQVJURUZBQ1QsIHRydWUsIHRydWUpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKCXB1YmxpYyBFTGlzdDxBc3N1cmFuY2VBc3NldEV2ZW50PiBnZXRBc3NldEV2ZW50KCkgewoJCXJldHVybiAoRUxpc3Q8QXNzdXJhbmNlQXNzZXRFdmVudD4pZUR5bmFtaWNHZXQoUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX0FTU0VUX0VWRU5ULCBQcm9jZXNzUGFja2FnZS5MaXRlcmFscy5BQ1RJVklUWV9fQVNTRVRfRVZFTlQsIHRydWUsIHRydWUpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAT3ZlcnJpZGUKCXB1YmxpYyBOb3RpZmljYXRpb25DaGFpbiBlSW52ZXJzZVJlbW92ZShJbnRlcm5hbEVPYmplY3Qgb3RoZXJFbmQsIGludCBmZWF0dXJlSUQsIE5vdGlmaWNhdGlvbkNoYWluIG1zZ3MpIHsKCQlzd2l0Y2ggKGZlYXR1cmVJRCkgewoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19TVUJfQUNUSVZJVFk6CgkJCQlyZXR1cm4gKChJbnRlcm5hbEVMaXN0PD8+KWdldFN1YkFjdGl2aXR5KCkpLmJhc2ljUmVtb3ZlKG90aGVyRW5kLCBtc2dzKTsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fT1dORURfUkVMOgoJCQkJcmV0dXJuICgoSW50ZXJuYWxFTGlzdDw/PilnZXRPd25lZFJlbCgpKS5iYXNpY1JlbW92ZShvdGhlckVuZCwgbXNncyk7CgkJfQoJCXJldHVybiBzdXBlci5lSW52ZXJzZVJlbW92ZShvdGhlckVuZCwgZmVhdHVyZUlELCBtc2dzKTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQE92ZXJyaWRlCglwdWJsaWMgT2JqZWN0IGVHZXQoaW50IGZlYXR1cmVJRCwgYm9vbGVhbiByZXNvbHZlLCBib29sZWFuIGNvcmVUeXBlKSB7CgkJc3dpdGNoIChmZWF0dXJlSUQpIHsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fSUQ6CgkJCQlyZXR1cm4gZ2V0SWQoKTsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fTkFNRToKCQkJCXJldHVybiBnZXROYW1lKCk7CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX0RFU0NSSVBUSU9OOgoJCQkJcmV0dXJuIGdldERlc2NyaXB0aW9uKCk7CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1NUQVJUX1RJTUU6CgkJCQlyZXR1cm4gZ2V0U3RhcnRUaW1lKCk7CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX0VORF9USU1FOgoJCQkJcmV0dXJuIGdldEVuZFRpbWUoKTsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fU1VCX0FDVElWSVRZOgoJCQkJcmV0dXJuIGdldFN1YkFjdGl2aXR5KCk7CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1BSRUNFRElOR19BQ1RJVklUWToKCQkJCXJldHVybiBnZXRQcmVjZWRpbmdBY3Rpdml0eSgpOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19QQVJUSUNJUEFOVDoKCQkJCXJldHVybiBnZXRQYXJ0aWNpcGFudCgpOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19URUNITklRVUU6CgkJCQlyZXR1cm4gZ2V0VGVjaG5pcXVlKCk7CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX09XTkVEX1JFTDoKCQkJCXJldHVybiBnZXRPd25lZFJlbCgpOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19SRVFVSVJFRF9BUlRFRkFDVDoKCQkJCXJldHVybiBnZXRSZXF1aXJlZEFydGVmYWN0KCk7CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1BST0RVQ0VEX0FSVEVGQUNUOgoJCQkJcmV0dXJuIGdldFByb2R1Y2VkQXJ0ZWZhY3QoKTsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fQVNTRVRfRVZFTlQ6CgkJCQlyZXR1cm4gZ2V0QXNzZXRFdmVudCgpOwoJCX0KCQlyZXR1cm4gc3VwZXIuZUdldChmZWF0dXJlSUQsIHJlc29sdmUsIGNvcmVUeXBlKTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCglAT3ZlcnJpZGUKCXB1YmxpYyB2b2lkIGVTZXQoaW50IGZlYXR1cmVJRCwgT2JqZWN0IG5ld1ZhbHVlKSB7CgkJc3dpdGNoIChmZWF0dXJlSUQpIHsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fSUQ6CgkJCQlzZXRJZCgoU3RyaW5nKW5ld1ZhbHVlKTsKCQkJCXJldHVybjsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fTkFNRToKCQkJCXNldE5hbWUoKFN0cmluZyluZXdWYWx1ZSk7CgkJCQlyZXR1cm47CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX0RFU0NSSVBUSU9OOgoJCQkJc2V0RGVzY3JpcHRpb24oKFN0cmluZyluZXdWYWx1ZSk7CgkJCQlyZXR1cm47CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1NUQVJUX1RJTUU6CgkJCQlzZXRTdGFydFRpbWUoKERhdGUpbmV3VmFsdWUpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19FTkRfVElNRToKCQkJCXNldEVuZFRpbWUoKERhdGUpbmV3VmFsdWUpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19TVUJfQUNUSVZJVFk6CgkJCQlnZXRTdWJBY3Rpdml0eSgpLmNsZWFyKCk7CgkJCQlnZXRTdWJBY3Rpdml0eSgpLmFkZEFsbCgoQ29sbGVjdGlvbjw/IGV4dGVuZHMgQWN0aXZpdHk+KW5ld1ZhbHVlKTsKCQkJCXJldHVybjsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fUFJFQ0VESU5HX0FDVElWSVRZOgoJCQkJZ2V0UHJlY2VkaW5nQWN0aXZpdHkoKS5jbGVhcigpOwoJCQkJZ2V0UHJlY2VkaW5nQWN0aXZpdHkoKS5hZGRBbGwoKENvbGxlY3Rpb248PyBleHRlbmRzIEFjdGl2aXR5PiluZXdWYWx1ZSk7CgkJCQlyZXR1cm47CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1BBUlRJQ0lQQU5UOgoJCQkJZ2V0UGFydGljaXBhbnQoKS5jbGVhcigpOwoJCQkJZ2V0UGFydGljaXBhbnQoKS5hZGRBbGwoKENvbGxlY3Rpb248PyBleHRlbmRzIFBhcnRpY2lwYW50PiluZXdWYWx1ZSk7CgkJCQlyZXR1cm47CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1RFQ0hOSVFVRToKCQkJCWdldFRlY2huaXF1ZSgpLmNsZWFyKCk7CgkJCQlnZXRUZWNobmlxdWUoKS5hZGRBbGwoKENvbGxlY3Rpb248PyBleHRlbmRzIFRlY2huaXF1ZT4pbmV3VmFsdWUpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19PV05FRF9SRUw6CgkJCQlnZXRPd25lZFJlbCgpLmNsZWFyKCk7CgkJCQlnZXRPd25lZFJlbCgpLmFkZEFsbCgoQ29sbGVjdGlvbjw/IGV4dGVuZHMgQWN0aXZpdHlSZWw+KW5ld1ZhbHVlKTsKCQkJCXJldHVybjsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fUkVRVUlSRURfQVJURUZBQ1Q6CgkJCQlnZXRSZXF1aXJlZEFydGVmYWN0KCkuY2xlYXIoKTsKCQkJCWdldFJlcXVpcmVkQXJ0ZWZhY3QoKS5hZGRBbGwoKENvbGxlY3Rpb248PyBleHRlbmRzIEFydGVmYWN0PiluZXdWYWx1ZSk7CgkJCQlyZXR1cm47CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1BST0RVQ0VEX0FSVEVGQUNUOgoJCQkJZ2V0UHJvZHVjZWRBcnRlZmFjdCgpLmNsZWFyKCk7CgkJCQlnZXRQcm9kdWNlZEFydGVmYWN0KCkuYWRkQWxsKChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBBcnRlZmFjdD4pbmV3VmFsdWUpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19BU1NFVF9FVkVOVDoKCQkJCWdldEFzc2V0RXZlbnQoKS5jbGVhcigpOwoJCQkJZ2V0QXNzZXRFdmVudCgpLmFkZEFsbCgoQ29sbGVjdGlvbjw/IGV4dGVuZHMgQXNzdXJhbmNlQXNzZXRFdmVudD4pbmV3VmFsdWUpOwoJCQkJcmV0dXJuOwoJCX0KCQlzdXBlci5lU2V0KGZlYXR1cmVJRCwgbmV3VmFsdWUpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAT3ZlcnJpZGUKCXB1YmxpYyB2b2lkIGVVbnNldChpbnQgZmVhdHVyZUlEKSB7CgkJc3dpdGNoIChmZWF0dXJlSUQpIHsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fSUQ6CgkJCQlzZXRJZChJRF9FREVGQVVMVCk7CgkJCQlyZXR1cm47CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX05BTUU6CgkJCQlzZXROYW1lKE5BTUVfRURFRkFVTFQpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19ERVNDUklQVElPTjoKCQkJCXNldERlc2NyaXB0aW9uKERFU0NSSVBUSU9OX0VERUZBVUxUKTsKCQkJCXJldHVybjsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fU1RBUlRfVElNRToKCQkJCXNldFN0YXJ0VGltZShTVEFSVF9USU1FX0VERUZBVUxUKTsKCQkJCXJldHVybjsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fRU5EX1RJTUU6CgkJCQlzZXRFbmRUaW1lKEVORF9USU1FX0VERUZBVUxUKTsKCQkJCXJldHVybjsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fU1VCX0FDVElWSVRZOgoJCQkJZ2V0U3ViQWN0aXZpdHkoKS5jbGVhcigpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19QUkVDRURJTkdfQUNUSVZJVFk6CgkJCQlnZXRQcmVjZWRpbmdBY3Rpdml0eSgpLmNsZWFyKCk7CgkJCQlyZXR1cm47CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1BBUlRJQ0lQQU5UOgoJCQkJZ2V0UGFydGljaXBhbnQoKS5jbGVhcigpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19URUNITklRVUU6CgkJCQlnZXRUZWNobmlxdWUoKS5jbGVhcigpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19PV05FRF9SRUw6CgkJCQlnZXRPd25lZFJlbCgpLmNsZWFyKCk7CgkJCQlyZXR1cm47CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1JFUVVJUkVEX0FSVEVGQUNUOgoJCQkJZ2V0UmVxdWlyZWRBcnRlZmFjdCgpLmNsZWFyKCk7CgkJCQlyZXR1cm47CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1BST0RVQ0VEX0FSVEVGQUNUOgoJCQkJZ2V0UHJvZHVjZWRBcnRlZmFjdCgpLmNsZWFyKCk7CgkJCQlyZXR1cm47CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX0FTU0VUX0VWRU5UOgoJCQkJZ2V0QXNzZXRFdmVudCgpLmNsZWFyKCk7CgkJCQlyZXR1cm47CgkJfQoJCXN1cGVyLmVVbnNldChmZWF0dXJlSUQpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAT3ZlcnJpZGUKCXB1YmxpYyBib29sZWFuIGVJc1NldChpbnQgZmVhdHVyZUlEKSB7CgkJc3dpdGNoIChmZWF0dXJlSUQpIHsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fSUQ6CgkJCQlyZXR1cm4gSURfRURFRkFVTFQgPT0gbnVsbCA/IGdldElkKCkgIT0gbnVsbCA6ICFJRF9FREVGQVVMVC5lcXVhbHMoZ2V0SWQoKSk7CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX05BTUU6CgkJCQlyZXR1cm4gTkFNRV9FREVGQVVMVCA9PSBudWxsID8gZ2V0TmFtZSgpICE9IG51bGwgOiAhTkFNRV9FREVGQVVMVC5lcXVhbHMoZ2V0TmFtZSgpKTsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fREVTQ1JJUFRJT046CgkJCQlyZXR1cm4gREVTQ1JJUFRJT05fRURFRkFVTFQgPT0gbnVsbCA/IGdldERlc2NyaXB0aW9uKCkgIT0gbnVsbCA6ICFERVNDUklQVElPTl9FREVGQVVMVC5lcXVhbHMoZ2V0RGVzY3JpcHRpb24oKSk7CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1NUQVJUX1RJTUU6CgkJCQlyZXR1cm4gU1RBUlRfVElNRV9FREVGQVVMVCA9PSBudWxsID8gZ2V0U3RhcnRUaW1lKCkgIT0gbnVsbCA6ICFTVEFSVF9USU1FX0VERUZBVUxULmVxdWFscyhnZXRTdGFydFRpbWUoKSk7CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX0VORF9USU1FOgoJCQkJcmV0dXJuIEVORF9USU1FX0VERUZBVUxUID09IG51bGwgPyBnZXRFbmRUaW1lKCkgIT0gbnVsbCA6ICFFTkRfVElNRV9FREVGQVVMVC5lcXVhbHMoZ2V0RW5kVGltZSgpKTsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fU1VCX0FDVElWSVRZOgoJCQkJcmV0dXJuICFnZXRTdWJBY3Rpdml0eSgpLmlzRW1wdHkoKTsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fUFJFQ0VESU5HX0FDVElWSVRZOgoJCQkJcmV0dXJuICFnZXRQcmVjZWRpbmdBY3Rpdml0eSgpLmlzRW1wdHkoKTsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fUEFSVElDSVBBTlQ6CgkJCQlyZXR1cm4gIWdldFBhcnRpY2lwYW50KCkuaXNFbXB0eSgpOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19URUNITklRVUU6CgkJCQlyZXR1cm4gIWdldFRlY2huaXF1ZSgpLmlzRW1wdHkoKTsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fT1dORURfUkVMOgoJCQkJcmV0dXJuICFnZXRPd25lZFJlbCgpLmlzRW1wdHkoKTsKCQkJY2FzZSBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fUkVRVUlSRURfQVJURUZBQ1Q6CgkJCQlyZXR1cm4gIWdldFJlcXVpcmVkQXJ0ZWZhY3QoKS5pc0VtcHR5KCk7CgkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX1BST0RVQ0VEX0FSVEVGQUNUOgoJCQkJcmV0dXJuICFnZXRQcm9kdWNlZEFydGVmYWN0KCkuaXNFbXB0eSgpOwoJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19BU1NFVF9FVkVOVDoKCQkJCXJldHVybiAhZ2V0QXNzZXRFdmVudCgpLmlzRW1wdHkoKTsKCQl9CgkJcmV0dXJuIHN1cGVyLmVJc1NldChmZWF0dXJlSUQpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAT3ZlcnJpZGUKCXB1YmxpYyBpbnQgZUJhc2VTdHJ1Y3R1cmFsRmVhdHVyZUlEKGludCBkZXJpdmVkRmVhdHVyZUlELCBDbGFzczw/PiBiYXNlQ2xhc3MpIHsKCQlpZiAoYmFzZUNsYXNzID09IE5hbWVkRWxlbWVudC5jbGFzcykgewoJCQlzd2l0Y2ggKGRlcml2ZWRGZWF0dXJlSUQpIHsKCQkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX0lEOiByZXR1cm4gR2VuZXJhbFBhY2thZ2UuTkFNRURfRUxFTUVOVF9fSUQ7CgkJCQljYXNlIFByb2Nlc3NQYWNrYWdlLkFDVElWSVRZX19OQU1FOiByZXR1cm4gR2VuZXJhbFBhY2thZ2UuTkFNRURfRUxFTUVOVF9fTkFNRTsKCQkJCWRlZmF1bHQ6IHJldHVybiAtMTsKCQkJfQoJCX0KCQlpZiAoYmFzZUNsYXNzID09IERlc2NyaWJhYmxlRWxlbWVudC5jbGFzcykgewoJCQlzd2l0Y2ggKGRlcml2ZWRGZWF0dXJlSUQpIHsKCQkJCWNhc2UgUHJvY2Vzc1BhY2thZ2UuQUNUSVZJVFlfX0RFU0NSSVBUSU9OOiByZXR1cm4gR2VuZXJhbFBhY2thZ2UuREVTQ1JJQkFCTEVfRUxFTUVOVF9fREVTQ1JJUFRJT047CgkJCQlkZWZhdWx0OiByZXR1cm4gLTE7CgkJCX0KCQl9CgkJcmV0dXJuIHN1cGVyLmVCYXNlU3RydWN0dXJhbEZlYXR1cmVJRChkZXJpdmVkRmVhdHVyZUlELCBiYXNlQ2xhc3MpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAT3ZlcnJpZGUKCXB1YmxpYyBpbnQgZURlcml2ZWRTdHJ1Y3R1cmFsRmVhdHVyZUlEKGludCBiYXNlRmVhdHVyZUlELCBDbGFzczw/PiBiYXNlQ2xhc3MpIHsKCQlpZiAoYmFzZUNsYXNzID09IE5hbWVkRWxlbWVudC5jbGFzcykgewoJCQlzd2l0Y2ggKGJhc2VGZWF0dXJlSUQpIHsKCQkJCWNhc2UgR2VuZXJhbFBhY2thZ2UuTkFNRURfRUxFTUVOVF9fSUQ6IHJldHVybiBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fSUQ7CgkJCQljYXNlIEdlbmVyYWxQYWNrYWdlLk5BTUVEX0VMRU1FTlRfX05BTUU6IHJldHVybiBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fTkFNRTsKCQkJCWRlZmF1bHQ6IHJldHVybiAtMTsKCQkJfQoJCX0KCQlpZiAoYmFzZUNsYXNzID09IERlc2NyaWJhYmxlRWxlbWVudC5jbGFzcykgewoJCQlzd2l0Y2ggKGJhc2VGZWF0dXJlSUQpIHsKCQkJCWNhc2UgR2VuZXJhbFBhY2thZ2UuREVTQ1JJQkFCTEVfRUxFTUVOVF9fREVTQ1JJUFRJT046IHJldHVybiBQcm9jZXNzUGFja2FnZS5BQ1RJVklUWV9fREVTQ1JJUFRJT047CgkJCQlkZWZhdWx0OiByZXR1cm4gLTE7CgkJCX0KCQl9CgkJcmV0dXJuIHN1cGVyLmVEZXJpdmVkU3RydWN0dXJhbEZlYXR1cmVJRChiYXNlRmVhdHVyZUlELCBiYXNlQ2xhc3MpOwoJfQoKfSAvL0FjdGl2aXR5SW1wbAo=