LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5odG1sLmNvcmUuaW50ZXJuYWwuY2xlYW51cDsKCgoKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CgppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UudGV4dC5CYWRMb2NhdGlvbkV4Y2VwdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnRleHQuZWRpdHMuSW5zZXJ0RWRpdDsKaW1wb3J0IG9yZy5lY2xpcHNlLnRleHQuZWRpdHMuTXVsdGlUZXh0RWRpdDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5jc3MuY29yZS5pbnRlcm5hbC5mb3JtYXQuQ1NTU291cmNlRm9ybWF0dGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmNzcy5jb3JlLmludGVybmFsLnByb3Zpc2lvbmFsLmFkYXB0ZXJzLklTdHlsZURlY2xhcmF0aW9uQWRhcHRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5jc3MuY29yZS5pbnRlcm5hbC5wcm92aXNpb25hbC5kb2N1bWVudC5JQ1NTTW9kZWw7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuY3NzLmNvcmUuaW50ZXJuYWwucHJvdmlzaW9uYWwuZG9jdW1lbnQuSUNTU05vZGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuaHRtbC5jb3JlLmludGVybmFsLnByZWZlcmVuY2VzLkhUTUxDb3JlUHJlZmVyZW5jZU5hbWVzOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlLmludGVybmFsLmNsZWFudXAuSVN0cnVjdHVyZWRDbGVhbnVwSGFuZGxlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS5pbnRlcm5hbC5wcm92aXNpb25hbC5JTm9kZUFkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUuaW50ZXJuYWwucHJvdmlzaW9uYWwuSU5vZGVOb3RpZmllcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS5pbnRlcm5hbC5wcm92aXNpb25hbC5leGNlcHRpb25zLlNvdXJjZUVkaXRpbmdSdW50aW1lRXhjZXB0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlLmludGVybmFsLnByb3Zpc2lvbmFsLnRleHQuSVN0cnVjdHVyZWREb2N1bWVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS5pbnRlcm5hbC5wcm92aXNpb25hbC50ZXh0LklTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb247CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUuaW50ZXJuYWwucHJvdmlzaW9uYWwudGV4dC5JVGV4dFJlZ2lvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS5pbnRlcm5hbC5wcm92aXNpb25hbC50ZXh0LklUZXh0UmVnaW9uTGlzdDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS5pbnRlcm5hbC51dGlsLlN0cmluZ1V0aWxzOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnhtbC5jb3JlLmludGVybmFsLmNvbnRlbnRtb2RlbC5DTUF0dHJpYnV0ZURlY2xhcmF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnhtbC5jb3JlLmludGVybmFsLmNvbnRlbnRtb2RlbC5DTUVsZW1lbnREZWNsYXJhdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwuY29yZS5pbnRlcm5hbC5jb250ZW50bW9kZWwuQ01OYW1lZE5vZGVNYXA7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QueG1sLmNvcmUuaW50ZXJuYWwuY29udGVudG1vZGVsLm1vZGVscXVlcnkuTW9kZWxRdWVyeTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwuY29yZS5pbnRlcm5hbC5tb2RlbHF1ZXJ5Lk1vZGVsUXVlcnlVdGlsOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnhtbC5jb3JlLmludGVybmFsLnByb3Zpc2lvbmFsLmRvY3VtZW50LklET01BdHRyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnhtbC5jb3JlLmludGVybmFsLnByb3Zpc2lvbmFsLmRvY3VtZW50LklET01Eb2N1bWVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwuY29yZS5pbnRlcm5hbC5wcm92aXNpb25hbC5kb2N1bWVudC5JRE9NRWxlbWVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwuY29yZS5pbnRlcm5hbC5wcm92aXNpb25hbC5kb2N1bWVudC5JRE9NTW9kZWw7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QueG1sLmNvcmUuaW50ZXJuYWwucHJvdmlzaW9uYWwuZG9jdW1lbnQuSURPTU5vZGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QueG1sLmNvcmUuaW50ZXJuYWwucHJvdmlzaW9uYWwuZG9jdW1lbnQuSVNvdXJjZUdlbmVyYXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwuY29yZS5pbnRlcm5hbC5yZWdpb25zLkRPTVJlZ2lvbkNvbnRleHQ7CmltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwppbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CmltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwppbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwppbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKCi8vIG5ha2Ftb3JpX1RPRE86IGNoZWNrIGFuZCByZW1vdmUgQ1NTIGZvcm1hdHRpbmcKCnB1YmxpYyBjbGFzcyBFbGVtZW50Tm9kZUNsZWFudXBIYW5kbGVyIGV4dGVuZHMgQWJzdHJhY3ROb2RlQ2xlYW51cEhhbmRsZXIgewoKCS8qKiBOb24tTkxTIHN0cmluZ3MgKi8KCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNUQVJUX1RBR19PUEVOID0gIjwiOyAvLyROT04tTkxTLTEkCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFTkRfVEFHX09QRU4gPSAiPC8iOyAvLyROT04tTkxTLTEkCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBUQUdfQ0xPU0UgPSAiPiI7IC8vJE5PTi1OTFMtMSQKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZX1RBR19DTE9TRSA9ICIvPiI7IC8vJE5PTi1OTFMtMSQKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNJTkdMRV9RVU9URVMgPSAiJyciOyAvLyROT04tTkxTLTEkCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBET1VCTEVfUVVPVEVTID0gIlwiXCIiOyAvLyROT04tTkxTLTEkCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGNoYXIgU0lOR0xFX1FVT1RFID0gJ1wnJzsgLy8kTk9OLU5MUy0xJAoJcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBjaGFyIERPVUJMRV9RVU9URSA9ICdcIic7IC8vJE5PTi1OTFMtMSQKCglwdWJsaWMgTm9kZSBjbGVhbnVwKE5vZGUgbm9kZSkgewoJCUlET01Ob2RlIHJlbmFtZWROb2RlID0gKElET01Ob2RlKSBjbGVhbnVwQ2hpbGRyZW4obm9kZSk7CgoJCS8vIGNhbGwgcXVvdGVBdHRyVmFsdWUoKSBmaXJzdCBzbyBpdCB3aWxsIGNsb3NlIGFueSB1bmNsb3NlZCBhdHRyCgkJLy8gcXVvdGVBdHRyVmFsdWUoKSB3aWxsIHJldHVybiB0aGUgbmV3IHN0YXJ0IHRhZyBpZiB0aGVyZSBpcyBhIHN0cnVjdHVyZSBjaGFuZ2UKCQlyZW5hbWVkTm9kZSA9IHF1b3RlQXR0clZhbHVlKHJlbmFtZWROb2RlKTsKCgkJLy8gaW5zZXJ0IHRhZyBjbG9zZSBpZiBtaXNzaW5nCgkJLy8gaWYgbm9kZSBpcyBub3QgY29tbWVudCB0YWcKCQkvLyBhbmQgbm90IGltcGxpY2l0IHRhZwoJCWlmICghKChJRE9NRWxlbWVudCkgcmVuYW1lZE5vZGUpLmlzQ29tbWVudFRhZygpICYmIChyZW5hbWVkTm9kZS5nZXRTdGFydFN0cnVjdHVyZWREb2N1bWVudFJlZ2lvbigpICE9IG51bGwpKSB7CgkJCUlET01Nb2RlbCBzdHJ1Y3R1cmVkTW9kZWwgPSByZW5hbWVkTm9kZS5nZXRNb2RlbCgpOwoKCQkJLy8gc2F2ZSBzdGFydCBvZmZzZXQgYmVmb3JlIGluc2VydFRhZ0Nsb3NlKCkKCQkJLy8gb3IgZWxzZSByZW5hbWVkTm9kZS5nZXRTdGFydE9mZnNldCgpIHdpbGwgYmUgemVybyBpZiByZW5hbWVkTm9kZSByZXBsYWNlZCBieSBpbnNlcnRUYWdDbG9zZSgpCgkJCWludCBzdGFydFRhZ1N0YXJ0T2Zmc2V0ID0gcmVuYW1lZE5vZGUuZ2V0U3RhcnRPZmZzZXQoKTsKCgkJCS8vIGZvciBzdGFydCB0YWcKCQkJSVN0cnVjdHVyZWREb2N1bWVudFJlZ2lvbiBzdGFydFRhZ1N0cnVjdHVyZWREb2N1bWVudFJlZ2lvbiA9IHJlbmFtZWROb2RlLmdldFN0YXJ0U3RydWN0dXJlZERvY3VtZW50UmVnaW9uKCk7CgkJCWluc2VydFRhZ0Nsb3NlKHN0cnVjdHVyZWRNb2RlbCwgc3RhcnRUYWdTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24pOwoKCQkJLy8gdXBkYXRlIHJlbmFtZWROb2RlIGFuZCBzdGFydFRhZ1N0cnVjdHVyZWREb2N1bWVudFJlZ2lvbiBhZnRlciBpbnNlcnRUYWdDbG9zZSgpCgkJCXJlbmFtZWROb2RlID0gKElET01Ob2RlKSBzdHJ1Y3R1cmVkTW9kZWwuZ2V0SW5kZXhlZFJlZ2lvbihzdGFydFRhZ1N0YXJ0T2Zmc2V0KTsKCQkJc3RhcnRUYWdTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gPSByZW5hbWVkTm9kZS5nZXRTdGFydFN0cnVjdHVyZWREb2N1bWVudFJlZ2lvbigpOwoKCQkJLy8gZm9yIGVuZCB0YWcKCQkJSVN0cnVjdHVyZWREb2N1bWVudFJlZ2lvbiBlbmRUYWdTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gPSByZW5hbWVkTm9kZS5nZXRFbmRTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24oKTsKCQkJaWYgKGVuZFRhZ1N0cnVjdHVyZWREb2N1bWVudFJlZ2lvbiAhPSBzdGFydFRhZ1N0cnVjdHVyZWREb2N1bWVudFJlZ2lvbikKCQkJCWluc2VydFRhZ0Nsb3NlKHN0cnVjdHVyZWRNb2RlbCwgZW5kVGFnU3RydWN0dXJlZERvY3VtZW50UmVnaW9uKTsKCQl9CgoJCS8vIGNhbGwgaW5zZXJ0TWlzc2luZ1RhZ3MoKSBuZXh0LCBpdCB3aWxsIGdlbmVyYXRlIGltcGxpY2l0IHRhZ3MgaWYgdGhlcmUgYXJlIGFueQoJCS8vIGluc2VydE1pc3NpbmdUYWdzKCkgd2lsbCByZXR1cm4gdGhlIG5ldyBtaXNzaW5nIHN0YXJ0IHRhZyBpZiBvbmUgaXMgbWlzc2luZwoJCS8vIGFwcGx5VGFnTmFtZUNhc2UoKSB3aWxsIHJldHVybiB0aGUgcmVuYW1lZCBub2RlLgoJCS8vIFRoZSByZW5hbWVkL25ldyBub2RlIHdpbGwgYmUgc2F2ZWQgYW5kIHJldHVybmVkIHRvIGNhbGxlciB3aGVuIGFsbCBjbGVhbnVwIGlzIGRvbmUuCgkJcmVuYW1lZE5vZGUgPSBpbnNlcnRNaXNzaW5nVGFncyhyZW5hbWVkTm9kZSk7CgkJcmVuYW1lZE5vZGUgPSBpbnNlcnRSZXF1aXJlZEF0dHJzKHJlbmFtZWROb2RlKTsKCQlyZW5hbWVkTm9kZSA9IGFwcGx5VGFnTmFtZUNhc2UocmVuYW1lZE5vZGUpOwoJCWFwcGx5QXR0ck5hbWVDYXNlKHJlbmFtZWROb2RlKTsKCQljbGVhbnVwQ1NTQXR0clZhbHVlKHJlbmFtZWROb2RlKTsKCgkJcmV0dXJuIHJlbmFtZWROb2RlOwoJfQoKCXByaXZhdGUgYm9vbGVhbiBzaG91bGRJZ25vcmVDYXNlKElET01FbGVtZW50IGVsZW1lbnQpIHsKCQkvLyBjYXNlIG9wdGlvbiBjYW4gYmUgYXBwbGllZCB0byBubyBuYW1lc3BhY2UgdGFncwoJCXJldHVybiBlbGVtZW50LmlzR2xvYmFsVGFnKCk7CgkJLyoKCQkgTW9kZWxRdWVyeUFkYXB0ZXIgbXFhZGFwdGVyID0gKE1vZGVsUXVlcnlBZGFwdGVyKSBlbGVtZW50LmdldEFkYXB0ZXJGb3IoTW9kZWxRdWVyeUFkYXB0ZXIuY2xhc3MpOwoJCSBNb2RlbFF1ZXJ5IG1xID0gbnVsbDsKCQkgQ01Ob2RlIG5vZGVkZWNsID0gbnVsbDsKCQkgaWYgKG1xYWRhcHRlciAhPSBudWxsKQoJCSBtcSA9IG1xYWRhcHRlci5nZXRNb2RlbFF1ZXJ5KCk7CgkJIGlmIChtcSAhPSBudWxsKQoJCSBub2RlZGVjbCA9IG1xLmdldENNTm9kZShub2RlKTsKCQkgLy8gaWYgYSBOb2RlIGlzbid0IHJlY29nbml6ZWQgYXMgSFRNTCBvciBpcyBhbmQgY2FyZXMgYWJvdXQgY2FzZSwgZG8gbm90IGFsdGVyIGl0CgkJIC8vCWlmIChub2RlZGVjbCA9PSBudWxsIHx8IChub2RlZGVjbCBpbnN0YW5jZW9mIEhUTUxDTU5vZGUgJiYgKChIVE1MQ01Ob2RlKSBub2RlZGVjbCkuc2hvdWxkSWdub3JlQ2FzZSgpKSkKCQkgaWYgKCEgbm9kZWRlY2wuc3VwcG9ydHMoSFRNTENNUHJvcGVydGllcy5TSE9VTERfSUdOT1JFX0NBU0UpKSByZXR1cm4gZmFsc2U7CgkJIHJldHVybiAoKEJvb2xlYW4pY21ub2RlLmdldFByb3BlcnR5KEhUTUxDTVByb3BlcnRpZXMuU0hPVUxEX0lHTk9SRV9DQVNFKSkuYm9vbGVhblZhbHVlKCk7CgkJICovCgl9CgoJcHJvdGVjdGVkIHZvaWQgYXBwbHlBdHRyTmFtZUNhc2UoSURPTU5vZGUgbm9kZSkgewoJCUlET01FbGVtZW50IGVsZW1lbnQgPSAoSURPTUVsZW1lbnQpIG5vZGU7CgkJaWYgKGVsZW1lbnQuaXNDb21tZW50VGFnKCkpCgkJCXJldHVybjsgLy8gZG8gbm90aGluZwoKCQlpbnQgYXR0ck5hbWVDYXNlID0gSFRNTENvcmVQcmVmZXJlbmNlTmFtZXMuQVNJUzsKCgkJaWYgKHNob3VsZElnbm9yZUNhc2UoZWxlbWVudCkpCgkJCWF0dHJOYW1lQ2FzZSA9IGdldENsZWFudXBQcmVmZXJlbmNlcygpLmdldEF0dHJOYW1lQ2FzZSgpOwoKCQlOYW1lZE5vZGVNYXAgYXR0cmlidXRlcyA9IG5vZGUuZ2V0QXR0cmlidXRlcygpOwoJCWludCBhdHRyaWJ1dGVzTGVuZ3RoID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKCgkJZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzTGVuZ3RoOyBpKyspIHsKCQkJSURPTU5vZGUgZWFjaEF0dHIgPSAoSURPTU5vZGUpIGF0dHJpYnV0ZXMuaXRlbShpKTsKCQkJU3RyaW5nIG9sZEF0dHJOYW1lID0gZWFjaEF0dHIuZ2V0Tm9kZU5hbWUoKTsKCQkJU3RyaW5nIG5ld0F0dHJOYW1lID0gb2xkQXR0ck5hbWU7CgkJCS8vIDI1NDk2MSAtIGFsbCBIVE1MIHRhZyBuYW1lcyBhbmQgYXR0cmlidXRlIG5hbWVzIHNob3VsZCBiZSBpbiBFbmdsaXNoCgkJCS8vICAgICAgICAgIGV2ZW4gZm9yIEhUTUwgZmlsZXMgaW4gb3RoZXIgbGFuZ3VhZ2VzIGxpa2UgSmFwYW5lc2Ugb3IgVHVya2lzaC4KCQkJLy8gICAgICAgICAgRW5nbGlzaCBsb2NhbGUgc2hvdWxkIGJlIHVzZWQgdG8gY29udmVydCBiZXR3ZWVuIHVwcGVyY2FzZSBhbmQgbG93ZXJjYXNlCgkJCS8vICAgICAgICAgIChvdGhlcndpc2UgImxpbmsiIHdvdWxkIGJlIGNvbnZlcnRlZCB0byAiTN1OSyIgaW4gVHVya2lzaCwgd2hlcmUgJz8nIGluICJM3U5LIgoJCQkvLyAgICAgICAgICBpcyB0aGUgIkkgT3ZlcmRvdCBDYXBpdGFsIiBpbiBUdXJraXNoKS4KCQkJaWYgKGF0dHJOYW1lQ2FzZSA9PSBIVE1MQ29yZVByZWZlcmVuY2VOYW1lcy5MT1dFUikKCQkJCW5ld0F0dHJOYW1lID0gb2xkQXR0ck5hbWUudG9Mb3dlckNhc2UoTG9jYWxlLlVTKTsKCQkJZWxzZSBpZiAoYXR0ck5hbWVDYXNlID09IEhUTUxDb3JlUHJlZmVyZW5jZU5hbWVzLlVQUEVSKQoJCQkJbmV3QXR0ck5hbWUgPSBvbGRBdHRyTmFtZS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpOwoKCQkJaWYgKG5ld0F0dHJOYW1lLmNvbXBhcmVUbyhvbGRBdHRyTmFtZSkgIT0gMCkgewoJCQkJaW50IGF0dHJOYW1lU3RhcnRPZmZzZXQgPSBlYWNoQXR0ci5nZXRTdGFydE9mZnNldCgpOwoJCQkJaW50IGF0dHJOYW1lTGVuZ3RoID0gb2xkQXR0ck5hbWUubGVuZ3RoKCk7CgoJCQkJSURPTU1vZGVsIHN0cnVjdHVyZWRNb2RlbCA9IG5vZGUuZ2V0TW9kZWwoKTsKCQkJCUlTdHJ1Y3R1cmVkRG9jdW1lbnQgc3RydWN0dXJlZERvY3VtZW50ID0gc3RydWN0dXJlZE1vZGVsLmdldFN0cnVjdHVyZWREb2N1bWVudCgpOwoJCQkJcmVwbGFjZVNvdXJjZShzdHJ1Y3R1cmVkTW9kZWwsIHN0cnVjdHVyZWREb2N1bWVudCwgYXR0ck5hbWVTdGFydE9mZnNldCwgYXR0ck5hbWVMZW5ndGgsIG5ld0F0dHJOYW1lKTsKCQkJfQoJCX0KCX0KCglwcm90ZWN0ZWQgSURPTU5vZGUgYXBwbHlUYWdOYW1lQ2FzZShJRE9NTm9kZSBub2RlKSB7CgkJSURPTUVsZW1lbnQgZWxlbWVudCA9IChJRE9NRWxlbWVudCkgbm9kZTsKCQlpZiAoZWxlbWVudC5pc0NvbW1lbnRUYWcoKSkKCQkJcmV0dXJuIG5vZGU7IC8vIGRvIG5vdGhpbmcKCgkJaW50IHRhZ05hbWVDYXNlID0gSFRNTENvcmVQcmVmZXJlbmNlTmFtZXMuQVNJUzsKCgkJaWYgKHNob3VsZElnbm9yZUNhc2UoZWxlbWVudCkpCgkJCXRhZ05hbWVDYXNlID0gZ2V0Q2xlYW51cFByZWZlcmVuY2VzKCkuZ2V0VGFnTmFtZUNhc2UoKTsKCgkJU3RyaW5nIG9sZFRhZ05hbWUgPSBub2RlLmdldE5vZGVOYW1lKCk7CgkJU3RyaW5nIG5ld1RhZ05hbWUgPSBvbGRUYWdOYW1lOwoJCUlET01Ob2RlIG5ld05vZGUgPSBub2RlOwoKCQkvLyAyNTQ5NjEgLSBhbGwgSFRNTCB0YWcgbmFtZXMgYW5kIGF0dHJpYnV0ZSBuYW1lcyBzaG91bGQgYmUgaW4gRW5nbGlzaAoJCS8vICAgICAgICAgIGV2ZW4gZm9yIEhUTUwgZmlsZXMgaW4gb3RoZXIgbGFuZ3VhZ2VzIGxpa2UgSmFwYW5lc2Ugb3IgVHVya2lzaC4KCQkvLyAgICAgICAgICBFbmdsaXNoIGxvY2FsZSBzaG91bGQgYmUgdXNlZCB0byBjb252ZXJ0IGJldHdlZW4gdXBwZXJjYXNlIGFuZCBsb3dlcmNhc2UKCQkvLyAgICAgICAgICAob3RoZXJ3aXNlICJsaW5rIiB3b3VsZCBiZSBjb252ZXJ0ZWQgdG8gIkzdTksiIGluIFR1cmtpc2gsIHdoZXJlICc/JyBpbiAiTN1OSyIKCQkvLyAgICAgICAgICBpcyB0aGUgIkkgT3ZlcmRvdCBDYXBpdGFsIiBpbiBUdXJraXNoKS4KCQlpZiAodGFnTmFtZUNhc2UgPT0gSFRNTENvcmVQcmVmZXJlbmNlTmFtZXMuTE9XRVIpCgkJCW5ld1RhZ05hbWUgPSBvbGRUYWdOYW1lLnRvTG93ZXJDYXNlKExvY2FsZS5VUyk7CgkJZWxzZSBpZiAodGFnTmFtZUNhc2UgPT0gSFRNTENvcmVQcmVmZXJlbmNlTmFtZXMuVVBQRVIpCgkJCW5ld1RhZ05hbWUgPSBvbGRUYWdOYW1lLnRvVXBwZXJDYXNlKExvY2FsZS5VUyk7CgoJCUlET01Nb2RlbCBzdHJ1Y3R1cmVkTW9kZWwgPSBub2RlLmdldE1vZGVsKCk7CgkJSVN0cnVjdHVyZWREb2N1bWVudCBzdHJ1Y3R1cmVkRG9jdW1lbnQgPSBzdHJ1Y3R1cmVkTW9kZWwuZ2V0U3RydWN0dXJlZERvY3VtZW50KCk7CgoJCUlTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gc3RhcnRUYWdTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gPSBub2RlLmdldFN0YXJ0U3RydWN0dXJlZERvY3VtZW50UmVnaW9uKCk7CgkJaWYgKHN0YXJ0VGFnU3RydWN0dXJlZERvY3VtZW50UmVnaW9uICE9IG51bGwpIHsKCQkJSVRleHRSZWdpb25MaXN0IHJlZ2lvbnMgPSBzdGFydFRhZ1N0cnVjdHVyZWREb2N1bWVudFJlZ2lvbi5nZXRSZWdpb25zKCk7CgkJCWlmIChyZWdpb25zICE9IG51bGwgJiYgcmVnaW9ucy5zaXplKCkgPiAwKSB7CgkJCQlJVGV4dFJlZ2lvbiBzdGFydFRhZ05hbWVSZWdpb24gPSByZWdpb25zLmdldCgxKTsKCQkJCWludCBzdGFydFRhZ05hbWVTdGFydE9mZnNldCA9IHN0YXJ0VGFnU3RydWN0dXJlZERvY3VtZW50UmVnaW9uLmdldFN0YXJ0T2Zmc2V0KHN0YXJ0VGFnTmFtZVJlZ2lvbik7CgkJCQlpbnQgc3RhcnRUYWdOYW1lTGVuZ3RoID0gc3RhcnRUYWdTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24uZ2V0VGV4dEVuZE9mZnNldChzdGFydFRhZ05hbWVSZWdpb24pIC0gc3RhcnRUYWdOYW1lU3RhcnRPZmZzZXQ7CgoJCQkJcmVwbGFjZVNvdXJjZShzdHJ1Y3R1cmVkTW9kZWwsIHN0cnVjdHVyZWREb2N1bWVudCwgc3RhcnRUYWdOYW1lU3RhcnRPZmZzZXQsIHN0YXJ0VGFnTmFtZUxlbmd0aCwgbmV3VGFnTmFtZSk7CgkJCQluZXdOb2RlID0gKElET01Ob2RlKSBzdHJ1Y3R1cmVkTW9kZWwuZ2V0SW5kZXhlZFJlZ2lvbihzdGFydFRhZ05hbWVTdGFydE9mZnNldCk7IC8vIHNhdmUgbmV3IG5vZGUKCQkJfQoJCX0KCgkJSVN0cnVjdHVyZWREb2N1bWVudFJlZ2lvbiBlbmRUYWdTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gPSBub2RlLmdldEVuZFN0cnVjdHVyZWREb2N1bWVudFJlZ2lvbigpOwoJCWlmIChlbmRUYWdTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gIT0gbnVsbCkgewoJCQlJVGV4dFJlZ2lvbkxpc3QgcmVnaW9ucyA9IGVuZFRhZ1N0cnVjdHVyZWREb2N1bWVudFJlZ2lvbi5nZXRSZWdpb25zKCk7CgkJCWlmIChyZWdpb25zICE9IG51bGwgJiYgcmVnaW9ucy5zaXplKCkgPiAwKSB7CgkJCQlJVGV4dFJlZ2lvbiBlbmRUYWdOYW1lUmVnaW9uID0gcmVnaW9ucy5nZXQoMSk7CgkJCQlpbnQgZW5kVGFnTmFtZVN0YXJ0T2Zmc2V0ID0gZW5kVGFnU3RydWN0dXJlZERvY3VtZW50UmVnaW9uLmdldFN0YXJ0T2Zmc2V0KGVuZFRhZ05hbWVSZWdpb24pOwoJCQkJaW50IGVuZFRhZ05hbWVMZW5ndGggPSBlbmRUYWdTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24uZ2V0VGV4dEVuZE9mZnNldChlbmRUYWdOYW1lUmVnaW9uKSAtIGVuZFRhZ05hbWVTdGFydE9mZnNldDsKCgkJCQlpZiAoc3RhcnRUYWdTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gIT0gZW5kVGFnU3RydWN0dXJlZERvY3VtZW50UmVnaW9uKQoJCQkJCXJlcGxhY2VTb3VyY2Uoc3RydWN0dXJlZE1vZGVsLCBzdHJ1Y3R1cmVkRG9jdW1lbnQsIGVuZFRhZ05hbWVTdGFydE9mZnNldCwgZW5kVGFnTmFtZUxlbmd0aCwgbmV3VGFnTmFtZSk7CgkJCX0KCQl9CgoJCXJldHVybiBuZXdOb2RlOwoJfQoKCXByb3RlY3RlZCBOb2RlIGNsZWFudXBDaGlsZHJlbihOb2RlIG5vZGUpIHsKCQlOb2RlIHBhcmVudE5vZGUgPSBub2RlOwoKCQlpZiAobm9kZSAhPSBudWxsKSB7CgkJCU5vZGUgY2hpbGROb2RlID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7CgkJCUhUTUxDbGVhbnVwSGFuZGxlckZhY3RvcnkgZmFjdG9yeSA9IEhUTUxDbGVhbnVwSGFuZGxlckZhY3RvcnkuZ2V0SW5zdGFuY2UoKTsKCQkJd2hpbGUgKGNoaWxkTm9kZSAhPSBudWxsKSB7CgkJCQkvLyBjbGVhbnVwIHRoaXMgY2hpbGQgbm9kZQoJCQkJSVN0cnVjdHVyZWRDbGVhbnVwSGFuZGxlciBjbGVhbnVwSGFuZGxlciA9IGZhY3RvcnkuY3JlYXRlSGFuZGxlcihjaGlsZE5vZGUsIGdldENsZWFudXBQcmVmZXJlbmNlcygpKTsKCQkJCWNoaWxkTm9kZSA9IGNsZWFudXBIYW5kbGVyLmNsZWFudXAoY2hpbGROb2RlKTsKCgkJCQkvLyBnZXQgbmV3IHBhcmVudCBub2RlCgkJCQlwYXJlbnROb2RlID0gKElET01Ob2RlKSBjaGlsZE5vZGUuZ2V0UGFyZW50Tm9kZSgpOwoKCQkJCS8vIGdldCBuZXh0IGNoaWxkIG5vZGUKCQkJCWNoaWxkTm9kZSA9IChJRE9NTm9kZSkgY2hpbGROb2RlLmdldE5leHRTaWJsaW5nKCk7CgkJCX0KCQl9CgoJCXJldHVybiBwYXJlbnROb2RlOwoJfQoKCS8qKgoJICovCglwcm90ZWN0ZWQgdm9pZCBjbGVhbnVwQ1NTQXR0clZhbHVlKElET01Ob2RlIG5vZGUpIHsKCQlpZiAobm9kZSA9PSBudWxsIHx8IG5vZGUuZ2V0Tm9kZVR5cGUoKSAhPSBOb2RlLkVMRU1FTlRfTk9ERSkKCQkJcmV0dXJuOwoJCUlET01FbGVtZW50IGVsZW1lbnQgPSAoSURPTUVsZW1lbnQpIG5vZGU7CgkJaWYgKCFlbGVtZW50LmlzR2xvYmFsVGFnKCkpCgkJCXJldHVybjsKCgkJQXR0ciBhdHRyID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlKCJzdHlsZSIpOyAvLyROT04tTkxTLTEkCgkJaWYgKGF0dHIgPT0gbnVsbCkKCQkJcmV0dXJuOwoJCVN0cmluZyB2YWx1ZSA9IGdldENTU1ZhbHVlKGF0dHIpOwoJCWlmICh2YWx1ZSA9PSBudWxsKQoJCQlyZXR1cm47CgkJU3RyaW5nIG9sZFZhbHVlID0gKChJRE9NTm9kZSkgYXR0cikuZ2V0VmFsdWVTb3VyY2UoKTsKCQlpZiAob2xkVmFsdWUgIT0gbnVsbCAmJiB2YWx1ZS5lcXVhbHMob2xkVmFsdWUpKQoJCQlyZXR1cm47CgkJYXR0ci5zZXRWYWx1ZSh2YWx1ZSk7Cgl9CgoJLyoqCgkgKi8KCXByaXZhdGUgSUNTU01vZGVsIGdldENTU01vZGVsKEF0dHIgYXR0cikgewoJCWlmIChhdHRyID09IG51bGwpCgkJCXJldHVybiBudWxsOwoJCUlOb2RlTm90aWZpZXIgbm90aWZpZXIgPSAoSU5vZGVOb3RpZmllcikgYXR0ci5nZXRPd25lckVsZW1lbnQoKTsKCQlpZiAobm90aWZpZXIgPT0gbnVsbCkKCQkJcmV0dXJuIG51bGw7CgkJSU5vZGVBZGFwdGVyIGFkYXB0ZXIgPSBub3RpZmllci5nZXRBZGFwdGVyRm9yKElTdHlsZURlY2xhcmF0aW9uQWRhcHRlci5jbGFzcyk7CgkJaWYgKGFkYXB0ZXIgPT0gbnVsbCkKCQkJcmV0dXJuIG51bGw7CgkJaWYgKCEoYWRhcHRlciBpbnN0YW5jZW9mIElTdHlsZURlY2xhcmF0aW9uQWRhcHRlcikpCgkJCXJldHVybiBudWxsOwoJCUlTdHlsZURlY2xhcmF0aW9uQWRhcHRlciBzdHlsZUFkYXB0ZXIgPSAoSVN0eWxlRGVjbGFyYXRpb25BZGFwdGVyKSBhZGFwdGVyOwoJCXJldHVybiBzdHlsZUFkYXB0ZXIuZ2V0TW9kZWwoKTsKCX0KCgkvKioKCSAqLwoJcHJpdmF0ZSBTdHJpbmcgZ2V0Q1NTVmFsdWUoQXR0ciBhdHRyKSB7CgkJSUNTU01vZGVsIG1vZGVsID0gZ2V0Q1NTTW9kZWwoYXR0cik7CgkJaWYgKG1vZGVsID09IG51bGwpCgkJCXJldHVybiBudWxsOwoJCUlDU1NOb2RlIGRvY3VtZW50ID0gbW9kZWwuZ2V0RG9jdW1lbnQoKTsKCQlpZiAoZG9jdW1lbnQgPT0gbnVsbCkKCQkJcmV0dXJuIG51bGw7CgkJSU5vZGVOb3RpZmllciBub3RpZmllciA9IChJTm9kZU5vdGlmaWVyKSBkb2N1bWVudDsKCQlJTm9kZUFkYXB0ZXIgYWRhcHRlciA9IG5vdGlmaWVyLmdldEFkYXB0ZXJGb3IoQ1NTU291cmNlRm9ybWF0dGVyLmNsYXNzKTsKCQlpZiAoYWRhcHRlciA9PSBudWxsKQoJCQlyZXR1cm4gbnVsbDsKCQlDU1NTb3VyY2VGb3JtYXR0ZXIgZm9ybWF0dGVyID0gKENTU1NvdXJjZUZvcm1hdHRlcikgYWRhcHRlcjsKCQlTdHJpbmdCdWZmZXIgYnVmZmVyID0gZm9ybWF0dGVyLmNsZWFudXAoZG9jdW1lbnQpOwoJCWlmIChidWZmZXIgPT0gbnVsbCkKCQkJcmV0dXJuIG51bGw7CgkJcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOwoJfQoKCXByaXZhdGUgYm9vbGVhbiBpc0VtcHR5RWxlbWVudChJRE9NRWxlbWVudCBlbGVtZW50KSB7CgkJRG9jdW1lbnQgZG9jdW1lbnQgPSBlbGVtZW50LmdldE93bmVyRG9jdW1lbnQoKTsKCQlpZiAoZG9jdW1lbnQgPT0gbnVsbCkKCQkJLy8gdW5kZWZpbmVkIHRhZywgcmV0dXJuIGRlZmF1bHQKCQkJcmV0dXJuIGZhbHNlOwoKCQlNb2RlbFF1ZXJ5IG1vZGVsUXVlcnkgPSBNb2RlbFF1ZXJ5VXRpbC5nZXRNb2RlbFF1ZXJ5KGRvY3VtZW50KTsKCQlpZiAobW9kZWxRdWVyeSA9PSBudWxsKQoJCQkvLyB1bmRlZmluZWQgdGFnLCByZXR1cm4gZGVmYXVsdAoJCQlyZXR1cm4gZmFsc2U7CgoJCUNNRWxlbWVudERlY2xhcmF0aW9uIGRlY2wgPSBtb2RlbFF1ZXJ5LmdldENNRWxlbWVudERlY2xhcmF0aW9uKGVsZW1lbnQpOwoJCWlmIChkZWNsID09IG51bGwpCgkJCS8vIHVuZGVmaW5lZCB0YWcsIHJldHVybiBkZWZhdWx0CgkJCXJldHVybiBmYWxzZTsKCgkJcmV0dXJuIChkZWNsLmdldENvbnRlbnRUeXBlKCkgPT0gQ01FbGVtZW50RGVjbGFyYXRpb24uRU1QVFkpOwoJfQoKCXByb3RlY3RlZCBJRE9NTm9kZSBpbnNlcnRFbmRUYWcoSURPTU5vZGUgbm9kZSkgewoJCUlET01FbGVtZW50IGVsZW1lbnQgPSAoSURPTUVsZW1lbnQpIG5vZGU7CgoJCWludCBzdGFydFRhZ1N0YXJ0T2Zmc2V0ID0gbm9kZS5nZXRTdGFydE9mZnNldCgpOwoJCUlET01Nb2RlbCBzdHJ1Y3R1cmVkTW9kZWwgPSBub2RlLmdldE1vZGVsKCk7CgkJSURPTU5vZGUgbmV3Tm9kZSA9IG51bGw7CgoJCWlmIChlbGVtZW50LmlzQ29tbWVudFRhZygpKSB7CgkJCS8vIGRvIG5vdGhpbmcKCQl9CgkJZWxzZSBpZiAoaXNFbXB0eUVsZW1lbnQoZWxlbWVudCkpIHsKCQkJSVN0cnVjdHVyZWREb2N1bWVudCBzdHJ1Y3R1cmVkRG9jdW1lbnQgPSBzdHJ1Y3R1cmVkTW9kZWwuZ2V0U3RydWN0dXJlZERvY3VtZW50KCk7CgkJCUlTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gc3RhcnRTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gPSBub2RlLmdldFN0YXJ0U3RydWN0dXJlZERvY3VtZW50UmVnaW9uKCk7CgkJCUlUZXh0UmVnaW9uTGlzdCByZWdpb25zID0gc3RhcnRTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24uZ2V0UmVnaW9ucygpOwoJCQlJVGV4dFJlZ2lvbiBsYXN0UmVnaW9uID0gcmVnaW9ucy5nZXQocmVnaW9ucy5zaXplKCkgLSAxKTsKCQkJcmVwbGFjZVNvdXJjZShzdHJ1Y3R1cmVkTW9kZWwsIHN0cnVjdHVyZWREb2N1bWVudCwgc3RhcnRTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24uZ2V0U3RhcnRPZmZzZXQobGFzdFJlZ2lvbiksIGxhc3RSZWdpb24uZ2V0TGVuZ3RoKCksIEVNUFRZX1RBR19DTE9TRSk7CgoJCQlpZiAocmVnaW9ucy5zaXplKCkgPiAxKSB7CgkJCQlJVGV4dFJlZ2lvbiByZWdpb25CZWZvcmVUYWdDbG9zZSA9IHJlZ2lvbnMuZ2V0KHJlZ2lvbnMuc2l6ZSgpIC0gMSAtIDEpOwoKCQkJCS8vIGluc2VydCBhIHNwYWNlIHNlcGFyYXRvciBiZWZvcmUgdGFnIGNsb3NlIGlmIHRoZSBwcmV2aW91cyByZWdpb24gZG9lcyBub3QgaGF2ZSBleHRyYSBzcGFjZXMKCQkJCWlmIChyZWdpb25CZWZvcmVUYWdDbG9zZS5nZXRUZXh0TGVuZ3RoKCkgPT0gcmVnaW9uQmVmb3JlVGFnQ2xvc2UuZ2V0TGVuZ3RoKCkpCgkJCQkJcmVwbGFjZVNvdXJjZShzdHJ1Y3R1cmVkTW9kZWwsIHN0cnVjdHVyZWREb2N1bWVudCwgc3RhcnRTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24uZ2V0U3RhcnRPZmZzZXQobGFzdFJlZ2lvbiksIDAsICIgIik7IC8vJE5PTi1OTFMtMSQKCQkJfQoJCX0KCQllbHNlIHsKCQkJU3RyaW5nIHRhZ05hbWUgPSBub2RlLmdldE5vZGVOYW1lKCk7CgkJCVN0cmluZyBlbmRUYWcgPSBFTkRfVEFHX09QRU4uY29uY2F0KHRhZ05hbWUpLmNvbmNhdChUQUdfQ0xPU0UpOwoKCQkJSURPTU5vZGUgbGFzdENoaWxkID0gKElET01Ob2RlKSBub2RlLmdldExhc3RDaGlsZCgpOwoJCQlpbnQgZW5kVGFnU3RhcnRPZmZzZXQgPSAwOwoJCQlpZiAobGFzdENoaWxkICE9IG51bGwpCgkJCQkvLyBpZiB0aGlzIG5vZGUgaGFzIGNoaWxkcmVuLCBpbnNlcnQgdGhlIGVuZCB0YWcgYWZ0ZXIgdGhlIGxhc3QgY2hpbGQKCQkJCWVuZFRhZ1N0YXJ0T2Zmc2V0ID0gbGFzdENoaWxkLmdldEVuZE9mZnNldCgpOwoJCQllbHNlCgkJCQkvLyBpZiB0aGlzIG5vZGUgZG9lcyBub3QgaGFzIGNoaWxkcmVuLCBpbnNlcnQgdGhlIGVuZCB0YWcgYWZ0ZXIgdGhlIHN0YXJ0IHRhZwoJCQkJZW5kVGFnU3RhcnRPZmZzZXQgPSBub2RlLmdldEVuZE9mZnNldCgpOwoKCQkJSVN0cnVjdHVyZWREb2N1bWVudCBzdHJ1Y3R1cmVkRG9jdW1lbnQgPSBzdHJ1Y3R1cmVkTW9kZWwuZ2V0U3RydWN0dXJlZERvY3VtZW50KCk7CgkJCXJlcGxhY2VTb3VyY2Uoc3RydWN0dXJlZE1vZGVsLCBzdHJ1Y3R1cmVkRG9jdW1lbnQsIGVuZFRhZ1N0YXJ0T2Zmc2V0LCAwLCBlbmRUYWcpOwoJCX0KCgkJbmV3Tm9kZSA9IChJRE9NTm9kZSkgc3RydWN0dXJlZE1vZGVsLmdldEluZGV4ZWRSZWdpb24oc3RhcnRUYWdTdGFydE9mZnNldCk7IC8vIHNhdmUgbmV3IG5vZGUKCgkJcmV0dXJuIG5ld05vZGU7Cgl9CgoJcHJvdGVjdGVkIElET01Ob2RlIGluc2VydE1pc3NpbmdUYWdzKElET01Ob2RlIG5vZGUpIHsKCQlib29sZWFuIGluc2VydE1pc3NpbmdUYWdzID0gZ2V0Q2xlYW51cFByZWZlcmVuY2VzKCkuZ2V0SW5zZXJ0TWlzc2luZ1RhZ3MoKTsKCQlJRE9NTm9kZSBuZXdOb2RlID0gbm9kZTsKCgkJaWYgKGluc2VydE1pc3NpbmdUYWdzKSB7CgkJCUlTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gc3RhcnRUYWdTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gPSBub2RlLmdldFN0YXJ0U3RydWN0dXJlZERvY3VtZW50UmVnaW9uKCk7CgkJCWlmIChzdGFydFRhZ1N0cnVjdHVyZWREb2N1bWVudFJlZ2lvbiA9PSBudWxsKSB7CgkJCQkvLyBpbXBsaWNpdCBzdGFydCB0YWc7IGdlbmVyYXRlIHRhZyBmb3IgaXQKCQkJCW5ld05vZGUgPSBpbnNlcnRTdGFydFRhZyhub2RlKTsKCQkJCXN0YXJ0VGFnU3RydWN0dXJlZERvY3VtZW50UmVnaW9uID0gbmV3Tm9kZS5nZXRTdGFydFN0cnVjdHVyZWREb2N1bWVudFJlZ2lvbigpOwoJCQl9CgoJCQlJU3RydWN0dXJlZERvY3VtZW50UmVnaW9uIGVuZFRhZ1N0cnVjdHVyZWREb2N1bWVudFJlZ2lvbiA9IG5ld05vZGUuZ2V0RW5kU3RydWN0dXJlZERvY3VtZW50UmVnaW9uKCk7CgoJCQlJVGV4dFJlZ2lvbkxpc3QgcmVnaW9uTGlzdCA9IHN0YXJ0VGFnU3RydWN0dXJlZERvY3VtZW50UmVnaW9uLmdldFJlZ2lvbnMoKTsKCQkJaWYgKHN0YXJ0VGFnU3RydWN0dXJlZERvY3VtZW50UmVnaW9uICE9IG51bGwgJiYgcmVnaW9uTGlzdCAhPSBudWxsICYmIHJlZ2lvbkxpc3QuZ2V0KHJlZ2lvbkxpc3Quc2l6ZSgpIC0gMSkuZ2V0VHlwZSgpID09IERPTVJlZ2lvbkNvbnRleHQuWE1MX0VNUFRZX1RBR19DTE9TRSkgewoKCQkJfQoJCQllbHNlIHsKCQkJCWlmIChzdGFydFRhZ1N0cnVjdHVyZWREb2N1bWVudFJlZ2lvbiA9PSBudWxsKSB7CgkJCQkJLy8gc3RhcnQgdGFnIG1pc3NpbmcKCQkJCQlpZiAoaXNTdGFydFRhZ1JlcXVpcmVkKG5ld05vZGUpKQoJCQkJCQluZXdOb2RlID0gaW5zZXJ0U3RhcnRUYWcobmV3Tm9kZSk7CgkJCQl9CgkJCQllbHNlIGlmIChlbmRUYWdTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gPT0gbnVsbCkgewoJCQkJCS8vIGVuZCB0YWcgbWlzc2luZwoJCQkJCWlmIChpc0VuZFRhZ1JlcXVpcmVkKG5ld05vZGUpKQoJCQkJCQluZXdOb2RlID0gaW5zZXJ0RW5kVGFnKG5ld05vZGUpOwoJCQkJfQoJCQl9CgkJfQoKCQlyZXR1cm4gbmV3Tm9kZTsKCX0KCglwcm90ZWN0ZWQgSURPTU5vZGUgaW5zZXJ0U3RhcnRUYWcoSURPTU5vZGUgbm9kZSkgewoJCUlET01FbGVtZW50IGVsZW1lbnQgPSAoSURPTUVsZW1lbnQpIG5vZGU7CgkJaWYgKGVsZW1lbnQuaXNDb21tZW50VGFnKCkpCgkJCXJldHVybiBub2RlOyAvLyBkbyBub3RoaW5nCgoJCUlET01Ob2RlIG5ld05vZGUgPSBudWxsOwoKCQlTdHJpbmcgdGFnTmFtZSA9IG5vZGUuZ2V0Tm9kZU5hbWUoKTsKCQlTdHJpbmcgc3RhcnRUYWcgPSBTVEFSVF9UQUdfT1BFTi5jb25jYXQodGFnTmFtZSkuY29uY2F0KFRBR19DTE9TRSk7CgkJaW50IHN0YXJ0VGFnU3RhcnRPZmZzZXQgPSBub2RlLmdldFN0YXJ0T2Zmc2V0KCk7CgoJCUlET01Nb2RlbCBzdHJ1Y3R1cmVkTW9kZWwgPSBub2RlLmdldE1vZGVsKCk7CgkJSVN0cnVjdHVyZWREb2N1bWVudCBzdHJ1Y3R1cmVkRG9jdW1lbnQgPSBzdHJ1Y3R1cmVkTW9kZWwuZ2V0U3RydWN0dXJlZERvY3VtZW50KCk7CgkJcmVwbGFjZVNvdXJjZShzdHJ1Y3R1cmVkTW9kZWwsIHN0cnVjdHVyZWREb2N1bWVudCwgc3RhcnRUYWdTdGFydE9mZnNldCwgMCwgc3RhcnRUYWcpOwoJCW5ld05vZGUgPSAoSURPTU5vZGUpIHN0cnVjdHVyZWRNb2RlbC5nZXRJbmRleGVkUmVnaW9uKHN0YXJ0VGFnU3RhcnRPZmZzZXQpOyAvLyBzYXZlIG5ldyBub2RlCgoJCXJldHVybiBuZXdOb2RlOwoJfQoKCXByb3RlY3RlZCB2b2lkIGluc2VydFRhZ0Nsb3NlKElET01Nb2RlbCBzdHJ1Y3R1cmVkTW9kZWwsIElTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24gZmxhdE5vZGUpIHsKCQlpZiAoKGZsYXROb2RlICE9IG51bGwpICYmIChmbGF0Tm9kZS5nZXRSZWdpb25zKCkgIT0gbnVsbCkpIHsKCQkJSVRleHRSZWdpb25MaXN0IHJlZ2lvbkxpc3QgPSBmbGF0Tm9kZS5nZXRSZWdpb25zKCk7CgkJCUlUZXh0UmVnaW9uIGxhc3RSZWdpb24gPSByZWdpb25MaXN0LmdldChyZWdpb25MaXN0LnNpemUoKSAtIDEpOwoJCQlpZiAobGFzdFJlZ2lvbiAhPSBudWxsKSB7CgkJCQlTdHJpbmcgcmVnaW9uVHlwZSA9IGxhc3RSZWdpb24uZ2V0VHlwZSgpOwoJCQkJaWYgKChyZWdpb25UeXBlICE9IERPTVJlZ2lvbkNvbnRleHQuWE1MX0VNUFRZX1RBR19DTE9TRSkgJiYgKHJlZ2lvblR5cGUgIT0gRE9NUmVnaW9uQ29udGV4dC5YTUxfVEFHX0NMT1NFKSkgewoJCQkJCUlTdHJ1Y3R1cmVkRG9jdW1lbnQgc3RydWN0dXJlZERvY3VtZW50ID0gc3RydWN0dXJlZE1vZGVsLmdldFN0cnVjdHVyZWREb2N1bWVudCgpOwoKCQkJCQkvLyBpbnNlcnQgIj4iIGFmdGVyIGxhc3RSZWdpb24gb2YgZmxhdE5vZGUKCQkJCQkvLyBhcyBpbiAiPGE8L2E+IiBpZiBmbGF0Tm9kZSBpcyBmb3Igc3RhcnQgdGFnLCBvciBpbiAiPGE+PC9hIiBpZiBmbGF0Tm9kZSBpcyBmb3IgZW5kIHRhZwoJCQkJCXJlcGxhY2VTb3VyY2Uoc3RydWN0dXJlZE1vZGVsLCBzdHJ1Y3R1cmVkRG9jdW1lbnQsIGZsYXROb2RlLmdldFRleHRFbmRPZmZzZXQobGFzdFJlZ2lvbiksIDAsICI+Iik7IC8vJE5PTi1OTFMtMSQKCQkJCX0KCQkJfQoJCX0KCX0KCglwcm90ZWN0ZWQgYm9vbGVhbiBpc0VuZFRhZ1JlcXVpcmVkKElET01Ob2RlIG5vZGUpIHsKCQlpZiAobm9kZSA9PSBudWxsKQoJCQlyZXR1cm4gZmFsc2U7CgkJcmV0dXJuIG5vZGUuaXNDb250YWluZXIoKTsKCX0KCgkvKioKCSAqIFRoZSBlbmQgdGFncyBvZiBIVE1MIEVNUFRZIGNvbnRlbnQgdHlwZSwgc3VjaCBhcyBJTUcsCgkgKiBhbmQgSFRNTCB1bmRlZmluZWQgdGFncyBhcmUgcGFyc2VkIHNlcGFyYXRlbHkgZnJvbSB0aGUgc3RhcnQgdGFncy4KCSAqIFNvIGluc2VydGluZyB0aGUgbWlzc2luZyBzdGFydCB0YWcgaXMgdXNlbGVzcyBhbmQgZXZlbiBoYXJtZnVsLgoJICovCglwcm90ZWN0ZWQgYm9vbGVhbiBpc1N0YXJ0VGFnUmVxdWlyZWQoSURPTU5vZGUgbm9kZSkgewoJCWlmIChub2RlID09IG51bGwpCgkJCXJldHVybiBmYWxzZTsKCQlyZXR1cm4gbm9kZS5pc0NvbnRhaW5lcigpOwoJfQoKCXByb3RlY3RlZCBib29sZWFuIGlzWE1MVHlwZShJRE9NTW9kZWwgc3RydWN0dXJlZE1vZGVsKSB7CgkJYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsKCgkJaWYgKHN0cnVjdHVyZWRNb2RlbCAhPSBudWxsICYmIHN0cnVjdHVyZWRNb2RlbCAhPSBudWxsKSB7CgkJCUlET01Eb2N1bWVudCBkb2N1bWVudCA9IHN0cnVjdHVyZWRNb2RlbC5nZXREb2N1bWVudCgpOwoKCQkJaWYgKGRvY3VtZW50ICE9IG51bGwpCgkJCQlyZXN1bHQgPSBkb2N1bWVudC5pc1hNTFR5cGUoKTsKCQl9CgoJCXJldHVybiByZXN1bHQ7Cgl9CgoJcHJvdGVjdGVkIElET01Ob2RlIHF1b3RlQXR0clZhbHVlKElET01Ob2RlIG5vZGUpIHsKCQlJRE9NRWxlbWVudCBlbGVtZW50ID0gKElET01FbGVtZW50KSBub2RlOwoJCWlmIChlbGVtZW50LmlzQ29tbWVudFRhZygpKQoJCQlyZXR1cm4gbm9kZTsgLy8gZG8gbm90aGluZwoKCQlib29sZWFuIHF1b3RlQXR0clZhbHVlcyA9IGdldENsZWFudXBQcmVmZXJlbmNlcygpLmdldFF1b3RlQXR0clZhbHVlcygpOwoJCUlET01Ob2RlIG5ld05vZGUgPSBub2RlOwoKCQlpZiAocXVvdGVBdHRyVmFsdWVzKSB7CgkJCU5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzID0gbmV3Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CgkJCWludCBhdHRyaWJ1dGVzTGVuZ3RoID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKCQkJSVNvdXJjZUdlbmVyYXRvciBnZW5lcmF0b3IgPSBub2RlLmdldE1vZGVsKCkuZ2V0R2VuZXJhdG9yKCk7CgoJCQlmb3IgKGludCBpID0gMDsgaSA8IGF0dHJpYnV0ZXNMZW5ndGg7IGkrKykgewoJCQkJYXR0cmlidXRlcyA9IG5ld05vZGUuZ2V0QXR0cmlidXRlcygpOwoJCQkJYXR0cmlidXRlc0xlbmd0aCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7CgkJCQlJRE9NQXR0ciBlYWNoQXR0ciA9IChJRE9NQXR0cikgYXR0cmlidXRlcy5pdGVtKGkpOwoJCQkJLy9JVGV4dFJlZ2lvbiBvbGRBdHRyVmFsdWVSZWdpb24gPSBlYWNoQXR0ci5nZXRWYWx1ZVJlZ2lvbigpOwoJCQkJU3RyaW5nIG9sZEF0dHJWYWx1ZSA9IGVhY2hBdHRyLmdldFZhbHVlUmVnaW9uVGV4dCgpOwoJCQkJaWYgKG9sZEF0dHJWYWx1ZSA9PSBudWxsKSB7CgkJCQkJSURPTU1vZGVsIHN0cnVjdHVyZWRNb2RlbCA9IG5vZGUuZ2V0TW9kZWwoKTsKCQkJCQlpZiAoaXNYTUxUeXBlKHN0cnVjdHVyZWRNb2RlbCkpIHsKCQkJCQkJLy8gVE9ETzogS2l0LCBwbGVhc2UgY2hlY2suIElzIHRoZXJlIGFueSB3YXkgdG8gbm90IHJlbHkgb24gZ2V0dGluZyByZWdpb25zIGZyb20gYXR0cmlidXRlcz8KCQkJCQkJU3RyaW5nIG5ld0F0dHJWYWx1ZSA9ICI9XCIiICsgZWFjaEF0dHIuZ2V0TmFtZVJlZ2lvblRleHQoKSArICJcIiI7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAoKCQkJCQkJSVN0cnVjdHVyZWREb2N1bWVudCBzdHJ1Y3R1cmVkRG9jdW1lbnQgPSBzdHJ1Y3R1cmVkTW9kZWwuZ2V0U3RydWN0dXJlZERvY3VtZW50KCk7CgkJCQkJCXJlcGxhY2VTb3VyY2Uoc3RydWN0dXJlZE1vZGVsLCBzdHJ1Y3R1cmVkRG9jdW1lbnQsIGVhY2hBdHRyLmdldE5hbWVSZWdpb25FbmRPZmZzZXQoKSwgMCwgbmV3QXR0clZhbHVlKTsKCQkJCQkJbmV3Tm9kZSA9IChJRE9NTm9kZSkgc3RydWN0dXJlZE1vZGVsLmdldEluZGV4ZWRSZWdpb24obm9kZS5nZXRTdGFydE9mZnNldCgpKTsgLy8gc2F2ZSBuZXcgbm9kZQoJCQkJCX0KCQkJCX0KCQkJCWVsc2UgewoKCQkJCQljaGFyIHF1b3RlID0gU3RyaW5nVXRpbHMuaXNRdW90ZWQob2xkQXR0clZhbHVlKSA/IG9sZEF0dHJWYWx1ZS5jaGFyQXQoMCkgOiBET1VCTEVfUVVPVEU7CgkJCQkJU3RyaW5nIG5ld0F0dHJWYWx1ZSA9IGdlbmVyYXRvci5nZW5lcmF0ZUF0dHJWYWx1ZShlYWNoQXR0ciwgcXVvdGUpOwoKCQkJCQkvLyBUaGVyZSBpcyBhIHByb2JsZW0gaW4gU3RydWN0dXJlZERvY3VtZW50UmVnaW9uVXRpbC5nZXRBdHRyVmFsdWUoSVRleHRSZWdpb24pIHdoZW4gdGhlIHJlZ2lvbiBpcyBpbnN0YW5jZW9mIENvbnRleHRSZWdpb24uCgkJCQkJLy8gV29ya2Fyb3VuZCBmb3Igbm93Li4uCgkJCQkJaWYgKG9sZEF0dHJWYWx1ZS5sZW5ndGgoKSA9PSAxKSB7CgkJCQkJCWNoYXIgZmlyc3RDaGFyID0gb2xkQXR0clZhbHVlLmNoYXJBdCgwKTsKCQkJCQkJaWYgKGZpcnN0Q2hhciA9PSBTSU5HTEVfUVVPVEUpCgkJCQkJCQluZXdBdHRyVmFsdWUgPSBTSU5HTEVfUVVPVEVTOwoJCQkJCQllbHNlIGlmIChmaXJzdENoYXIgPT0gRE9VQkxFX1FVT1RFKQoJCQkJCQkJbmV3QXR0clZhbHVlID0gRE9VQkxFX1FVT1RFUzsKCQkJCQl9CgoJCQkJCWlmIChuZXdBdHRyVmFsdWUgIT0gbnVsbCkgewoJCQkJCQlpZiAobmV3QXR0clZhbHVlLmNvbXBhcmVUbyhvbGRBdHRyVmFsdWUpICE9IDApIHsKCQkJCQkJCWludCBhdHRyVmFsdWVTdGFydE9mZnNldCA9IGVhY2hBdHRyLmdldFZhbHVlUmVnaW9uU3RhcnRPZmZzZXQoKTsKCQkJCQkJCWludCBhdHRyVmFsdWVMZW5ndGggPSBvbGRBdHRyVmFsdWUubGVuZ3RoKCk7CgkJCQkJCQlpbnQgc3RhcnRUYWdTdGFydE9mZnNldCA9IG5vZGUuZ2V0U3RhcnRPZmZzZXQoKTsKCgkJCQkJCQlJRE9NTW9kZWwgc3RydWN0dXJlZE1vZGVsID0gbm9kZS5nZXRNb2RlbCgpOwoJCQkJCQkJSVN0cnVjdHVyZWREb2N1bWVudCBzdHJ1Y3R1cmVkRG9jdW1lbnQgPSBzdHJ1Y3R1cmVkTW9kZWwuZ2V0U3RydWN0dXJlZERvY3VtZW50KCk7CgkJCQkJCQlyZXBsYWNlU291cmNlKHN0cnVjdHVyZWRNb2RlbCwgc3RydWN0dXJlZERvY3VtZW50LCBhdHRyVmFsdWVTdGFydE9mZnNldCwgYXR0clZhbHVlTGVuZ3RoLCBuZXdBdHRyVmFsdWUpOwoJCQkJCQkJbmV3Tm9kZSA9IChJRE9NTm9kZSkgc3RydWN0dXJlZE1vZGVsLmdldEluZGV4ZWRSZWdpb24oc3RhcnRUYWdTdGFydE9mZnNldCk7IC8vIHNhdmUgbmV3IG5vZGUKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJcmV0dXJuIG5ld05vZGU7Cgl9CgoJcHJpdmF0ZSBJRE9NTm9kZSBpbnNlcnRSZXF1aXJlZEF0dHJzKElET01Ob2RlIG5vZGUpIHsKCQlib29sZWFuIGluc2VydFJlcXVpcmVkQXR0cnMgPSBnZXRDbGVhbnVwUHJlZmVyZW5jZXMoKS5nZXRJbnNlcnRSZXF1aXJlZEF0dHJzKCk7CgkJSURPTU5vZGUgbmV3Tm9kZSA9IG5vZGU7CgoJCWlmIChpbnNlcnRSZXF1aXJlZEF0dHJzKSB7CgkJCUxpc3QgcmVxdWlyZWRBdHRycyA9IGdldFJlcXVpcmVkQXR0cnMobmV3Tm9kZSk7CgkJCWlmIChyZXF1aXJlZEF0dHJzLnNpemUoKSA+IDApIHsKCQkJCU5hbWVkTm9kZU1hcCBjdXJyZW50QXR0cnMgPSBub2RlLmdldEF0dHJpYnV0ZXMoKTsKCQkJCUxpc3QgaW5zZXJ0QXR0cnMgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCQlpZiAoY3VycmVudEF0dHJzLmdldExlbmd0aCgpID09IDApCgkJCQkJaW5zZXJ0QXR0cnMuYWRkQWxsKHJlcXVpcmVkQXR0cnMpOwoJCQkJZWxzZSB7CgkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCByZXF1aXJlZEF0dHJzLnNpemUoKTsgaSsrKSB7CgkJCQkJCVN0cmluZyByZXF1aXJlZEF0dHJOYW1lID0gKChDTUF0dHJpYnV0ZURlY2xhcmF0aW9uKSByZXF1aXJlZEF0dHJzLmdldChpKSkuZ2V0QXR0ck5hbWUoKTsKCQkJCQkJYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwoJCQkJCQlmb3IgKGludCBqID0gMDsgaiA8IGN1cnJlbnRBdHRycy5nZXRMZW5ndGgoKTsgaisrKSB7CgkJCQkJCQlTdHJpbmcgY3VycmVudEF0dHJOYW1lID0gY3VycmVudEF0dHJzLml0ZW0oaikuZ2V0Tm9kZU5hbWUoKTsKCQkJCQkJCWlmIChyZXF1aXJlZEF0dHJOYW1lLmNvbXBhcmVUb0lnbm9yZUNhc2UoY3VycmVudEF0dHJOYW1lKSA9PSAwKSB7CgkJCQkJCQkJZm91bmQgPSB0cnVlOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWlmICghZm91bmQpCgkJCQkJCQlpbnNlcnRBdHRycy5hZGQocmVxdWlyZWRBdHRycy5nZXQoaSkpOwoJCQkJCX0KCQkJCX0KCQkJCWlmIChpbnNlcnRBdHRycy5zaXplKCkgPiAwKSB7CgkJCQkJSVN0cnVjdHVyZWREb2N1bWVudFJlZ2lvbiBzdGFydFN0cnVjdHVyZWREb2N1bWVudFJlZ2lvbiA9IG5ld05vZGUuZ2V0U3RhcnRTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24oKTsKCQkJCQlpbnQgaW5kZXggPSBzdGFydFN0cnVjdHVyZWREb2N1bWVudFJlZ2lvbi5nZXRFbmRPZmZzZXQoKTsKCQkJCQlJVGV4dFJlZ2lvbiBsYXN0UmVnaW9uID0gc3RhcnRTdHJ1Y3R1cmVkRG9jdW1lbnRSZWdpb24uZ2V0TGFzdFJlZ2lvbigpOyAKCQkJCQlpZiAobGFzdFJlZ2lvbi5nZXRUeXBlKCkgPT0gRE9NUmVnaW9uQ29udGV4dC5YTUxfVEFHX0NMT1NFKSB7CgkJCQkJCWluZGV4LS07CgkJCQkJCWxhc3RSZWdpb24gPSBzdGFydFN0cnVjdHVyZWREb2N1bWVudFJlZ2lvbi5nZXRSZWdpb25BdENoYXJhY3Rlck9mZnNldChpbmRleCAtIDEpOwoJCQkJCX0KCQkJCQllbHNlIGlmIChsYXN0UmVnaW9uLmdldFR5cGUoKSA9PSBET01SZWdpb25Db250ZXh0LlhNTF9FTVBUWV9UQUdfQ0xPU0UpIHsKCQkJCQkJaW5kZXggPSBpbmRleCAtIDI7CgkJCQkJCWxhc3RSZWdpb24gPSBzdGFydFN0cnVjdHVyZWREb2N1bWVudFJlZ2lvbi5nZXRSZWdpb25BdENoYXJhY3Rlck9mZnNldChpbmRleCAtIDEpOwoJCQkJCX0KCQkJCQlNdWx0aVRleHRFZGl0IG11bHRpVGV4dEVkaXQgPSBuZXcgTXVsdGlUZXh0RWRpdCgpOwoJCQkJCXRyeSB7CgkJCQkJCWZvciAoaW50IGkgPSBpbnNlcnRBdHRycy5zaXplKCkgLSAxOyBpID49IDA7IGktLSkgewoJCQkJCQkJQ01BdHRyaWJ1dGVEZWNsYXJhdGlvbiBhdHRyRGVjbCA9IChDTUF0dHJpYnV0ZURlY2xhcmF0aW9uKSBpbnNlcnRBdHRycy5nZXQoaSk7CgkJCQkJCQlTdHJpbmcgcmVxdWlyZWRBdHRyaWJ1dGVOYW1lID0gYXR0ckRlY2wuZ2V0QXR0ck5hbWUoKTsKCQkJCQkJCVN0cmluZyBkZWZhdWx0VmFsdWUgPSBhdHRyRGVjbC5nZXREZWZhdWx0VmFsdWUoKTsKCQkJCQkJCWlmIChkZWZhdWx0VmFsdWUgPT0gbnVsbCkKCQkJCQkJCQlkZWZhdWx0VmFsdWUgPSAiIjsgLy8kTk9OLU5MUy0xJAoJCQkJCQkJU3RyaW5nIG5hbWVBbmREZWZhdWx0VmFsdWUgPSAiICI7IC8vJE5PTi1OTFMtMSQKCQkJCQkJCWlmIChpID09IDAgJiYgbGFzdFJlZ2lvbi5nZXRMZW5ndGgoKSA+IGxhc3RSZWdpb24uZ2V0VGV4dExlbmd0aCgpKQoJCQkJCQkJCW5hbWVBbmREZWZhdWx0VmFsdWUgPSAiIjsgLy8kTk9OLU5MUy0xJAoJCQkJCQkJbmFtZUFuZERlZmF1bHRWYWx1ZSArPSByZXF1aXJlZEF0dHJpYnV0ZU5hbWUgKyAiPVwiIiArIGRlZmF1bHRWYWx1ZSArICJcIiI7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAoJCQkJCQkJbXVsdGlUZXh0RWRpdC5hZGRDaGlsZChuZXcgSW5zZXJ0RWRpdChpbmRleCwgbmFtZUFuZERlZmF1bHRWYWx1ZSkpOwoJCQkJCQkJLy8gQlVHMzM4MTogTXVsdGlUZXh0RWRpdCBhcHBsaWVzIGFsbCBjaGlsZCBUZXh0RWRpdCdzIGJhc2luZyBvbiBvZmZzZXRzCgkJCQkJCQkvLyAgICAgICAgICBpbiB0aGUgZG9jdW1lbnQgYmVmb3JlIHRoZSBmaXJzdCBUZXh0RWRpdCwgbm90IGFmdGVyIGVhY2gKCQkJCQkJCS8vICAgICAgICAgIGNoaWxkIFRleHRFZGl0LiBUaGVyZWZvcmUsIGRvIG5vdCBuZWVkIHRvIGFkdmFuY2UgdGhlIGluZGV4LgoJCQkJCQkJLy9pbmRleCArPSBuYW1lQW5kRGVmYXVsdFZhbHVlLmxlbmd0aCgpOwoJCQkJCQl9CgkJCQkJCW11bHRpVGV4dEVkaXQuYXBwbHkobmV3Tm9kZS5nZXRTdHJ1Y3R1cmVkRG9jdW1lbnQoKSk7CgkJCQkJfQoJCQkJCWNhdGNoIChCYWRMb2NhdGlvbkV4Y2VwdGlvbiBlKSB7CgkJCQkJCXRocm93IG5ldyBTb3VyY2VFZGl0aW5nUnVudGltZUV4Y2VwdGlvbihlKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiBuZXdOb2RlOwoJfQoKCglwcm90ZWN0ZWQgTW9kZWxRdWVyeSBnZXRNb2RlbFF1ZXJ5KE5vZGUgbm9kZSkgewoJCWlmIChub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9OT0RFKSB7CgkJCXJldHVybiBNb2RlbFF1ZXJ5VXRpbC5nZXRNb2RlbFF1ZXJ5KChEb2N1bWVudCkgbm9kZSk7CgkJfQoJCWVsc2UgewoJCQlyZXR1cm4gTW9kZWxRdWVyeVV0aWwuZ2V0TW9kZWxRdWVyeShub2RlLmdldE93bmVyRG9jdW1lbnQoKSk7CgkJfQoJfQoKCXByb3RlY3RlZCBMaXN0IGdldFJlcXVpcmVkQXR0cnMoTm9kZSBub2RlKSB7CgkJTGlzdCByZXN1bHQgPSBuZXcgQXJyYXlMaXN0KCk7CgoJCU1vZGVsUXVlcnkgbW9kZWxRdWVyeSA9IGdldE1vZGVsUXVlcnkobm9kZSk7CgkJaWYgKG1vZGVsUXVlcnkgIT0gbnVsbCkgewoJCQlDTUVsZW1lbnREZWNsYXJhdGlvbiBlbGVtZW50RGVjbCA9IG1vZGVsUXVlcnkuZ2V0Q01FbGVtZW50RGVjbGFyYXRpb24oKEVsZW1lbnQpIG5vZGUpOwoJCQlpZiAoZWxlbWVudERlY2wgIT0gbnVsbCkgewoJCQkJQ01OYW1lZE5vZGVNYXAgYXR0ck1hcCA9IGVsZW1lbnREZWNsLmdldEF0dHJpYnV0ZXMoKTsKCQkJCUl0ZXJhdG9yIGl0ID0gYXR0ck1hcC5pdGVyYXRvcigpOwoJCQkJQ01BdHRyaWJ1dGVEZWNsYXJhdGlvbiBhdHRyID0gbnVsbDsKCQkJCXdoaWxlIChpdC5oYXNOZXh0KCkpIHsKCQkJCQlhdHRyID0gKENNQXR0cmlidXRlRGVjbGFyYXRpb24pIGl0Lm5leHQoKTsKCQkJCQlpZiAoYXR0ci5nZXRVc2FnZSgpID09IENNQXR0cmlidXRlRGVjbGFyYXRpb24uUkVRVUlSRUQpIHsKCQkJCQkJcmVzdWx0LmFkZChhdHRyKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiByZXN1bHQ7Cgl9Cn0=