LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDA3IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgICBKZW5zIEx1a293c2tpL0lubm9vcHJhY3QgLSBpbml0aWFsIHJlbmFtaW5nL3Jlc3RydWN0dXJpbmcKICogICAgIEplc3BlciBTdGVlbiBN+GxsZXIgLSBpbml0aWFsIElEb2N1bWVudEV4dGVuc2lvbjQgc3VwcG9ydCAtICMxMDI4MjIKICogICAgIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUuaW50ZXJuYWwuZm9ybWF0OwoKaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGaWxlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnRleHQuRG9jdW1lbnRSZXdyaXRlU2Vzc2lvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnRleHQuRG9jdW1lbnRSZXdyaXRlU2Vzc2lvblR5cGU7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS50ZXh0LklEb2N1bWVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnRleHQuSURvY3VtZW50RXh0ZW5zaW9uNDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS5pbnRlcm5hbC5Mb2dnZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUuaW50ZXJuYWwucHJvdmlzaW9uYWwuSVN0cnVjdHVyZWRNb2RlbDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS5pbnRlcm5hbC5wcm92aXNpb25hbC5TdHJ1Y3R1cmVkTW9kZWxNYW5hZ2VyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlLmludGVybmFsLnV0aWwuQXNzZXJ0OwppbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CgoKcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0U3RydWN0dXJlZEZvcm1hdFByb2Nlc3NvciBpbXBsZW1lbnRzIElTdHJ1Y3R1cmVkRm9ybWF0UHJvY2Vzc29yIHsKCXByb3RlY3RlZCBJU3RydWN0dXJlZEZvcm1hdENvbnRyYWludHMgZkZvcm1hdENvbnRyYWludHMgPSBudWxsOwoJcHJvdGVjdGVkIElQcm9ncmVzc01vbml0b3IgZlByb2dyZXNzTW9uaXRvciA9IG51bGw7CglwdWJsaWMgYm9vbGVhbiByZWZyZXNoRm9ybWF0UHJlZmVyZW5jZXMgPSB0cnVlOyAvLyBzcGVjaWFsIGZsYWcgZm9yIEpVbml0CgkvKgoJICogTWF4IGxlbmd0aCBvZiB0ZXh0IHRvIGJlIGZvcm1hdHRlZCB0byBiZSBjb25zaWRlcmVkIGEgInNtYWxsIGNoYW5nZSIKCSAqIFVzZWQgZm9yIGRvY3VtZW50IHJld3JpdGUgc2Vzc2lvbiB0eXBlLgoJICovCglwcml2YXRlIGZpbmFsIGludCBNQVhfU01BTExfRk9STUFUX1NJWkUgPSAxMDAwOwoKCXByb3RlY3RlZCB2b2lkIGVuc3VyZUNsb3NlZChPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtLCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSkgewoKCQl0cnkgewoJCQlpZiAoaW5wdXRTdHJlYW0gIT0gbnVsbCkgewoJCQkJaW5wdXRTdHJlYW0uY2xvc2UoKTsKCQkJfQoJCX0KCQljYXRjaCAoSU9FeGNlcHRpb24gZSkgewoJCQlMb2dnZXIubG9nRXhjZXB0aW9uKGUpOyAvLyBob3BlbGVzcwoJCX0KCQl0cnkgewoJCQlpZiAob3V0cHV0U3RyZWFtICE9IG51bGwpIHsKCQkJCW91dHB1dFN0cmVhbS5jbG9zZSgpOwoJCQl9CgkJfQoJCWNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CgkJCUxvZ2dlci5sb2dFeGNlcHRpb24oZSk7IC8vIGhvcGVsZXNzCgkJfQoJfQoKCXB1YmxpYyBTdHJpbmcgZm9ybWF0Q29udGVudChTdHJpbmcgaW5wdXQpIHRocm93cyBJT0V4Y2VwdGlvbiwgQ29yZUV4Y2VwdGlvbiB7CgkJaWYgKGlucHV0ID09IG51bGwpCgkJCXJldHVybiBpbnB1dDsKCgkJSVN0cnVjdHVyZWRNb2RlbCBzdHJ1Y3R1cmVkTW9kZWwgPSBudWxsOwoJCUlucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gbnVsbDsKCQl0cnkgewoJCQkvLyBzZXR1cCBzdHJ1Y3R1cmVkTW9kZWwKCQkJLy8gTm90ZTogV2UgYXJlIGdldHRpbmcgbW9kZWwgZm9yIHJlYWQuIFdpbGwgcmV0dXJuIGZvcm1hdHRlZAoJCQkvLyBzdHJpbmcgYW5kIE5PVCBzYXZlIG1vZGVsLgoJCQlpbnB1dFN0cmVhbSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShpbnB1dC5nZXRCeXRlcygiVVRGOCIpKTsgLy8kTk9OLU5MUy0xJAoJCQlTdHJpbmcgaWQgPSBpbnB1dFN0cmVhbS50b1N0cmluZygpICsgIi4iICsgZ2V0RmlsZUV4dGVuc2lvbigpOyAvLyROT04tTkxTLTEkCgkJCXN0cnVjdHVyZWRNb2RlbCA9IFN0cnVjdHVyZWRNb2RlbE1hbmFnZXIuZ2V0TW9kZWxNYW5hZ2VyKCkuZ2V0TW9kZWxGb3JSZWFkKGlkLCBpbnB1dFN0cmVhbSwgbnVsbCk7CgoJCQkvLyBmb3JtYXQKCQkJZm9ybWF0TW9kZWwoc3RydWN0dXJlZE1vZGVsKTsKCgkJCS8vIHJldHVybiBvdXRwdXQKCQkJcmV0dXJuIHN0cnVjdHVyZWRNb2RlbC5nZXRTdHJ1Y3R1cmVkRG9jdW1lbnQoKS5nZXQoKTsKCQl9CgkJZmluYWxseSB7CgkJCWVuc3VyZUNsb3NlZChudWxsLCBpbnB1dFN0cmVhbSk7CgkJCS8vIHJlbGVhc2UgZnJvbSBtb2RlbCBtYW5hZ2VyCgkJCWlmIChzdHJ1Y3R1cmVkTW9kZWwgIT0gbnVsbCkKCQkJCXN0cnVjdHVyZWRNb2RlbC5yZWxlYXNlRnJvbVJlYWQoKTsKCQl9Cgl9CgoJcHVibGljIFN0cmluZyBmb3JtYXRDb250ZW50KFN0cmluZyBpbnB1dCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCWlmIChpbnB1dCA9PSBudWxsKQoJCQlyZXR1cm4gaW5wdXQ7CgoJCWlmICgoc3RhcnQgPj0gMCkgJiYgKGxlbmd0aCA+PSAwKSAmJiAoc3RhcnQgKyBsZW5ndGggPD0gaW5wdXQubGVuZ3RoKCkpKSB7CgkJCUlTdHJ1Y3R1cmVkTW9kZWwgc3RydWN0dXJlZE1vZGVsID0gbnVsbDsKCQkJSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0gPSBudWxsOwoJCQl0cnkgewoJCQkJLy8gc2V0dXAgc3RydWN0dXJlZE1vZGVsCgkJCQkvLyBOb3RlOiBXZSBhcmUgZ2V0dGluZyBtb2RlbCBmb3IgcmVhZC4gV2lsbCByZXR1cm4gZm9ybWF0dGVkCgkJCQkvLyBzdHJpbmcgYW5kIE5PVCBzYXZlIG1vZGVsLgoJCQkJaW5wdXRTdHJlYW0gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW5wdXQuZ2V0Qnl0ZXMoIlVURjgiKSk7IC8vJE5PTi1OTFMtMSQKCQkJCVN0cmluZyBpZCA9IGlucHV0U3RyZWFtLnRvU3RyaW5nKCkgKyAiLiIgKyBnZXRGaWxlRXh0ZW5zaW9uKCk7IC8vJE5PTi1OTFMtMSQKCQkJCXN0cnVjdHVyZWRNb2RlbCA9IFN0cnVjdHVyZWRNb2RlbE1hbmFnZXIuZ2V0TW9kZWxNYW5hZ2VyKCkuZ2V0TW9kZWxGb3JSZWFkKGlkLCBpbnB1dFN0cmVhbSwgbnVsbCk7CgoJCQkJLy8gZm9ybWF0CgkJCQlmb3JtYXRNb2RlbChzdHJ1Y3R1cmVkTW9kZWwsIHN0YXJ0LCBsZW5ndGgpOwoKCQkJCS8vIHJldHVybiBvdXRwdXQKCQkJCXJldHVybiBzdHJ1Y3R1cmVkTW9kZWwuZ2V0U3RydWN0dXJlZERvY3VtZW50KCkuZ2V0KCk7CgkJCX0KCQkJZmluYWxseSB7CgkJCQllbnN1cmVDbG9zZWQobnVsbCwgaW5wdXRTdHJlYW0pOwoJCQkJLy8gcmVsZWFzZSBmcm9tIG1vZGVsIG1hbmFnZXIKCQkJCWlmIChzdHJ1Y3R1cmVkTW9kZWwgIT0gbnVsbCkKCQkJCQlzdHJ1Y3R1cmVkTW9kZWwucmVsZWFzZUZyb21SZWFkKCk7CgkJCX0KCQl9CgkJZWxzZQoJCQlyZXR1cm4gaW5wdXQ7Cgl9CgoJcHVibGljIHZvaWQgZm9ybWF0RG9jdW1lbnQoSURvY3VtZW50IGRvY3VtZW50KSB0aHJvd3MgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCWlmIChkb2N1bWVudCA9PSBudWxsKQoJCQlyZXR1cm47CgoJCUlTdHJ1Y3R1cmVkTW9kZWwgc3RydWN0dXJlZE1vZGVsID0gbnVsbDsKCQkvLyBPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtID0gbnVsbDsKCQl0cnkgewoJCQkvLyBzZXR1cCBzdHJ1Y3R1cmVkTW9kZWwKCQkJLy8gTm90ZTogV2UgYXJlIGdldHRpbmcgbW9kZWwgZm9yIGVkaXQuIFdpbGwgc2F2ZSBtb2RlbCBpZiBtb2RlbAoJCQkvLyBjaGFuZ2VkLgoJCQlzdHJ1Y3R1cmVkTW9kZWwgPSBTdHJ1Y3R1cmVkTW9kZWxNYW5hZ2VyLmdldE1vZGVsTWFuYWdlcigpLmdldEV4aXN0aW5nTW9kZWxGb3JFZGl0KGRvY3VtZW50KTsKCgkJCS8vIGZvcm1hdAoJCQlmb3JtYXRNb2RlbChzdHJ1Y3R1cmVkTW9kZWwpOwoKCQkJLy8gc2F2ZSBtb2RlbCBpZiBuZWVkZWQKCQkJaWYgKCFzdHJ1Y3R1cmVkTW9kZWwuaXNTaGFyZWRGb3JFZGl0KCkgJiYgc3RydWN0dXJlZE1vZGVsLmlzU2F2ZU5lZWRlZCgpKQoJCQkJc3RydWN0dXJlZE1vZGVsLnNhdmUoKTsKCQl9CgkJZmluYWxseSB7CgkJCS8vIGVuc3VyZUNsb3NlZChvdXRwdXRTdHJlYW0sIG51bGwpOwoJCQkvLyByZWxlYXNlIGZyb20gbW9kZWwgbWFuYWdlcgoJCQlpZiAoc3RydWN0dXJlZE1vZGVsICE9IG51bGwpCgkJCQlzdHJ1Y3R1cmVkTW9kZWwucmVsZWFzZUZyb21FZGl0KCk7CgkJfQoJfQoKCXB1YmxpYyB2b2lkIGZvcm1hdERvY3VtZW50KElEb2N1bWVudCBkb2N1bWVudCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCWlmIChkb2N1bWVudCA9PSBudWxsKQoJCQlyZXR1cm47CgoJCWlmICgoc3RhcnQgPj0gMCkgJiYgKGxlbmd0aCA+PSAwKSAmJiAoc3RhcnQgKyBsZW5ndGggPD0gZG9jdW1lbnQuZ2V0TGVuZ3RoKCkpKSB7CgkJCUlTdHJ1Y3R1cmVkTW9kZWwgc3RydWN0dXJlZE1vZGVsID0gbnVsbDsKCQkJLy8gT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSA9IG51bGw7CgkJCXRyeSB7CgkJCQkvLyBzZXR1cCBzdHJ1Y3R1cmVkTW9kZWwKCQkJCS8vIE5vdGU6IFdlIGFyZSBnZXR0aW5nIG1vZGVsIGZvciBlZGl0LiBXaWxsIHNhdmUgbW9kZWwgaWYKCQkJCS8vIG1vZGVsIGNoYW5nZWQuCgkJCQlzdHJ1Y3R1cmVkTW9kZWwgPSBTdHJ1Y3R1cmVkTW9kZWxNYW5hZ2VyLmdldE1vZGVsTWFuYWdlcigpLmdldEV4aXN0aW5nTW9kZWxGb3JFZGl0KGRvY3VtZW50KTsKCgkJCQlpZiAoc3RydWN0dXJlZE1vZGVsICE9IG51bGwpIHsKCQkJCQkvLyBmb3JtYXQKCQkJCQlmb3JtYXRNb2RlbChzdHJ1Y3R1cmVkTW9kZWwsIHN0YXJ0LCBsZW5ndGgpOwoKCQkJCQkvLyBzYXZlIG1vZGVsIGlmIG5lZWRlZAoJCQkJCWlmICghc3RydWN0dXJlZE1vZGVsLmlzU2hhcmVkRm9yRWRpdCgpICYmIHN0cnVjdHVyZWRNb2RlbC5pc1NhdmVOZWVkZWQoKSkKCQkJCQkJc3RydWN0dXJlZE1vZGVsLnNhdmUoKTsKCQkJCX0KCQkJfQoJCQlmaW5hbGx5IHsKCQkJCS8vIGVuc3VyZUNsb3NlZChvdXRwdXRTdHJlYW0sIG51bGwpOwoJCQkJLy8gcmVsZWFzZSBmcm9tIG1vZGVsIG1hbmFnZXIKCQkJCWlmIChzdHJ1Y3R1cmVkTW9kZWwgIT0gbnVsbCkKCQkJCQlzdHJ1Y3R1cmVkTW9kZWwucmVsZWFzZUZyb21FZGl0KCk7CgkJCX0KCQl9Cgl9CgoJcHVibGljIHZvaWQgZm9ybWF0RmlsZShJRmlsZSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCWlmIChmaWxlID09IG51bGwpCgkJCXJldHVybjsKCgkJSVN0cnVjdHVyZWRNb2RlbCBzdHJ1Y3R1cmVkTW9kZWwgPSBudWxsOwoJCS8vIE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0gPSBudWxsOwoJCXRyeSB7CgkJCS8vIHNldHVwIHN0cnVjdHVyZWRNb2RlbAoJCQkvLyBOb3RlOiBXZSBhcmUgZ2V0dGluZyBtb2RlbCBmb3IgZWRpdC4gV2lsbCBzYXZlIG1vZGVsIGlmIG1vZGVsCgkJCS8vIGNoYW5nZWQuCgkJCXN0cnVjdHVyZWRNb2RlbCA9IFN0cnVjdHVyZWRNb2RlbE1hbmFnZXIuZ2V0TW9kZWxNYW5hZ2VyKCkuZ2V0TW9kZWxGb3JFZGl0KGZpbGUpOwoKCQkJLy8gZm9ybWF0CgkJCWZvcm1hdE1vZGVsKHN0cnVjdHVyZWRNb2RlbCk7CgoJCQkvLyBzYXZlIG1vZGVsIGlmIG5lZWRlZAoJCQlpZiAoIXN0cnVjdHVyZWRNb2RlbC5pc1NoYXJlZEZvckVkaXQoKSAmJiBzdHJ1Y3R1cmVkTW9kZWwuaXNTYXZlTmVlZGVkKCkpCgkJCQlzdHJ1Y3R1cmVkTW9kZWwuc2F2ZSgpOwoJCX0KCQlmaW5hbGx5IHsKCQkJLy8gZW5zdXJlQ2xvc2VkKG91dHB1dFN0cmVhbSwgbnVsbCk7CgkJCS8vIHJlbGVhc2UgZnJvbSBtb2RlbCBtYW5hZ2VyCgkJCWlmIChzdHJ1Y3R1cmVkTW9kZWwgIT0gbnVsbCkgewoJCQkJc3RydWN0dXJlZE1vZGVsLnJlbGVhc2VGcm9tRWRpdCgpOwoJCQl9CgoJCX0KCX0KCglwdWJsaWMgdm9pZCBmb3JtYXRGaWxlKElGaWxlIGZpbGUsIGludCBzdGFydCwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDb3JlRXhjZXB0aW9uIHsKCQlpZiAoZmlsZSA9PSBudWxsKQoJCQlyZXR1cm47CgoJCUlTdHJ1Y3R1cmVkTW9kZWwgc3RydWN0dXJlZE1vZGVsID0gbnVsbDsKCQkvLyBPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtID0gbnVsbDsKCQl0cnkgewoJCQkvLyBzZXR1cCBzdHJ1Y3R1cmVkTW9kZWwKCQkJLy8gTm90ZTogV2UgYXJlIGdldHRpbmcgbW9kZWwgZm9yIGVkaXQuIFdpbGwgc2F2ZSBtb2RlbCBpZiBtb2RlbAoJCQkvLyBjaGFuZ2VkLgoJCQlzdHJ1Y3R1cmVkTW9kZWwgPSBTdHJ1Y3R1cmVkTW9kZWxNYW5hZ2VyLmdldE1vZGVsTWFuYWdlcigpLmdldE1vZGVsRm9yRWRpdChmaWxlKTsKCgkJCS8vIGZvcm1hdAoJCQlmb3JtYXRNb2RlbChzdHJ1Y3R1cmVkTW9kZWwsIHN0YXJ0LCBsZW5ndGgpOwoKCQkJLy8gc2F2ZSBtb2RlbCBpZiBuZWVkZWQKCQkJaWYgKCFzdHJ1Y3R1cmVkTW9kZWwuaXNTaGFyZWRGb3JFZGl0KCkgJiYgc3RydWN0dXJlZE1vZGVsLmlzU2F2ZU5lZWRlZCgpKQoJCQkJc3RydWN0dXJlZE1vZGVsLnNhdmUoKTsKCQl9CgkJZmluYWxseSB7CgkJCS8vIGVuc3VyZUNsb3NlZChvdXRwdXRTdHJlYW0sIG51bGwpOwoJCQkvLyByZWxlYXNlIGZyb20gbW9kZWwgbWFuYWdlcgoJCQlpZiAoc3RydWN0dXJlZE1vZGVsICE9IG51bGwpCgkJCQlzdHJ1Y3R1cmVkTW9kZWwucmVsZWFzZUZyb21FZGl0KCk7CgkJfQoJfQoKCXB1YmxpYyB2b2lkIGZvcm1hdEZpbGVOYW1lKFN0cmluZyBmaWxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uLCBDb3JlRXhjZXB0aW9uIHsKCQlpZiAoZmlsZU5hbWUgPT0gbnVsbCkKCQkJcmV0dXJuOwoKCQlJU3RydWN0dXJlZE1vZGVsIHN0cnVjdHVyZWRNb2RlbCA9IG51bGw7CgkJSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0gPSBudWxsOwoJCS8vIE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0gPSBudWxsOwoJCXRyeSB7CgkJCS8vIHNldHVwIHN0cnVjdHVyZWRNb2RlbAoJCQkvLyBOb3RlOiBXZSBhcmUgZ2V0dGluZyBtb2RlbCBmb3IgZWRpdC4gV2lsbCBzYXZlIG1vZGVsIGlmIG1vZGVsCgkJCS8vIGNoYW5nZWQuCgkJCWlucHV0U3RyZWFtID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlTmFtZSk7CgkJCXN0cnVjdHVyZWRNb2RlbCA9IFN0cnVjdHVyZWRNb2RlbE1hbmFnZXIuZ2V0TW9kZWxNYW5hZ2VyKCkuZ2V0TW9kZWxGb3JFZGl0KGZpbGVOYW1lLCBpbnB1dFN0cmVhbSwgbnVsbCk7CgoJCQkvLyBmb3JtYXQKCQkJZm9ybWF0TW9kZWwoc3RydWN0dXJlZE1vZGVsKTsKCgkJCS8vIHNhdmUgbW9kZWwgaWYgbmVlZGVkCgkJCWlmICghc3RydWN0dXJlZE1vZGVsLmlzU2hhcmVkRm9yRWRpdCgpICYmIHN0cnVjdHVyZWRNb2RlbC5pc1NhdmVOZWVkZWQoKSkKCQkJCXN0cnVjdHVyZWRNb2RlbC5zYXZlKCk7CgkJfQoJCWZpbmFsbHkgewoJCQkvLyBlbnN1cmVDbG9zZWQob3V0cHV0U3RyZWFtLCBpbnB1dFN0cmVhbSk7CgkJCS8vIHJlbGVhc2UgZnJvbSBtb2RlbCBtYW5hZ2VyCgkJCWlmIChzdHJ1Y3R1cmVkTW9kZWwgIT0gbnVsbCkKCQkJCXN0cnVjdHVyZWRNb2RlbC5yZWxlYXNlRnJvbUVkaXQoKTsKCQl9Cgl9CgoJcHVibGljIHZvaWQgZm9ybWF0RmlsZU5hbWUoU3RyaW5nIGZpbGVOYW1lLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiwgQ29yZUV4Y2VwdGlvbiB7CgkJaWYgKGZpbGVOYW1lID09IG51bGwpCgkJCXJldHVybjsKCgkJSVN0cnVjdHVyZWRNb2RlbCBzdHJ1Y3R1cmVkTW9kZWwgPSBudWxsOwoJCUlucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gbnVsbDsKCQkvLyBPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtID0gbnVsbDsKCQl0cnkgewoJCQkvLyBzZXR1cCBzdHJ1Y3R1cmVkTW9kZWwKCQkJLy8gTm90ZTogV2UgYXJlIGdldHRpbmcgbW9kZWwgZm9yIGVkaXQuIFdpbGwgc2F2ZSBtb2RlbCBpZiBtb2RlbAoJCQkvLyBjaGFuZ2VkLgoJCQlpbnB1dFN0cmVhbSA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZU5hbWUpOwoJCQlzdHJ1Y3R1cmVkTW9kZWwgPSBTdHJ1Y3R1cmVkTW9kZWxNYW5hZ2VyLmdldE1vZGVsTWFuYWdlcigpLmdldE1vZGVsRm9yRWRpdChmaWxlTmFtZSwgaW5wdXRTdHJlYW0sIG51bGwpOwoKCQkJLy8gZm9ybWF0CgkJCWZvcm1hdE1vZGVsKHN0cnVjdHVyZWRNb2RlbCwgc3RhcnQsIGxlbmd0aCk7CgoJCQkvLyBzYXZlIG1vZGVsIGlmIG5lZWRlZAoJCQlpZiAoIXN0cnVjdHVyZWRNb2RlbC5pc1NoYXJlZEZvckVkaXQoKSAmJiBzdHJ1Y3R1cmVkTW9kZWwuaXNTYXZlTmVlZGVkKCkpCgkJCQlzdHJ1Y3R1cmVkTW9kZWwuc2F2ZSgpOwoJCX0KCQlmaW5hbGx5IHsKCQkJLy8gZW5zdXJlQ2xvc2VkKG91dHB1dFN0cmVhbSwgaW5wdXRTdHJlYW0pOwoJCQkvLyByZWxlYXNlIGZyb20gbW9kZWwgbWFuYWdlcgoJCQlpZiAoc3RydWN0dXJlZE1vZGVsICE9IG51bGwpCgkJCQlzdHJ1Y3R1cmVkTW9kZWwucmVsZWFzZUZyb21FZGl0KCk7CgkJfQoJfQoKCXB1YmxpYyB2b2lkIGZvcm1hdE1vZGVsKElTdHJ1Y3R1cmVkTW9kZWwgc3RydWN0dXJlZE1vZGVsKSB7CgkJaW50IHN0YXJ0ID0gMDsKCQlpbnQgbGVuZ3RoID0gc3RydWN0dXJlZE1vZGVsLmdldFN0cnVjdHVyZWREb2N1bWVudCgpLmdldExlbmd0aCgpOwoKCQlmb3JtYXRNb2RlbChzdHJ1Y3R1cmVkTW9kZWwsIHN0YXJ0LCBsZW5ndGgpOwoJfQoKCXB1YmxpYyB2b2lkIGZvcm1hdE1vZGVsKElTdHJ1Y3R1cmVkTW9kZWwgc3RydWN0dXJlZE1vZGVsLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHsKCQlpZiAoc3RydWN0dXJlZE1vZGVsICE9IG51bGwpIHsKCQkJLy8gZm9yIGRlYnVnZ2luZyBwdXJwb3NlcwoJCQlsb25nIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwoKCQkJSURvY3VtZW50RXh0ZW5zaW9uNCBkb2NFeHQ0ID0gbnVsbDsKCQkJaWYgKHN0cnVjdHVyZWRNb2RlbC5nZXRTdHJ1Y3R1cmVkRG9jdW1lbnQoKSBpbnN0YW5jZW9mIElEb2N1bWVudEV4dGVuc2lvbjQpIHsKCQkJCWRvY0V4dDQgPSAoSURvY3VtZW50RXh0ZW5zaW9uNCkgc3RydWN0dXJlZE1vZGVsLmdldFN0cnVjdHVyZWREb2N1bWVudCgpOwoJCQl9CgkJCURvY3VtZW50UmV3cml0ZVNlc3Npb24gcmV3cml0ZVNlc3Npb24gPSBudWxsOwoKCQkJdHJ5IHsKCQkJCS8vIHdoZW5ldmVyIGZvcm1hdHRpbmcgbW9kZWwsIGZpcmUgYWJvdXR0b2NoYW5nZS9tb2RlbGNoYW5nZWQKCQkJCXN0cnVjdHVyZWRNb2RlbC5hYm91dFRvQ2hhbmdlTW9kZWwoKTsKCQkJCURvY3VtZW50UmV3cml0ZVNlc3Npb25UeXBlIHJld3JpdGVUeXBlID0gKGxlbmd0aCA+IE1BWF9TTUFMTF9GT1JNQVRfU0laRSkgPyBEb2N1bWVudFJld3JpdGVTZXNzaW9uVHlwZS5VTlJFU1RSSUNURUQgOiBEb2N1bWVudFJld3JpdGVTZXNzaW9uVHlwZS5VTlJFU1RSSUNURURfU01BTEw7CgkJCQlyZXdyaXRlU2Vzc2lvbiA9IChkb2NFeHQ0ID09IG51bGwgfHwgZG9jRXh0NC5nZXRBY3RpdmVSZXdyaXRlU2Vzc2lvbigpICE9IG51bGwpID8gbnVsbCA6IGRvY0V4dDQuc3RhcnRSZXdyaXRlU2Vzc2lvbihyZXdyaXRlVHlwZSk7CgoJCQkJaWYgKChzdGFydCA9PSAwKSAmJiAobGVuZ3RoID09IHN0cnVjdHVyZWRNb2RlbC5nZXRTdHJ1Y3R1cmVkRG9jdW1lbnQoKS5nZXRMZW5ndGgoKSkpCgkJCQkJc2V0Rm9ybWF0V2l0aFNpYmxpbmdJbmRlbnQoc3RydWN0dXJlZE1vZGVsLCBmYWxzZSk7CgkJCQllbHNlCgkJCQkJc2V0Rm9ybWF0V2l0aFNpYmxpbmdJbmRlbnQoc3RydWN0dXJlZE1vZGVsLCB0cnVlKTsKCgkJCQlpZiAoKHN0YXJ0ID49IDApICYmIChsZW5ndGggPj0gMCkgJiYgKHN0YXJ0ICsgbGVuZ3RoIDw9IHN0cnVjdHVyZWRNb2RlbC5nZXRTdHJ1Y3R1cmVkRG9jdW1lbnQoKS5nZXRMZW5ndGgoKSkpIHsKCQkJCQlMaXN0IGFjdGl2ZU5vZGVzID0gZ2V0QWxsQWN0aXZlTm9kZXMoc3RydWN0dXJlZE1vZGVsLCBzdGFydCwgbGVuZ3RoKTsKCQkJCQlpZiAoYWN0aXZlTm9kZXMuc2l6ZSgpID4gMCkgewoJCQkJCQlOb2RlIGZpcnN0Tm9kZSA9IChOb2RlKSBhY3RpdmVOb2Rlcy5nZXQoMCk7CgkJCQkJCU5vZGUgbGFzdE5vZGUgPSAoTm9kZSkgYWN0aXZlTm9kZXMuZ2V0KGFjdGl2ZU5vZGVzLnNpemUoKSAtIDEpOwoKCQkJCQkJYm9vbGVhbiBkb25lID0gZmFsc2U7CgkJCQkJCU5vZGUgZWFjaE5vZGUgPSBmaXJzdE5vZGU7CgkJCQkJCU5vZGUgbmV4dE5vZGUgPSBudWxsOwoJCQkJCQl3aGlsZSAoIWRvbmUpIHsKCQkJCQkJCS8vIHVwZGF0ZSAiZG9uZSIKCQkJCQkJCWRvbmUgPSAoZWFjaE5vZGUgPT0gbGFzdE5vZGUpOwoKCQkJCQkJCS8qCgkJCQkJCQkgKiBnZXQgbmV4dCBzaWJsaW5nIGJlZm9yZSBmb3JtYXQgYmVjYXVzZSBlYWNoTm9kZQoJCQkJCQkJICogbWF5IGJlIGRlbGV0ZWQsIGZvciBleGFtcGxlIHdoZW4gaXQncyBhbiBlbXB0eQoJCQkJCQkJICogdGV4dCBub2RlCgkJCQkJCQkgKi8KCQkJCQkJCW5leHROb2RlID0gZWFjaE5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKCgkJCQkJCQkvLyBmb3JtYXQgZWFjaCBub2RlCgkJCQkJCQlmb3JtYXROb2RlKGVhY2hOb2RlKTsKCgkJCQkJCQkvLyB1cGRhdGUgZWFjaCBub2RlCgkJCQkJCQlpZiAoKG5leHROb2RlICE9IG51bGwpICYmIChuZXh0Tm9kZS5nZXRQYXJlbnROb2RlKCkgPT0gbnVsbCkpCgkJCQkJCQkJLy8gbmV4dE5vZGUgaXMgZGVsZXRlZCBkdXJpbmcgZm9ybWF0CgkJCQkJCQkJZWFjaE5vZGUgPSBlYWNoTm9kZS5nZXROZXh0U2libGluZygpOwoJCQkJCQkJZWxzZQoJCQkJCQkJCWVhY2hOb2RlID0gbmV4dE5vZGU7CgoJCQkJCQkJLy8gVGhpcyBzaG91bGQgbm90IGJlIG5lZWRlZCwgYnV0IGp1c3QgaW4gY2FzZQoJCQkJCQkJLy8gc29tZXRoaW5nIHdlbnQgd3Jvbmcgd2l0aCB3aXRoIGVhY2hOb2RlLgoJCQkJCQkJLy8gV2UgZG9uJ3Qgd2FudCBhbiBpbmZpbml0ZSBsb29wIGhlcmUuCgkJCQkJCQlpZiAoZWFjaE5vZGUgPT0gbnVsbCkKCQkJCQkJCQlkb25lID0gdHJ1ZTsKCQkJCQkJfQoKCQkJCQl9CgkJCQl9CgkJCX0KCQkJZmluYWxseSB7CgkJCQkvLyB3ZSBuZWVkIHR3byBmaW5hbGx5J3MsIGp1c3QgaW4gY2FzZSBmaXJzdCBmYWlscwoJCQkJdHJ5IHsKCQkJCQlpZiAoKGRvY0V4dDQgIT0gbnVsbCkgJiYgKHJld3JpdGVTZXNzaW9uICE9IG51bGwpKQoJCQkJCQlkb2NFeHQ0LnN0b3BSZXdyaXRlU2Vzc2lvbihyZXdyaXRlU2Vzc2lvbik7CgkJCQl9CgkJCQlmaW5hbGx5IHsKCQkJCQkvLyBhbHdheXMgbWFrZSBzdXJlIHRvIGZpcmUgY2hhbmdlZG1vZGVsIHdoZW4gZG9uZQoJCQkJCXN0cnVjdHVyZWRNb2RlbC5jaGFuZ2VkTW9kZWwoKTsKCQkJCX0KCQkJfQoKCQkJaWYgKExvZ2dlci5ERUJVR19GT1JNQVQpIHsKCQkJCWxvbmcgZW5kVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJmb3JtYXRNb2RlbCB0aW1lOiAiICsgKGVuZFRpbWUgLSBzdGFydFRpbWUpKTsgLy8kTk9OLU5MUy0xJAoJCQl9CgkJfQoJfQoKCXB1YmxpYyB2b2lkIGZvcm1hdE5vZGUoTm9kZSBub2RlKSB7CgkJaWYgKG5vZGUgIT0gbnVsbCkgewoJCQlOb2RlIG5ld05vZGUgPSBub2RlOwoKCQkJLy8gZm9ybWF0IHRoZSBvd25lciBub2RlIGlmIGl0J3MgYW4gYXR0cmlidXRlIG5vZGUKCQkJaWYgKG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkFUVFJJQlVURV9OT0RFKQoJCQkJbmV3Tm9kZSA9ICgoQXR0cikgbm9kZSkuZ2V0T3duZXJFbGVtZW50KCk7CgoJCQkvLyByZWZyZXNoIGZvcm1hdCBwcmVmZXJlbmNlcyBiZWZvcmUgZ2V0dGluZyBmb3JtYXR0ZXIKCQkJaWYgKHJlZnJlc2hGb3JtYXRQcmVmZXJlbmNlcykKCQkJCXJlZnJlc2hGb3JtYXRQcmVmZXJlbmNlcygpOwoKCQkJLy8gZ2V0IGZvcm1hdHRlciBhbmQgZm9ybWF0IGNvbnRyYWludHMKCQkJSVN0cnVjdHVyZWRGb3JtYXR0ZXIgZm9ybWF0dGVyID0gZ2V0Rm9ybWF0dGVyKG5ld05vZGUpOwoJCQkvLyBUT0RPX2Z1dHVyZTogYWRkZWQgYXNzZXJ0IHRvIHJlcGxhY2UgInJlZHVuZGFudCBudWxsIGNoZWNrIi4KCQkJLy8gaWYgZm9ybWF0dGVyIGlzIGV2ZXIgbnVsbCwgd2Ugc2hvdWxkIHByb3ZpZGUgc29tZQoJCQkvLyBkZWZhdWx0IGZvcm1hdHRlciB0byBzZXJ2ZSBhcyBwbGFjZSBob2xkZXIuCgkJCUFzc2VydC5pc05vdE51bGwoZm9ybWF0dGVyLCAiZm9ybWF0dGVyIHdhcyBudWxsIGZvciBhIG5vZGUsICIpOyAvLyROT04tTkxTLTEkCgkJCUlTdHJ1Y3R1cmVkRm9ybWF0Q29udHJhaW50cyBmb3JtYXRDb250cmFpbnRzID0gZm9ybWF0dGVyLmdldEZvcm1hdENvbnRyYWludHMoKTsKCQkJZm9ybWF0Q29udHJhaW50cy5zZXRGb3JtYXRXaXRoU2libGluZ0luZGVudCh0cnVlKTsKCQkJLy8gZm9ybWF0IGVhY2ggbm9kZQoJCQlmb3JtYXR0ZXIuZm9ybWF0KG5ld05vZGUsIGZvcm1hdENvbnRyYWludHMpOwoJCX0KCX0KCgkvKioKCSAqIEBkZXByZWNhdGVkIFVzZSBnZXRBbGxBY3RpdmVOb2RlcyBpbnN0ZWFkCgkgKi8KCXByb3RlY3RlZCBWZWN0b3IgZ2V0QWN0aXZlTm9kZXMoSVN0cnVjdHVyZWRNb2RlbCBzdHJ1Y3R1cmVkTW9kZWwsIGludCBzdGFydE5vZGVPZmZzZXQsIGludCBsZW5ndGgpIHsKCQlMaXN0IGFsbEFjdGl2ZU5vZGVzID0gZ2V0QWxsQWN0aXZlTm9kZXMoc3RydWN0dXJlZE1vZGVsLCBzdGFydE5vZGVPZmZzZXQsIGxlbmd0aCk7CgkJcmV0dXJuIG5ldyBWZWN0b3IoYWxsQWN0aXZlTm9kZXMpOwoJfQoKCXByb3RlY3RlZCBMaXN0IGdldEFsbEFjdGl2ZU5vZGVzKElTdHJ1Y3R1cmVkTW9kZWwgc3RydWN0dXJlZE1vZGVsLCBpbnQgc3RhcnROb2RlT2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CgkJTGlzdCBhY3RpdmVOb2RlcyA9IG5ldyBBcnJheUxpc3QoKTsKCgkJaWYgKHN0cnVjdHVyZWRNb2RlbCAhPSBudWxsKSB7CgkJCU5vZGUgc3RhcnROb2RlID0gKE5vZGUpIHN0cnVjdHVyZWRNb2RlbC5nZXRJbmRleGVkUmVnaW9uKHN0YXJ0Tm9kZU9mZnNldCk7CgkJCS8vIHNlZSBodHRwczovL3czLm9wZW5zb3VyY2UuaWJtLmNvbS9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9NDcxMQoJCQkvLwoJCQkvLyBXZSBoYXZlIHRvIHdhdGNoIGZvciBzZWxlY3Rpb24gYm91bmRhcnkgY29uZGl0aW9ucy4gVXNlIHRoaXMgYXMKCQkJLy8gYW4gZXhhbXBsZTogPGE+dGV4dDwvYT48Yj50ZXh0PC9iPiwKCQkJLy8gSWYgdGhlIHdob2xlIDxhPiBub2RlIGlzIHNlbGVjdGVkLCBsaWtlOgoJCQkvLyB8PGE+dGV4dDwvYT58PGI+dGV4dDwvYj4sIHdlIG5lZWQgdG8gc3Vic3RyYWN0IHRoZSBsZW5ndGggYnkgMQoJCQkvLyB0byBmaW5kCgkJCS8vIHRoZSBub2RlIGF0IHRoZSBlbmQgb2YgdGhlIHNlbGVjdGlvbjoKCQkJLy8gc3RydWN0dXJlZE1vZGVsLmdldEluZGV4ZWRSZWdpb24oc3RhcnROb2RlT2Zmc2V0ICsgbGVuZ3RoIC0gMSksCgkJCS8vIG9yIGVsc2UKCQkJLy8gd2UnZCBmaW5kIHRoZSBuZXh0IGFkamFjZW50IG5vZGUuCgkJCS8vCgkJCS8vIEhvd2V2ZXIsIHdoZW4gdGhlIHNlbGVjdGlvbiBsZW5ndGggaXMgMCAobWVhbmluZyBubyB0ZXh0IGlzCgkJCS8vIHNlbGVjdGVkKSwgdGhlIGN1cnNvciBpcyBhdCB0aGUgYmVnaW5uaW5nCgkJCS8vIG9mIHRoZSBub2RlIHdlIHdhbnQgdG8gZm9ybWF0OiB8PGE+dGV4dDwvYT48Yj50ZXh0PC9iPiwgdGhlCgkJCS8vIG5vZGUgYXQgdGhlIGVuZCBvZiB0aGUgc2VsZWN0aW9uIGlzOgoJCQkvLyBzdHJ1Y3R1cmVkTW9kZWwuZ2V0SW5kZXhlZFJlZ2lvbihzdGFydE5vZGVPZmZzZXQgKyBsZW5ndGgpLgoJCQlpbnQgZW5kTm9kZU9mZnNldCA9IGxlbmd0aCA+IDAgPyBzdGFydE5vZGVPZmZzZXQgKyBsZW5ndGggLSAxIDogc3RhcnROb2RlT2Zmc2V0ICsgbGVuZ3RoOwoJCQlOb2RlIGVuZE5vZGUgPSAoTm9kZSkgc3RydWN0dXJlZE1vZGVsLmdldEluZGV4ZWRSZWdpb24oZW5kTm9kZU9mZnNldCk7CgoJCQkvLyBtYWtlIHN1cmUgaXQncyBhbiBub24tZW1wdHkgZG9jdW1lbnQKCQkJaWYgKHN0YXJ0Tm9kZSAhPSBudWxsKSB7CgkJCQl3aGlsZSAoaXNTaWJsaW5nT2Yoc3RhcnROb2RlLCBlbmROb2RlKSA9PSBmYWxzZSkgewoJCQkJCWlmIChlbmROb2RlICE9IG51bGwpCgkJCQkJCWVuZE5vZGUgPSBlbmROb2RlLmdldFBhcmVudE5vZGUoKTsKCQkJCQlpZiAoZW5kTm9kZSA9PSBudWxsKSB7CgkJCQkJCXN0YXJ0Tm9kZSA9IHN0YXJ0Tm9kZS5nZXRQYXJlbnROb2RlKCk7CgkJCQkJCS8vIHNlZQoJCQkJCQkvLyBodHRwczovL3czLm9wZW5zb3VyY2UuaWJtLmNvbS9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9NDcxMQoJCQkJCQkvLyBhbmQgbm90ZXMgYWJvdmUKCQkJCQkJZW5kTm9kZU9mZnNldCA9IGxlbmd0aCA+IDAgPyBzdGFydE5vZGVPZmZzZXQgKyBsZW5ndGggLSAxIDogc3RhcnROb2RlT2Zmc2V0ICsgbGVuZ3RoOwoJCQkJCQllbmROb2RlID0gKE5vZGUpIHN0cnVjdHVyZWRNb2RlbC5nZXRJbmRleGVkUmVnaW9uKGVuZE5vZGVPZmZzZXQpOwoJCQkJCX0KCQkJCX0KCgkJCQl3aGlsZSAoc3RhcnROb2RlICE9IGVuZE5vZGUpIHsKCQkJCQlhY3RpdmVOb2Rlcy5hZGQoc3RhcnROb2RlKTsKCQkJCQlzdGFydE5vZGUgPSBzdGFydE5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKCQkJCX0KCQkJCWlmIChzdGFydE5vZGUgIT0gbnVsbCkKCQkJCQlhY3RpdmVOb2Rlcy5hZGQoc3RhcnROb2RlKTsKCQkJfQoJCX0KCgkJcmV0dXJuIGFjdGl2ZU5vZGVzOwoJfQoKCWFic3RyYWN0IHByb3RlY3RlZCBTdHJpbmcgZ2V0RmlsZUV4dGVuc2lvbigpOwoKCXByb3RlY3RlZCBJU3RydWN0dXJlZEZvcm1hdENvbnRyYWludHMgZ2V0Rm9ybWF0Q29udHJhaW50cyhJU3RydWN0dXJlZE1vZGVsIHN0cnVjdHVyZWRNb2RlbCkgewoJCS8vIDI2MjEzNSAtIE5QRSBkdXJpbmcgZm9ybWF0IG9mIGVtcHR5IGRvY3VtZW50CgkJaWYgKChmRm9ybWF0Q29udHJhaW50cyA9PSBudWxsKSAmJiAoc3RydWN0dXJlZE1vZGVsICE9IG51bGwpKSB7CgkJCU5vZGUgbm9kZSA9IChOb2RlKSBzdHJ1Y3R1cmVkTW9kZWwuZ2V0SW5kZXhlZFJlZ2lvbigwKTsKCgkJCWlmIChub2RlICE9IG51bGwpIHsKCQkJCUlTdHJ1Y3R1cmVkRm9ybWF0dGVyIGZvcm1hdHRlciA9IGdldEZvcm1hdHRlcihub2RlKTsKCQkJCWlmIChmb3JtYXR0ZXIgIT0gbnVsbCkgewoJCQkJCWZGb3JtYXRDb250cmFpbnRzID0gZm9ybWF0dGVyLmdldEZvcm1hdENvbnRyYWludHMoKTsKCQkJCX0KCQkJfQoJCX0KCgkJcmV0dXJuIGZGb3JtYXRDb250cmFpbnRzOwoJfQoKCWFic3RyYWN0IHByb3RlY3RlZCBJU3RydWN0dXJlZEZvcm1hdHRlciBnZXRGb3JtYXR0ZXIoTm9kZSBub2RlKTsKCglwcm90ZWN0ZWQgYm9vbGVhbiBpc1NpYmxpbmdPZihOb2RlIG5vZGUsIE5vZGUgZW5kTm9kZSkgewoJCWlmIChlbmROb2RlID09IG51bGwpCgkJCXJldHVybiB0cnVlOwoJCWVsc2UgewoJCQlOb2RlIHNpYmxpbmdOb2RlID0gbm9kZTsKCQkJd2hpbGUgKHNpYmxpbmdOb2RlICE9IG51bGwpIHsKCQkJCWlmIChzaWJsaW5nTm9kZSA9PSBlbmROb2RlKQoJCQkJCXJldHVybiB0cnVlOwoJCQkJZWxzZQoJCQkJCXNpYmxpbmdOb2RlID0gc2libGluZ05vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKCQkJfQoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJfQoKCWFic3RyYWN0IHByb3RlY3RlZCB2b2lkIHJlZnJlc2hGb3JtYXRQcmVmZXJlbmNlcygpOwoKCXByb3RlY3RlZCB2b2lkIHNldEZvcm1hdFdpdGhTaWJsaW5nSW5kZW50KElTdHJ1Y3R1cmVkTW9kZWwgc3RydWN0dXJlZE1vZGVsLCBib29sZWFuIGZvcm1hdFdpdGhTaWJsaW5nSW5kZW50KSB7CgkJLy8gMjYyMTM1IC0gTlBFIGR1cmluZyBmb3JtYXQgb2YgZW1wdHkgZG9jdW1lbnQKCQlJU3RydWN0dXJlZEZvcm1hdENvbnRyYWludHMgZm9ybWF0Q29udHJhaW50cyA9IGdldEZvcm1hdENvbnRyYWludHMoc3RydWN0dXJlZE1vZGVsKTsKCgkJaWYgKGZvcm1hdENvbnRyYWludHMgIT0gbnVsbCkKCQkJZm9ybWF0Q29udHJhaW50cy5zZXRGb3JtYXRXaXRoU2libGluZ0luZGVudChmb3JtYXRXaXRoU2libGluZ0luZGVudCk7Cgl9CgoJcHVibGljIHZvaWQgc2V0UHJvZ3Jlc3NNb25pdG9yKElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCWZQcm9ncmVzc01vbml0b3IgPSBtb25pdG9yOwoJfQp9Cg==