LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUudXRpbDsKCmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuemlwLio7CmltcG9ydCBqYXZhLm5ldC5VUkw7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5Qcm9ncmVzc1V0aWw7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuU2VydmVyUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlRyYWNlOwovKioKICogVXRpbGl0eSBjbGFzcyB3aXRoIGFuIGFzc29ydG1lbnQgb2YgdXNlZnVsIGZpbGUgbWV0aG9kcy4KICovCnB1YmxpYyBjbGFzcyBGaWxlVXRpbCB7CgkvLyBzaXplIG9mIHRoZSBidWZmZXIKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCVUZGRVIgPSAxMDI0MDsKCgkvLyB0aGUgYnVmZmVyCglwcml2YXRlIHN0YXRpYyBieXRlW10gYnVmID0gbmV3IGJ5dGVbQlVGRkVSXTsKCgkvKioKCSAqIEZpbGVVdGlsIGNhbm5vdCBiZSBjcmVhdGVkLiBVc2Ugc3RhdGljIG1ldGhvZHMuCgkgKi8KCXByaXZhdGUgRmlsZVV0aWwoKSB7CgkJc3VwZXIoKTsKCX0KCgkvKioKCSAqIENvcHlzIGEgZGlyZWN0b3J5IGZyb20gYSB0byBiLgoJICoKCSAqIEBwYXJhbSBmcm9tIGphdmEubGFuZy5TdHJpbmcKCSAqIEBwYXJhbSB0byBqYXZhLmxhbmcuU3RyaW5nCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCBjb3B5RGlyZWN0b3J5KFN0cmluZyBmcm9tLCBTdHJpbmcgdG8sIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCXRyeSB7CgkJCUZpbGUgZnJvbURpciA9IG5ldyBGaWxlKGZyb20pOwoJCQlGaWxlIHRvRGlyID0gbmV3IEZpbGUodG8pOwoJCgkJCUZpbGVbXSBmaWxlcyA9IGZyb21EaXIubGlzdEZpbGVzKCk7CgkKCQkJdG9EaXIubWtkaXIoKTsKCQoJCQkvLyBjeWNsZSB0aHJvdWdoIGZpbGVzCgkJCWludCBzaXplID0gZmlsZXMubGVuZ3RoOwoJCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgkJCW1vbml0b3IuYmVnaW5UYXNrKFNlcnZlclBsdWdpbi5nZXRSZXNvdXJjZSgiJWNvcHlpbmdUYXNrIiwgbmV3IFN0cmluZ1tdIHtmcm9tLCB0b30pLCBzaXplICogNTApOwoJCgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlGaWxlIGN1cnJlbnQgPSBmaWxlc1tpXTsKCQkJCVN0cmluZyBmcm9tRmlsZSA9IGN1cnJlbnQuZ2V0QWJzb2x1dGVQYXRoKCk7CgkJCQlTdHJpbmcgdG9GaWxlID0gdG87CgkJCQlpZiAoIXRvRmlsZS5lbmRzV2l0aChGaWxlLnNlcGFyYXRvcikpCgkJCQkJdG9GaWxlICs9IEZpbGUuc2VwYXJhdG9yOwoJCQkJdG9GaWxlICs9IGN1cnJlbnQuZ2V0TmFtZSgpOwoJCQkJaWYgKGN1cnJlbnQuaXNGaWxlKCkpIHsKCQkJCQljb3B5RmlsZShmcm9tRmlsZSwgdG9GaWxlKTsKCQkJCQltb25pdG9yLndvcmtlZCg1MCk7CgkJCQl9IGVsc2UgaWYgKGN1cnJlbnQuaXNEaXJlY3RvcnkoKSkgewoJCQkJCW1vbml0b3Iuc3ViVGFzayhTZXJ2ZXJQbHVnaW4uZ2V0UmVzb3VyY2UoIiVjb3B5aW5nVGFzayIsIG5ldyBTdHJpbmdbXSB7ZnJvbUZpbGUsIHRvRmlsZX0pKTsKCQkJCQljb3B5RGlyZWN0b3J5KGZyb21GaWxlLCB0b0ZpbGUsIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDUwKSk7CgkJCQl9CgkJCQlpZiAobW9uaXRvci5pc0NhbmNlbGVkKCkpCgkJCQkJcmV0dXJuOwoJCQl9CgkJCW1vbml0b3IuZG9uZSgpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKCJFcnJvciBjb3B5aW5nIGRpcmVjdG9yeSIsIGUpOwoJCX0KCX0KCgkvKioKCSAqIENvcHkgYSBmaWxlIGZyb20gYSB0byBiLiBDbG9zZXMgdGhlIGlucHV0IHN0cmVhbSBhZnRlciB1c2UuCgkgKgoJICogQHBhcmFtIGluIGphdmEuaW8uSW5wdXRTdHJlYW0KCSAqIEBwYXJhbSB0byBqYXZhLmxhbmcuU3RyaW5nCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVN0YXR1cyBjb3B5RmlsZShJbnB1dFN0cmVhbSBpbiwgU3RyaW5nIHRvKSB7CgkJT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CgkKCQl0cnkgewoJCQlvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbSh0byk7CgkKCQkJaW50IGF2YWlsID0gaW4ucmVhZChidWYpOwoJCQl3aGlsZSAoYXZhaWwgPiAwKSB7CgkJCQlvdXQud3JpdGUoYnVmLCAwLCBhdmFpbCk7CgkJCQlhdmFpbCA9IGluLnJlYWQoYnVmKTsKCQkJfQoJCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLk9LLCBTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAwLCBTZXJ2ZXJQbHVnaW4uZ2V0UmVzb3VyY2UoIiVjb3B5aW5nVGFzayIsIG5ldyBTdHJpbmdbXSB7dG99KSwgbnVsbCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoIkVycm9yIGNvcHlpbmcgZmlsZSIsIGUpOwoJCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAwLCBTZXJ2ZXJQbHVnaW4uZ2V0UmVzb3VyY2UoIiVlcnJvckNvcHlpbmdGaWxlIiwgbmV3IFN0cmluZ1tdIHt0bywgZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCl9KSwgZSk7CgkJfSBmaW5hbGx5IHsKCQkJdHJ5IHsKCQkJCWlmIChpbiAhPSBudWxsKQoJCQkJCWluLmNsb3NlKCk7CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewoJCQkJLy8gaWdub3JlCgkJCX0KCQkJdHJ5IHsKCQkJCWlmIChvdXQgIT0gbnVsbCkKCQkJCQlvdXQuY2xvc2UoKTsKCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CgkJCQkvLyBpZ25vcmUKCQkJfQoJCX0KCX0KCgkvKioKCSAqIENvcHkgYSBmaWxlIGZyb20gYSB0byBiLgoJICoKCSAqIEBwYXJhbSBmcm9tIGphdmEubGFuZy5TdHJpbmcKCSAqIEBwYXJhbSB0byBqYXZhLmxhbmcuU3RyaW5nCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVN0YXR1cyBjb3B5RmlsZShTdHJpbmcgZnJvbSwgU3RyaW5nIHRvKSB7CgkJdHJ5IHsKCQkJcmV0dXJuIGNvcHlGaWxlKG5ldyBGaWxlSW5wdXRTdHJlYW0oZnJvbSksIHRvKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZSgiRXJyb3IgY29weWluZyBmaWxlIiwgZSk7CgkJCXJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsIDAsIFNlcnZlclBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yQ29weWluZ0ZpbGUiLCBuZXcgU3RyaW5nW10ge3RvLCBlLmdldExvY2FsaXplZE1lc3NhZ2UoKX0pLCBlKTsKCQl9Cgl9CgoJLyoqCgkgKiBDb3B5IGEgZmlsZSBmcm9tIGEgdG8gYi4KCSAqCgkgKiBAcGFyYW0gZnJvbSBqYXZhLm5ldC5VUkwKCSAqIEBwYXJhbSB0byBqYXZhLmxhbmcuU3RyaW5nCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVN0YXR1cyBjb3B5RmlsZShVUkwgZnJvbSwgU3RyaW5nIHRvKSB7CgkJdHJ5IHsKCQkJcmV0dXJuIGNvcHlGaWxlKGZyb20ub3BlblN0cmVhbSgpLCB0byk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoIkVycm9yIGNvcHlpbmcgZmlsZSIsIGUpOwoJCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAwLCBTZXJ2ZXJQbHVnaW4uZ2V0UmVzb3VyY2UoIiVlcnJvckNvcHlpbmdGaWxlIiwgbmV3IFN0cmluZ1tdIHt0bywgZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCl9KSwgZSk7CgkJfQoJfQoJLyoqCgkgKiBSZWN1cnNpdmVseSBkZWxldGVzIGEgZGlyZWN0b3J5LgoJICoKCSAqIEBwYXJhbSBkaXIgamF2YS5pby5GaWxlCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCBkZWxldGVEaXJlY3RvcnkoRmlsZSBkaXIsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCXRyeSB7CgkJCWlmICghZGlyLmV4aXN0cygpIHx8ICFkaXIuaXNEaXJlY3RvcnkoKSkKCQkJCXJldHVybjsKCQoJCQlGaWxlW10gZmlsZXMgPSBkaXIubGlzdEZpbGVzKCk7CgkJCWludCBzaXplID0gZmlsZXMubGVuZ3RoOwoJCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgkJCW1vbml0b3IuYmVnaW5UYXNrKFNlcnZlclBsdWdpbi5nZXRSZXNvdXJjZSgiJWRlbGV0aW5nVGFzayIsIG5ldyBTdHJpbmdbXSB7ZGlyLmdldEFic29sdXRlUGF0aCgpfSksIHNpemUgKiAxMCk7CgkKCQkJLy8gY3ljbGUgdGhyb3VnaCBmaWxlcwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJRmlsZSBjdXJyZW50ID0gZmlsZXNbaV07CgkJCQlpZiAoY3VycmVudC5pc0ZpbGUoKSkgewoJCQkJCWN1cnJlbnQuZGVsZXRlKCk7CgkJCQkJbW9uaXRvci53b3JrZWQoMTApOwoJCQkJfSBlbHNlIGlmIChjdXJyZW50LmlzRGlyZWN0b3J5KCkpIHsKCQkJCQltb25pdG9yLnN1YlRhc2soU2VydmVyUGx1Z2luLmdldFJlc291cmNlKCIlZGVsZXRpbmdUYXNrIiwgbmV3IFN0cmluZ1tdIHtjdXJyZW50LmdldEFic29sdXRlUGF0aCgpfSkpOwoJCQkJCWRlbGV0ZURpcmVjdG9yeShjdXJyZW50LCBQcm9ncmVzc1V0aWwuZ2V0U3ViTW9uaXRvckZvcihtb25pdG9yLCAxMCkpOwoJCQkJfQoJCQl9CgkJCWRpci5kZWxldGUoKTsKCQkJbW9uaXRvci5kb25lKCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoIkVycm9yIGRlbGV0aW5nIGRpcmVjdG9yeSAiICsgZGlyLmdldEFic29sdXRlUGF0aCgpLCBlKTsKCQl9Cgl9CgoJLyoqCgkgKiBFeHBhbmQgYSB6aXAgZmlsZSB0byBhIGdpdmVuIGRpcmVjdG9yeS4KCSAqCgkgKiBAcGFyYW0gemlwRmlsZSBqYXZhLmlvLkZpbGUKCSAqIEBwYXJhbSBkaXIgamF2YS5pby5GaWxlCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCBleHBhbmRaaXAoRmlsZSB6aXBGaWxlLCBGaWxlIGRpciwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB7CgkJWmlwSW5wdXRTdHJlYW0gemlzID0gbnVsbDsKCQoJCXRyeSB7CgkJCS8vIGZpcnN0LCBjb3VudCBudW1iZXIgb2YgaXRlbXMgaW4gemlwIGZpbGUKCQkJemlzID0gbmV3IFppcElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oemlwRmlsZSkpOwoJCQlpbnQgY291bnQgPSAwOwoJCQl3aGlsZSAoemlzLmdldE5leHRFbnRyeSgpICE9IG51bGwpCgkJCQljb3VudCsrOwoJCgkJCW1vbml0b3IgPSBQcm9ncmVzc1V0aWwuZ2V0TW9uaXRvckZvcihtb25pdG9yKTsKCQkJbW9uaXRvci5iZWdpblRhc2soU2VydmVyUGx1Z2luLmdldFJlc291cmNlKCIldW5aaXBwaW5nVGFzayIsIG5ldyBTdHJpbmdbXSB7emlwRmlsZS5nZXROYW1lKCl9KSwgY291bnQpOwoJCQkKCQkJemlzID0gbmV3IFppcElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oemlwRmlsZSkpOwoJCQlaaXBFbnRyeSB6ZSA9IHppcy5nZXROZXh0RW50cnkoKTsKCQoJCQlGaWxlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CgkKCQkJd2hpbGUgKHplICE9IG51bGwpIHsKCQkJCXRyeSB7CgkJCQkJbW9uaXRvci5zdWJUYXNrKFNlcnZlclBsdWdpbi5nZXRSZXNvdXJjZSgiJWV4cGFuZGluZ1Rhc2siLCBuZXcgU3RyaW5nW10ge3plLmdldE5hbWUoKX0pKTsKCQkJCQlGaWxlIGYgPSBuZXcgRmlsZShkaXIsIHplLmdldE5hbWUoKSk7CgkKCQkJCQlpZiAoemUuaXNEaXJlY3RvcnkoKSkgewoJCQkJCQlvdXQgPSBudWxsOwoJCQkJCQlmLm1rZGlycygpOwoJCQkJCX0gZWxzZSB7CgkJCQkJCW91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGYpOwoJCgkJCQkJCWludCBhdmFpbCA9IHppcy5yZWFkKGJ1Zik7CgkJCQkJCXdoaWxlIChhdmFpbCA+IDApIHsKCQkJCQkJCW91dC53cml0ZShidWYsIDAsIGF2YWlsKTsKCQkJCQkJCWF2YWlsID0gemlzLnJlYWQoYnVmKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBleCkgewoJCQkJCVRyYWNlLnRyYWNlKCJFcnJvciBleHRyYWN0aW5nICIgKyB6ZS5nZXROYW1lKCkgKyAiIGZyb20gemlwICIgKyB6aXBGaWxlLmdldEFic29sdXRlUGF0aCgpLCBleCk7CgkJCQl9IGZpbmFsbHkgewoJCQkJCXRyeSB7CgkJCQkJCWlmIChvdXQgIT0gbnVsbCkKCQkJCQkJCW91dC5jbG9zZSgpOwoJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJCS8vIGlnbm9yZQoJCQkJCX0KCQkJCX0KCQkJCXplID0gemlzLmdldE5leHRFbnRyeSgpOwoJCQkJbW9uaXRvci53b3JrZWQoMSk7CgkJCQlpZiAobW9uaXRvci5pc0NhbmNlbGVkKCkpCgkJCQkJcmV0dXJuOwoJCQl9CgkJCW1vbml0b3IuZG9uZSgpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKCJFcnJvciBleHBhbmRpbmcgemlwIGZpbGUgIiArIHppcEZpbGUuZ2V0QWJzb2x1dGVQYXRoKCksIGUpOwoJCX0gZmluYWxseSB7CgkJCXRyeSB7CgkJCQlpZiAoemlzICE9IG51bGwpCgkJCQkJemlzLmNsb3NlKCk7CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewoJCQkJLy8gaWdub3JlCgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBDb3B5cyBhIGRpcmVjdG9yeSBmcm9tIGEgdG8gYiwgb25seSBtb2RpZnlpbmcgYXMgbmVlZGVkCgkgKiBhbmQgZGVsZXRpbmcgb2xkIGZpbGVzIGFuZCBkaXJlY3Rvcmllcy4KCSAqCgkgKiBAcGFyYW0gZnJvbSBqYXZhLmxhbmcuU3RyaW5nCgkgKiBAcGFyYW0gdG8gamF2YS5sYW5nLlN0cmluZwoJICogQHBhcmFtIElQcm9ncmVzc01vbml0b3IKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIHNtYXJ0Q29weURpcmVjdG9yeShTdHJpbmcgZnJvbSwgU3RyaW5nIHRvLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQl0cnkgewoJCQlGaWxlIGZyb21EaXIgPSBuZXcgRmlsZShmcm9tKTsKCQkJRmlsZSB0b0RpciA9IG5ldyBGaWxlKHRvKTsKCQoJCQlGaWxlW10gZnJvbUZpbGVzID0gZnJvbURpci5saXN0RmlsZXMoKTsKCQkJaW50IGZyb21TaXplID0gZnJvbUZpbGVzLmxlbmd0aDsKCQoJCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgkJCW1vbml0b3IuYmVnaW5UYXNrKFNlcnZlclBsdWdpbi5nZXRSZXNvdXJjZSgiJWNvcHlpbmdUYXNrIiwgbmV3IFN0cmluZ1tdIHtmcm9tLCB0b30pLCA1NTApOwoJCgkJCUZpbGVbXSB0b0ZpbGVzID0gbnVsbDsKCQoJCQkvLyBkZWxldGUgb2xkIGZpbGVzIGFuZCBkaXJlY3RvcmllcyBmcm9tIHRoaXMgZGlyZWN0b3J5CgkJCWlmICh0b0Rpci5leGlzdHMoKSAmJiB0b0Rpci5pc0RpcmVjdG9yeSgpKSB7CgkJCQl0b0ZpbGVzID0gdG9EaXIubGlzdEZpbGVzKCk7CgkJCQlpbnQgdG9TaXplID0gdG9GaWxlcy5sZW5ndGg7CgkKCQkJCS8vIGNoZWNrIGlmIHRoaXMgZXhhY3QgZmlsZSBleGlzdHMgaW4gdGhlIG5ldyBkaXJlY3RvcnkKCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgdG9TaXplOyBpKyspIHsKCQkJCQlTdHJpbmcgbmFtZSA9IHRvRmlsZXNbaV0uZ2V0TmFtZSgpOwoJCQkJCWJvb2xlYW4gaXNEaXIgPSB0b0ZpbGVzW2ldLmlzRGlyZWN0b3J5KCk7CgkJCQkJYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwoJCQkJCWZvciAoaW50IGogPSAwOyBqIDwgZnJvbVNpemU7IGorKykgewoJCQkJCQlpZiAobmFtZS5lcXVhbHMoZnJvbUZpbGVzW2pdLmdldE5hbWUoKSkgJiYgaXNEaXIgPT0gZnJvbUZpbGVzW2pdLmlzRGlyZWN0b3J5KCkpCgkJCQkJCQlmb3VuZCA9IHRydWU7CgkJCQkJfQoJCgkJCQkJLy8gZGVsZXRlIGZpbGUgaWYgaXQgY2FuJ3QgYmUgZm91bmQgb3IgaXNuJ3QgdGhlIGNvcnJlY3QgdHlwZQoJCQkJCWlmICghZm91bmQpIHsKCQkJCQkJaWYgKGlzRGlyKQoJCQkJCQkJZGVsZXRlRGlyZWN0b3J5KHRvRmlsZXNbaV0sIG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCkpOwoJCQkJCQllbHNlCgkJCQkJCQl0b0ZpbGVzW2ldLmRlbGV0ZSgpOwoJCQkJCX0KCQkJCQlpZiAobW9uaXRvci5pc0NhbmNlbGVkKCkpCgkJCQkJCXJldHVybjsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWlmICh0b0Rpci5pc0ZpbGUoKSkKCQkJCQl0b0Rpci5kZWxldGUoKTsKCQkJCXRvRGlyLm1rZGlyKCk7CgkJCX0KCQkJbW9uaXRvci53b3JrZWQoNTApOwoJCgkJCS8vIGN5Y2xlIHRocm91Z2ggZmlsZXMgYW5kIG9ubHkgY29weSB3aGVuIGl0IGRvZXNuJ3QgZXhpc3QKCQkJLy8gb3IgaXMgbmV3ZXIKCQkJdG9GaWxlcyA9IHRvRGlyLmxpc3RGaWxlcygpOwoJCQlpbnQgdG9TaXplID0gdG9GaWxlcy5sZW5ndGg7CgkJCWludCBkdyA9IDA7CgkJCWlmICh0b1NpemUgPiAwKQoJCQkJZHcgPSA1MDAgLyB0b1NpemU7CgkKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBmcm9tU2l6ZTsgaSsrKSB7CgkJCQlGaWxlIGN1cnJlbnQgPSBmcm9tRmlsZXNbaV07CgkKCQkJCS8vIGNoZWNrIGlmIHRoaXMgaXMgYSBuZXcgb3IgbmV3ZXIgZmlsZQoJCQkJYm9vbGVhbiBjb3B5ID0gdHJ1ZTsKCQkJCWlmICghY3VycmVudC5pc0RpcmVjdG9yeSgpKSB7CgkJCQkJU3RyaW5nIG5hbWUgPSBjdXJyZW50LmdldE5hbWUoKTsKCQkJCQlsb25nIG1vZCA9IGN1cnJlbnQubGFzdE1vZGlmaWVkKCk7CgkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCB0b1NpemU7IGorKykgewoJCQkJCQlpZiAobmFtZS5lcXVhbHModG9GaWxlc1tqXS5nZXROYW1lKCkpICYmIG1vZCA8PSB0b0ZpbGVzW2pdLmxhc3RNb2RpZmllZCgpKQoJCQkJCQkJY29weSA9IGZhbHNlOwoJCQkJCX0KCQkJCX0KCQoJCQkJaWYgKGNvcHkpIHsKCQkJCQlTdHJpbmcgZnJvbUZpbGUgPSBjdXJyZW50LmdldEFic29sdXRlUGF0aCgpOwoJCQkJCVN0cmluZyB0b0ZpbGUgPSB0bzsKCQkJCQlpZiAoIXRvRmlsZS5lbmRzV2l0aChGaWxlLnNlcGFyYXRvcikpCgkJCQkJCXRvRmlsZSArPSBGaWxlLnNlcGFyYXRvcjsKCQkJCQl0b0ZpbGUgKz0gY3VycmVudC5nZXROYW1lKCk7CgkJCQkJaWYgKGN1cnJlbnQuaXNGaWxlKCkpIHsKCQkJCQkJY29weUZpbGUoZnJvbUZpbGUsIHRvRmlsZSk7CgkJCQkJCW1vbml0b3Iud29ya2VkKGR3KTsKCQkJCQl9IGVsc2UgaWYgKGN1cnJlbnQuaXNEaXJlY3RvcnkoKSkgewoJCQkJCQltb25pdG9yLnN1YlRhc2soU2VydmVyUGx1Z2luLmdldFJlc291cmNlKCIlY29weWluZ1Rhc2siLCBuZXcgU3RyaW5nW10ge2Zyb21GaWxlLCB0b0ZpbGV9KSk7CgkJCQkJCXNtYXJ0Q29weURpcmVjdG9yeShmcm9tRmlsZSwgdG9GaWxlLCBQcm9ncmVzc1V0aWwuZ2V0U3ViTW9uaXRvckZvcihtb25pdG9yLCBkdykpOwoJCQkJCX0KCQkJCX0KCQkJCWlmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkJCQlyZXR1cm47CgkJCX0KCQkJbW9uaXRvci53b3JrZWQoNTAwIC0gZHcgKiB0b1NpemUpOwoJCQltb25pdG9yLmRvbmUoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZSgiRXJyb3Igc21hcnQgY29weWluZyBkaXJlY3RvcnkgIiArIGZyb20gKyAiIC0gIiArIHRvLCBlKTsKCQl9Cgl9Cn0K