cGFja2FnZSBvcmcuZWNsaXBzZS51aS5leHRlcm5hbHRvb2xzLmludGVybmFsLnVpLmFudDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCkNvcHlyaWdodCAoYykgMjAwMiBJQk0gQ29ycC4gYW5kIG90aGVycy4KQWxsIHJpZ2h0cyByZXNlcnZlZC4goCBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCmFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MC41CndoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Cmh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYwNS5odG1sCqAKQ29udHJpYnV0b3JzOgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwppbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKCmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC4qOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5EaXNwbGF5OwppbXBvcnQgb3JnLmVjbGlwc2UudWkuZXh0ZXJuYWx0b29scy5pbnRlcm5hbC5jb3JlLio7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5leHRlcm5hbHRvb2xzLmludGVybmFsLnVpLio7CgpwdWJsaWMgY2xhc3MgQW50QnVpbGRMb2dnZXIgaW1wbGVtZW50cyBCdWlsZExvZ2dlciB7CgoJcHJvdGVjdGVkIGludCBwcmlvcml0eUZpbHRlciA9IExvZ0NvbnNvbGVEb2N1bWVudC5NU0dfSU5GTzsKCXByaXZhdGUgaW50IGxvZ0xlbmd0aCA9IDA7Cglwcml2YXRlIGludCBsYXN0VGFyZ2V0RW5kSW5kZXggPSAwOwoKCXB1YmxpYyBBbnRCdWlsZExvZ2dlcigpIHsKCX0KCgkvKioKCSAqIEBzZWUgQnVpbGRMaXN0ZW5lciNidWlsZFN0YXJ0ZWQoQnVpbGRFdmVudCkKCSAqLwoJcHVibGljIHZvaWQgYnVpbGRTdGFydGVkKEJ1aWxkRXZlbnQgZXZlbnQpIHsKCX0KCgkvKioKCSAqIEBzZWUgQnVpbGRMaXN0ZW5lciNidWlsZEZpbmlzaGVkKEJ1aWxkRXZlbnQpCgkgKi8KCXB1YmxpYyB2b2lkIGJ1aWxkRmluaXNoZWQoQnVpbGRFdmVudCBldmVudCkgewoJCWhhbmRsZUV4Y2VwdGlvbihldmVudCk7Cgl9CgoJcHJvdGVjdGVkIHZvaWQgaGFuZGxlRXhjZXB0aW9uKEJ1aWxkRXZlbnQgZXZlbnQpIHsKCQlUaHJvd2FibGUgZXhjZXB0aW9uID0gZXZlbnQuZ2V0RXhjZXB0aW9uKCk7CgkJaWYgKGV4Y2VwdGlvbiA9PSBudWxsKQoJCQlyZXR1cm47CgkJbG9nTWVzc2FnZSgKCQkJVG9vbE1lc3NhZ2VzLmZvcm1hdCgKCQkJCSJBbnRCdWlsZExvZ2dlci5idWlsZEV4Y2VwdGlvbiIsIC8vICROT04tTkxTLTEkCgkJCQluZXcgU3RyaW5nW10geyBleGNlcHRpb24udG9TdHJpbmcoKX0pLAoJCQlMb2dDb25zb2xlRG9jdW1lbnQuTVNHX0VSUik7CQoJfQoKCS8qKgoJICogQHNlZSBCdWlsZExpc3RlbmVyI3RhcmdldFN0YXJ0ZWQoQnVpbGRFdmVudCkKCSAqLwoJcHVibGljIHZvaWQgdGFyZ2V0U3RhcnRlZChCdWlsZEV2ZW50IGV2ZW50KSB7CgkJY3JlYXRlTmV3T3V0cHV0U3RydWN0dXJlRWxlbWVudChldmVudC5nZXRUYXJnZXQoKS5nZXROYW1lKCksIGxvZ0xlbmd0aCk7Cgl9CgoJcHJvdGVjdGVkIHZvaWQgcmVmcmVzaENvbnNvbGVUcmVlcygpIHsKCQlmaW5hbCBMb2dDb25zb2xlRG9jdW1lbnQgZG9jID0gTG9nQ29uc29sZURvY3VtZW50LmdldEluc3RhbmNlKCk7CgkJaWYgKCFkb2MuaGFzVmlld3MoKSkKCQkJcmV0dXJuOwoJCS8vIHdlIGdldCB0aGUgZGlzcGxheSBmcm9tIHRoZSBjb25zb2xlICMwICh0aGF0IGV4aXN0cyBmb3Igc3VyZSBiZWNhdXNlIGNvbnNvbGVzIT1udWxsKQoJCURpc3BsYXkgZGlzcGxheSA9IGRvYy5nZXREaXNwbGF5KCk7CgkJLy8gY3JlYXRlIGEgbmV3IHRocmVhZCBmb3Igc3luY2hyb25pemluZyBhbGwgdGhlIHJlZnJlc2ggb3BlcmF0aW9ucwoJCWRpc3BsYXkuc3luY0V4ZWMobmV3IFJ1bm5hYmxlKCkgewoJCQlwdWJsaWMgdm9pZCBydW4oKSB7CgkJCQlkb2MucmVmcmVzaFRyZWUoKTsKCQkJfQoJCX0pOwoJfQoKCXByb3RlY3RlZCB2b2lkIGNyZWF0ZU5ld091dHB1dFN0cnVjdHVyZUVsZW1lbnQoU3RyaW5nIG5hbWUsIGludCBpbmRleCkgewoJCUxvZ0NvbnNvbGVEb2N1bWVudCBkb2MgPSBMb2dDb25zb2xlRG9jdW1lbnQuZ2V0SW5zdGFuY2UoKTsKCQlPdXRwdXRTdHJ1Y3R1cmVFbGVtZW50IG5ld0VsZW1lbnQgPQoJCQluZXcgT3V0cHV0U3RydWN0dXJlRWxlbWVudCgKCQkJCW5hbWUsCgkJCQlkb2MuZ2V0Q3VycmVudE91dHB1dFN0cnVjdHVyZUVsZW1lbnQoKSwKCQkJCWluZGV4KTsKCQlkb2Muc2V0Q3VycmVudE91dHB1dFN0cnVjdHVyZUVsZW1lbnQobmV3RWxlbWVudCk7Cgl9CgoJLyoqCgkgKiBAc2VlIEJ1aWxkTGlzdGVuZXIjdGFyZ2V0RmluaXNoZWQoQnVpbGRFdmVudCkKCSAqLwoJcHVibGljIHZvaWQgdGFyZ2V0RmluaXNoZWQoQnVpbGRFdmVudCBldmVudCkgewoJCWhhbmRsZUV4Y2VwdGlvbihldmVudCk7CgkJZmluaXNoQ3VycmVudE91dHB1dFN0cnVjdHVyZUVsZW1lbnQoKTsKCQkvLyBzdG9yZSB0aGUgZW5kIGluZGV4IG9mIHRoaXMgdGFyZ2V0J3MgbG9nIChzbyB0aGF0IHdlIGNhbiB1c2UgaXQgbGF0ZXIpCgkJbGFzdFRhcmdldEVuZEluZGV4ID0gbG9nTGVuZ3RoOwoJCXJlZnJlc2hDb25zb2xlVHJlZXMoKTsKCX0KCgkvKioKCSAqIEBzZWUgQnVpbGRMaXN0ZW5lciN0YXNrU3RhcnRlZChCdWlsZEV2ZW50KQoJICovCglwdWJsaWMgdm9pZCB0YXNrU3RhcnRlZChCdWlsZEV2ZW50IGV2ZW50KSB7CgkJY3JlYXRlTmV3T3V0cHV0U3RydWN0dXJlRWxlbWVudChldmVudC5nZXRUYXNrKCkuZ2V0VGFza05hbWUoKSk7Cgl9CgoJLyoqCgkgKiBAc2VlIEJ1aWxkTGlzdGVuZXIjdGFza0ZpbmlzaGVkKEJ1aWxkRXZlbnQpCgkgKi8KCXB1YmxpYyB2b2lkIHRhc2tGaW5pc2hlZChCdWlsZEV2ZW50IGV2ZW50KSB7CgkJaGFuZGxlRXhjZXB0aW9uKGV2ZW50KTsKCQlmaW5pc2hDdXJyZW50T3V0cHV0U3RydWN0dXJlRWxlbWVudCgpOwoJCXJlZnJlc2hDb25zb2xlVHJlZXMoKTsKCX0KCgkvKioKCSAqIEBzZWUgQnVpbGRMaXN0ZW5lciNtZXNzYWdlTG9nZ2VkKEJ1aWxkRXZlbnQpCgkgKi8KCXB1YmxpYyB2b2lkIG1lc3NhZ2VMb2dnZWQoQnVpbGRFdmVudCBldmVudCkgewoJCWxvZ01lc3NhZ2UoZXZlbnQuZ2V0TWVzc2FnZSgpLCB0b0NvbnNvbGVQcmlvcml0eShldmVudC5nZXRQcmlvcml0eSgpKSk7Cgl9CgkKCS8qKgoJICogQ29udmVydHMgYSBBbnQgcHJvamVjdCdzIHByaW9yaXR5IGxldmVsIHRvIGEgcHJpb3JpdHkKCSAqIGxldmVsIHVzZWQgYnkgdGhlIExvZyBDb25zb2xlLgoJICovCglwcml2YXRlIGludCB0b0NvbnNvbGVQcmlvcml0eShpbnQgYW50UHJpb3JpdHkpIHsKCQlzd2l0Y2ggKGFudFByaW9yaXR5KSB7CgkJCWNhc2UgUHJvamVjdC5NU0dfRVJSOgoJCQkJcmV0dXJuIExvZ0NvbnNvbGVEb2N1bWVudC5NU0dfRVJSOwoJCQljYXNlIFByb2plY3QuTVNHX1dBUk46CgkJCQlyZXR1cm4gTG9nQ29uc29sZURvY3VtZW50Lk1TR19XQVJOOwkKCQkJY2FzZSBQcm9qZWN0Lk1TR19JTkZPOgoJCQkJcmV0dXJuIExvZ0NvbnNvbGVEb2N1bWVudC5NU0dfSU5GTzsJCgkJCWNhc2UgUHJvamVjdC5NU0dfVkVSQk9TRToKCQkJCXJldHVybiBMb2dDb25zb2xlRG9jdW1lbnQuTVNHX1ZFUkJPU0U7CQoJCQljYXNlIFByb2plY3QuTVNHX0RFQlVHOgoJCQkJcmV0dXJuIExvZ0NvbnNvbGVEb2N1bWVudC5NU0dfREVCVUc7CQoJCQlkZWZhdWx0OgoJCQkJcmV0dXJuIExvZ0NvbnNvbGVEb2N1bWVudC5NU0dfSU5GTzsJCgkJfQoJfQoKCXByb3RlY3RlZCB2b2lkIGxvZ01lc3NhZ2UoU3RyaW5nIG1lc3NhZ2UsIGludCBwcmlvcml0eSkgewoJCWlmIChwcmlvcml0eSA+IHByaW9yaXR5RmlsdGVyKQoJCQlyZXR1cm47CgkJbWVzc2FnZSArPSAnXG4nOwoJCUxvZ0NvbnNvbGVEb2N1bWVudCBkb2MgPSBMb2dDb25zb2xlRG9jdW1lbnQuZ2V0SW5zdGFuY2UoKTsKCQlkb2MuYXBwZW5kKG1lc3NhZ2UsIHByaW9yaXR5KTsKCQlsb2dMZW5ndGggKz0gbWVzc2FnZS5sZW5ndGgoKTsKCX0KCglwcm90ZWN0ZWQgdm9pZCBmaW5pc2hDdXJyZW50T3V0cHV0U3RydWN0dXJlRWxlbWVudCgpIHsKCQlMb2dDb25zb2xlRG9jdW1lbnQgZG9jID0gTG9nQ29uc29sZURvY3VtZW50LmdldEluc3RhbmNlKCk7CgkJLy8gc2V0cyB0aGUgaW5kZXggdGhhdCBpbmRpY2F0ZXMgdGhlIGVuZCBvZiB0aGUgbG9nIHBhcnQgbGlua2VkIHRvIHRoaXMgZWxlbWVudAoJCU91dHB1dFN0cnVjdHVyZUVsZW1lbnQgb3V0cHV0ID0gZG9jLmdldEN1cnJlbnRPdXRwdXRTdHJ1Y3R1cmVFbGVtZW50KCk7CgkJb3V0cHV0LnNldEVuZEluZGV4KGxvZ0xlbmd0aCk7CgkJLy8gYW5kIHNldHMgdGhlIGN1cnJlbnQgZWxlbWVudCB0byB0aGUgcGFyZW50IG9mIHRoZSBlbGVtZW50CgkJZG9jLnNldEN1cnJlbnRPdXRwdXRTdHJ1Y3R1cmVFbGVtZW50KG91dHB1dC5nZXRQYXJlbnQoKSk7Cgl9CgoJcHJvdGVjdGVkIHZvaWQgY3JlYXRlTmV3T3V0cHV0U3RydWN0dXJlRWxlbWVudChTdHJpbmcgbmFtZSkgewoJCWNyZWF0ZU5ld091dHB1dFN0cnVjdHVyZUVsZW1lbnQobmFtZSwgbG9nTGVuZ3RoKTsKCX0KCglwdWJsaWMgdm9pZCBzZXRNZXNzYWdlT3V0cHV0TGV2ZWwoaW50IGxldmVsKSB7CgkJdGhpcy5wcmlvcml0eUZpbHRlciA9IHRvQ29uc29sZVByaW9yaXR5KGxldmVsKTsKCX0KCglwdWJsaWMgdm9pZCBzZXRFbWFjc01vZGUoYm9vbGVhbiBlbWFjc01vZGUpIHsKCX0KCglwdWJsaWMgdm9pZCBzZXRFcnJvclByaW50U3RyZWFtKFByaW50U3RyZWFtIGVycikgewoJfQoKCXB1YmxpYyB2b2lkIHNldE91dHB1dFByaW50U3RyZWFtKFByaW50U3RyZWFtIG91dHB1dCkgewoJfQoJcHJpdmF0ZSBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3JGb3IoSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB7CgkJaWYgKG1vbml0b3IgPT0gbnVsbCkKCQkJcmV0dXJuIG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCk7CgkJcmV0dXJuIG1vbml0b3I7Cgl9Cn0=