LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIAogKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLmNvcmUuaW50ZXJuYWwuY29udGVudDsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5pbnRlcm5hbC5ydW50aW1lLkludGVybmFsUGxhdGZvcm07CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5jb250ZW50Lio7CgpwdWJsaWMgY2xhc3MgQ29udGVudFR5cGVNYW5hZ2VyIGltcGxlbWVudHMgSUNvbnRlbnRUeXBlTWFuYWdlciwgSVJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIgewoJcHJpdmF0ZSBzdGF0aWMgQ29udGVudFR5cGVNYW5hZ2VyIGluc3RhbmNlOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BUktfTElNSVQgPSAweDEwMDsKCSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQVF9DT05URU5UVFlQRVM9ICJjb250ZW50VHlwZXMiOyAvLyROT04tTkxTLTEkCQoJLyoKCSAqIFJldHVybnMgdGhlIGV4dGVuc2lvbiBmb3IgYSBmaWxlIG5hbWUgKG9taXRpbmcgdGhlIGxlYWRpbmcgJy4nKS4gCgkgKi8KCXN0YXRpYyBTdHJpbmcgZ2V0RmlsZUV4dGVuc2lvbihTdHJpbmcgZmlsZU5hbWUpIHsKCQlpbnQgZG90UG9zaXRpb24gPSBmaWxlTmFtZS5sYXN0SW5kZXhPZignLicpOwoJCXJldHVybiAoZG90UG9zaXRpb24gPT0gLTEgfHwgZG90UG9zaXRpb24gPT0gZmlsZU5hbWUubGVuZ3RoKCkgLSAxKSA/IG51bGwgOiBmaWxlTmFtZS5zdWJzdHJpbmcoZG90UG9zaXRpb24gKyAxKTsKCX0KCXB1YmxpYyBzeW5jaHJvbml6ZWQgc3RhdGljIElDb250ZW50VHlwZU1hbmFnZXIgZ2V0SW5zdGFuY2UoKSB7CgkJaWYgKGluc3RhbmNlICE9IG51bGwpCgkJCXJldHVybiBpbnN0YW5jZTsKCQlpbnN0YW5jZSA9IG5ldyBDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlpbnN0YW5jZS5zdGFydHVwKCk7CgkJcmV0dXJuIGluc3RhbmNlOwoJfQoJcHJpdmF0ZSBNYXAgY2F0YWxvZyA9IG5ldyBIYXNoTWFwKCk7CgkvKioKCSAqIENvbnN0cnVjdHMgYSBuZXcgY29udGVudCB0eXBlIG1hbmFnZXIuCgkgKi8KCXByb3RlY3RlZCBDb250ZW50VHlwZU1hbmFnZXIoKSB7Cgl9Cglwcm90ZWN0ZWQgdm9pZCBhZGRDb250ZW50VHlwZShJQ29udGVudFR5cGUgY29udGVudFR5cGUpIHsKCQljYXRhbG9nLnB1dChjb250ZW50VHlwZS5nZXRJZCgpLCBjb250ZW50VHlwZSk7Cgl9Cglwcm90ZWN0ZWQgSUNvbnRlbnRUeXBlIGNyZWF0ZUNvbnRlbnRUeXBlKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBzaW1wbGVJZCwgU3RyaW5nIG5hbWUsIFN0cmluZ1tdIGZpbGVFeHRlbnNpb25zLCBTdHJpbmdbXSBmaWxlTmFtZXMsIFN0cmluZyBiYXNlVHlwZUlkKSB7CgkJQ29udGVudFR5cGUgY29udGVudFR5cGUgPSBuZXcgQ29udGVudFR5cGUodGhpcyk7CgkJY29udGVudFR5cGUuc2V0U2ltcGxlSWQoc2ltcGxlSWQpOwoJCWNvbnRlbnRUeXBlLnNldE5hbWVzcGFjZShuYW1lc3BhY2UpOwoJCWNvbnRlbnRUeXBlLnNldE5hbWUobmFtZSk7CgkJY29udGVudFR5cGUuc2V0RmlsZUV4dGVuc2lvbnMoZmlsZUV4dGVuc2lvbnMpOwoJCWNvbnRlbnRUeXBlLnNldEZpbGVOYW1lcyhmaWxlTmFtZXMpOwoJCWNvbnRlbnRUeXBlLnNldEJhc2VUeXBlSWQoYmFzZVR5cGVJZCk7CgkJcmV0dXJuIGNvbnRlbnRUeXBlOwoJfQoJLyoqCgkgKiBBIGNvbnRlbnQgdHlwZSB3aWxsIGJlIHZhbGlkIGlmOgoJICogPG9sPgoJICogPGxpPml0IGRvZXMgbm90IGRlc2lnbmF0ZSBhIGJhc2UgdHlwZSwgb3I8L2xpPgoJICogPGxpPml0IGRlc2lnbmF0ZXMgYSBiYXNlIHR5cGUgdGhhdCBleGlzdHMgYW5kIGlzIHZhbGlkPC9saT4KCSAqIDwvb2w+IAoJICovCglwcml2YXRlIHZvaWQgZW5zdXJlVmFsaWQoQ29udGVudFR5cGUgdHlwZSkgewoJCWlmICh0eXBlLmdldFZhbGlkYXRpb24oKSAhPSBDb250ZW50VHlwZS5VTktOT1dOKQoJCQlyZXR1cm47CgkJaWYgKHR5cGUuZ2V0QmFzZVR5cGVJZCgpID09IG51bGwpIHsKCQkJdHlwZS5zZXRWYWxpZGF0aW9uKENvbnRlbnRUeXBlLlZBTElEKTsKCQkJcmV0dXJuOwoJCX0KCQlDb250ZW50VHlwZSBiYXNlVHlwZSA9IChDb250ZW50VHlwZSkgY2F0YWxvZy5nZXQodHlwZS5nZXRCYXNlVHlwZUlkKCkpOwoJCWlmIChiYXNlVHlwZSA9PSBudWxsKSB7CgkJCXR5cGUuc2V0VmFsaWRhdGlvbihDb250ZW50VHlwZS5JTlZBTElEKTsKCQkJcmV0dXJuOwoJCX0KCQkvLyBzZXQgdGhpcyB0ZW1wb3JhcmlseSBhcyBpbnZhbGlkIHRvIHByZXZlbnQgY3ljbGVzCgkJLy8gYWxsIHR5cGVzIGluIHRoZSBjeWNsZSB3aWxsIGJlIG1hcmtlZCBhcyBpbnZhbGlkCgkJdHlwZS5zZXRWYWxpZGF0aW9uKENvbnRlbnRUeXBlLklOVkFMSUQpOwoJCWVuc3VyZVZhbGlkKGJhc2VUeXBlKTsKCQkvLyBiYXNlIHR5cGUgaXMgZWl0aGVyIGJlIHZhbGlkIG9yIGludmFsaWQgLSB0eXBlIHdpbGwgaGF2ZSB0aGUgc2FtZSBzdGF0dXMKCQl0eXBlLnNldFZhbGlkYXRpb24oYmFzZVR5cGUuZ2V0VmFsaWRhdGlvbigpKTsKCX0KCS8qKgoJICogQHNlZSBJQ29udGVudFR5cGVNYW5hZ2VyCgkgKi8KCXB1YmxpYyBJQ29udGVudFR5cGUgZmluZENvbnRlbnRUeXBlRm9yKElucHV0U3RyZWFtIGNvbnRlbnRzLCBJQ29udGVudFR5cGVbXSBzdWJzZXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CgkJaWYgKHN1YnNldCA9PSBudWxsKQoJCQlzdWJzZXQgPSBnZXRBbGxDb250ZW50VHlwZXMoKTsKCQlMaXN0IGFwcHJvcHJpYXRlID0gbmV3IEFycmF5TGlzdCgpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc3Vic2V0Lmxlbmd0aDsgaSsrKSB7CgkJCUlDb250ZW50RGVzY3JpYmVyIGRlc2NyaWJlciA9ICgoQ29udGVudFR5cGUpIHN1YnNldFtpXSkuZ2V0RGVzY3JpYmVyKCk7CgkJCWlmIChkZXNjcmliZXIgIT0gbnVsbCkgewoJCQkJY29udGVudHMubWFyayhNQVJLX0xJTUlUKTsKCQkJCWlmIChkZXNjcmliZXIuZGVzY3JpYmUoY29udGVudHMsIG51bGwsIDApKQoJCQkJCWFwcHJvcHJpYXRlLmFkZChzdWJzZXRbaV0pOwoJCQkJY29udGVudHMucmVzZXQoKTsKCQkJfQoJCX0KCQlyZXR1cm4gbW9zdEFwcHJvcHJpYXRlKGFwcHJvcHJpYXRlKTsKCX0KCS8qKgoJICogQHNlZSBJQ29udGVudFR5cGVNYW5hZ2VyCgkgKi8KCXB1YmxpYyBJQ29udGVudFR5cGUgZmluZENvbnRlbnRUeXBlRm9yRmlsZU5hbWUoU3RyaW5nIGZpbGVOYW1lKSB7CgkJLy8gYmFzaWMgaW1wbGVtZW50YXRpb24ganVzdCBnZXRzIGFsbCBjb250ZW50IHR5cGVzCQkKCQlJQ29udGVudFR5cGVbXSBhc3NvY2lhdGVkID0gZmluZENvbnRlbnRUeXBlc0ZvckZpbGVOYW1lKGZpbGVOYW1lKTsKCQlyZXR1cm4gYXNzb2NpYXRlZC5sZW5ndGggPT0gMCA/IG51bGwgOiBhc3NvY2lhdGVkWzFdOwoJfQoJLyoqCgkgKiBAc2VlIElDb250ZW50VHlwZU1hbmFnZXIKCSAqLwkKCXB1YmxpYyBJQ29udGVudFR5cGVbXSBmaW5kQ29udGVudFR5cGVzRm9yKElucHV0U3RyZWFtIGNvbnRlbnRzLCBJQ29udGVudFR5cGVbXSBzdWJzZXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CgkJaWYgKHN1YnNldCA9PSBudWxsKQoJCQlzdWJzZXQgPSBnZXRBbGxDb250ZW50VHlwZXMoKTsKCQlMaXN0IGFwcHJvcHJpYXRlID0gbmV3IEFycmF5TGlzdCgpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc3Vic2V0Lmxlbmd0aDsgaSsrKSB7CgkJCUlDb250ZW50RGVzY3JpYmVyIGRlc2NyaWJlciA9ICgoQ29udGVudFR5cGUpIHN1YnNldFtpXSkuZ2V0RGVzY3JpYmVyKCk7CgkJCWlmIChkZXNjcmliZXIgIT0gbnVsbCAmJiBkZXNjcmliZXIuZGVzY3JpYmUoY29udGVudHMsIG51bGwsIDApKQoJCQkJYXBwcm9wcmlhdGUuYWRkKHN1YnNldFtpXSk7CgkJfQoJCXJldHVybiAoSUNvbnRlbnRUeXBlW10pIGFwcHJvcHJpYXRlLnRvQXJyYXkobmV3IElDb250ZW50VHlwZVthcHByb3ByaWF0ZS5zaXplKCldKTsKCX0KCXByaXZhdGUgSUNvbnRlbnRUeXBlW10gZmluZENvbnRlbnRUeXBlc0ZvckZpbGVFeHRlbnNpb24oU3RyaW5nIGZpbGVFeHRlbnNpb24pIHsKCQlMaXN0IHJlc3VsdCA9IG5ldyBBcnJheUxpc3QoKTsKCQlmb3IgKEl0ZXJhdG9yIGl0ZXIgPSBjYXRhbG9nLnZhbHVlcygpLml0ZXJhdG9yKCk7IGl0ZXIuaGFzTmV4dCgpOykgewoJCQlDb250ZW50VHlwZSBjb250ZW50VHlwZSA9IChDb250ZW50VHlwZSkgaXRlci5uZXh0KCk7CgkJCWlmIChjb250ZW50VHlwZS5pc1ZhbGlkKCkgJiYgaW5kZXhPZihjb250ZW50VHlwZS5nZXRGaWxlRXh0ZW5zaW9ucygpLCBmaWxlRXh0ZW5zaW9uKSA+PSAwKQoJCQkJcmVzdWx0LmFkZChjb250ZW50VHlwZSk7CgkJfQoJCXJldHVybiAoSUNvbnRlbnRUeXBlW10pIHJlc3VsdC50b0FycmF5KG5ldyBJQ29udGVudFR5cGVbcmVzdWx0LnNpemUoKV0pOwoJfQoJLyoqCgkgKiBAc2VlIElDb250ZW50VHlwZU1hbmFnZXIKCSAqLwkKCXB1YmxpYyBJQ29udGVudFR5cGVbXSBmaW5kQ29udGVudFR5cGVzRm9yRmlsZU5hbWUoU3RyaW5nIGZpbGVOYW1lKSB7CgkJU2V0IHR5cGVzID0gbmV3IEhhc2hTZXQoKTsKCQlmb3IgKEl0ZXJhdG9yIGl0ZXIgPSBjYXRhbG9nLnZhbHVlcygpLml0ZXJhdG9yKCk7IGl0ZXIuaGFzTmV4dCgpOykgewoJCQlDb250ZW50VHlwZSBjb250ZW50VHlwZSA9IChDb250ZW50VHlwZSkgaXRlci5uZXh0KCk7CgkJCWlmIChjb250ZW50VHlwZS5pc1ZhbGlkKCkgJiYgaW5kZXhPZihjb250ZW50VHlwZS5nZXRGaWxlTmFtZXMoKSwgZmlsZU5hbWUpID49IDApCgkJCQl0eXBlcy5hZGQoY29udGVudFR5cGUpOwoJCX0KCQlTdHJpbmcgZmlsZUV4dGVuc2lvbiA9IGdldEZpbGVFeHRlbnNpb24oZmlsZU5hbWUpOwoJCWlmIChmaWxlRXh0ZW5zaW9uICE9IG51bGwpCgkJCWZvciAoSXRlcmF0b3IgaXRlciA9IGNhdGFsb2cudmFsdWVzKCkuaXRlcmF0b3IoKTsgaXRlci5oYXNOZXh0KCk7KSB7CgkJCQlDb250ZW50VHlwZSBjb250ZW50VHlwZSA9IChDb250ZW50VHlwZSkgaXRlci5uZXh0KCk7CgkJCQlpZiAoY29udGVudFR5cGUuaXNWYWxpZCgpICYmIGluZGV4T2YoY29udGVudFR5cGUuZ2V0RmlsZUV4dGVuc2lvbnMoKSwgZmlsZUV4dGVuc2lvbikgPj0gMCkKCQkJCQl0eXBlcy5hZGQoY29udGVudFR5cGUpOwoJCQl9CgkJcmV0dXJuIChJQ29udGVudFR5cGVbXSkgdHlwZXMudG9BcnJheShuZXcgSUNvbnRlbnRUeXBlW3R5cGVzLnNpemUoKV0pOwoJfQoJLyoqCgkgKiBAc2VlIElDb250ZW50VHlwZU1hbmFnZXIKCSAqLwkKCXB1YmxpYyBJQ29udGVudFR5cGVbXSBnZXRBbGxDb250ZW50VHlwZXMoKSB7CgkJTGlzdCByZXN1bHQgPSBuZXcgQXJyYXlMaXN0KGNhdGFsb2cuc2l6ZSgpKTsKCQlmb3IgKEl0ZXJhdG9yIGkgPSBjYXRhbG9nLnZhbHVlcygpLml0ZXJhdG9yKCk7IGkuaGFzTmV4dCgpOykgewoJCQlDb250ZW50VHlwZSB0eXBlID0gKENvbnRlbnRUeXBlKSBpLm5leHQoKTsKCQkJaWYgKHR5cGUuaXNWYWxpZCgpKQoJCQkJcmVzdWx0LmFkZCh0eXBlKTsKCQl9CgkJcmV0dXJuIChJQ29udGVudFR5cGVbXSkgcmVzdWx0LnRvQXJyYXkobmV3IElDb250ZW50VHlwZVtyZXN1bHQuc2l6ZSgpXSk7Cgl9CgkvKioKCSAqIEBzZWUgSUNvbnRlbnRUeXBlTWFuYWdlcgoJICovCQoJcHVibGljIElDb250ZW50VHlwZSBnZXRDb250ZW50VHlwZShTdHJpbmcgY29udGVudFR5cGVJZGVudGlmaWVyKSB7CgkJQ29udGVudFR5cGUgdHlwZSA9IChDb250ZW50VHlwZSkgY2F0YWxvZy5nZXQoY29udGVudFR5cGVJZGVudGlmaWVyKTsKCQlyZXR1cm4gKHR5cGUgIT0gbnVsbCAmJiB0eXBlLmlzVmFsaWQoKSkgPyB0eXBlIDogbnVsbDsKCX0KCS8qKgoJICogQHNlZSBJQ29udGVudFR5cGVNYW5hZ2VyCgkgKi8KCXB1YmxpYyBJQ29udGVudERlc2NyaXB0aW9uIGdldERlc2NyaXB0aW9uRm9yKElucHV0U3RyZWFtIGNvbnRlbnRzLCBJQ29udGVudFR5cGVbXSBzdWJzZXQsIGludCBvcHRpb25zTWFzaykgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQkvLyBuYe92ZSBpbXBsZW1lbnRhdGlvbiBmb3Igbm93CgkJSUNvbnRlbnRUeXBlIHNlbGVjdGVkID0gZmluZENvbnRlbnRUeXBlRm9yKGNvbnRlbnRzLCBzdWJzZXQpOwoJCWlmIChzZWxlY3RlZCA9PSBudWxsKQoJCQlyZXR1cm4gbnVsbDsKCQlDb250ZW50RGVzY3JpcHRpb24gZGVzY3JpcHRpb24gPSBuZXcgQ29udGVudERlc2NyaXB0aW9uKCk7CgkJZGVzY3JpcHRpb24uc2V0Q29udGVudFR5cGUoc2VsZWN0ZWQpOwoJCS8vIFRPRE8gbGVzcy10aGFuLW9wdGltYWw6IGNhdXNlcyBzdHJlYW0gdG8gYmUgcmVhZCBhZ2FpbgoJCUlDb250ZW50RGVzY3JpYmVyIHNlbGVjdGVkRGVzY3JpYmVyID0gKChDb250ZW50VHlwZSkgc2VsZWN0ZWQpLmdldERlc2NyaWJlcigpOwoJCWlmIChzZWxlY3RlZERlc2NyaWJlciAhPSBudWxsICYmIChzZWxlY3RlZERlc2NyaWJlci5nZXRTdXBwb3J0ZWRPcHRpb25zKCkgJiBvcHRpb25zTWFzaykgPT0gb3B0aW9uc01hc2spIHsKCQkJY29udGVudHMubWFyayhNQVJLX0xJTUlUKTsKCQkJc2VsZWN0ZWREZXNjcmliZXIuZGVzY3JpYmUoY29udGVudHMsIGRlc2NyaXB0aW9uLCBvcHRpb25zTWFzayk7CQkJCgkJCWNvbnRlbnRzLnJlc2V0KCk7CgkJfQoJCS8vIGNoZWNrIGlmIGFueSBvZiB0aGUgZGVmYXVsdHMgbmVlZCB0byBiZSBhcHBsaWVkCgkJaWYgKChvcHRpb25zTWFzayAmIElDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVCkgIT0gMCAmJiBkZXNjcmlwdGlvbi5nZXRDaGFyc2V0KCkgPT0gbnVsbCkKCQkJZGVzY3JpcHRpb24uc2V0Q2hhcnNldChzZWxlY3RlZC5nZXREZWZhdWx0Q2hhcnNldCgpKTsKCQlkZXNjcmlwdGlvbi5tYXJrQXNJbW11dGFibGUoKTsKCQlyZXR1cm4gZGVzY3JpcHRpb247Cgl9Cglwcml2YXRlIGludCBpbmRleE9mKE9iamVjdFtdIGFycmF5LCBPYmplY3Qgb2JqZWN0KSB7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykKCQkJaWYgKGFycmF5W2ldLmVxdWFscyhvYmplY3QpKQoJCQkJcmV0dXJuIGk7CgkJcmV0dXJuIC0xOwoJfQoJcHJpdmF0ZSBib29sZWFuIGlzQmFzZVR5cGVPZihJQ29udGVudFR5cGUgYmFzZSwgSUNvbnRlbnRUeXBlIHRhcmdldCkgewoJCUlDb250ZW50VHlwZSB0YXJnZXRCYXNlID0gdGFyZ2V0LmdldEJhc2VUeXBlKCk7CgkJaWYgKHRhcmdldEJhc2UgPT0gbnVsbCkKCQkJcmV0dXJuIGZhbHNlOwoJCXJldHVybiB0YXJnZXRCYXNlID09IGJhc2UgPyB0cnVlIDogaXNCYXNlVHlwZU9mKGJhc2UsIHRhcmdldEJhc2UpOwoJfQoJcHJpdmF0ZSBpbnQgbW9yZUFwcHJvcHJpYXRlKElDb250ZW50VHlwZSB0eXBlMSwgSUNvbnRlbnRUeXBlIHR5cGUyKSB7CgkJcmV0dXJuIGlzQmFzZVR5cGVPZih0eXBlMSwgdHlwZTIpID8gLTEgOiAoaXNCYXNlVHlwZU9mKHR5cGUyLCB0eXBlMSkgPyAxIDogMCk7Cgl9CgkvL1RPRE86IHNob3VsZCB0YWtlIGFueSB1c2VyLWRlZmluZWQgcHJlY2VkZW5jZXMgaW50byBhY2NvdW50CgkvL1RPRE86IHNob3VsZCBwaWNrIGEgY29tbW9uIGFuY2VzdG9yIGlmIHR3byBkaWZmZXJlbnQgc3BlY2lmaWMgdHlwZXMgYXJlIGRlZW1lZCBhcHByb3ByaWF0ZQoJcHJpdmF0ZSBJQ29udGVudFR5cGUgbW9zdEFwcHJvcHJpYXRlKExpc3QgY2FuZGlkYXRlcykgewoJCWludCBjYW5kaWRhdGVzQ291bnQgPSBjYW5kaWRhdGVzLnNpemUoKTsKCQlpZiAoY2FuZGlkYXRlc0NvdW50ID09IDApCgkJCXJldHVybiBudWxsOwoJCUlDb250ZW50VHlwZSBjaG9zZW4gPSAoSUNvbnRlbnRUeXBlKSBjYW5kaWRhdGVzLnJlbW92ZShjYW5kaWRhdGVzQ291bnQgLSAxKTsKCQlpZiAoY2FuZGlkYXRlc0NvdW50ID09IDEpCgkJCXJldHVybiBjaG9zZW47CgkJZm9yIChJdGVyYXRvciBpID0gY2FuZGlkYXRlcy5pdGVyYXRvcigpOyBpLmhhc05leHQoKTspIHsKCQkJSUNvbnRlbnRUeXBlIGN1cnJlbnQgPSAoSUNvbnRlbnRUeXBlKSBpLm5leHQoKTsKCQkJaS5yZW1vdmUoKTsKCQkJc3dpdGNoIChtb3JlQXBwcm9wcmlhdGUoY3VycmVudCwgY2hvc2VuKSkgewoJCQkJY2FzZSAtMSA6CgkJCQkJLy8gY3VycmVudGx5IGNob3NlbiBpcyBtb3JlIGFwcHJvcHJpYXRlCgkJCQkJYnJlYWs7CgkJCQljYXNlIDEgOgoJCQkJCS8vIGEgbW9yZSBhcHByb3ByaWF0ZSBjb250ZW50IHR5cGUgaGFzIGJlZW4gZm91bmQgLSBlbGVjdCBpdCBhcyB0aGUgbmV3IGNob3NlbiBvbmUKCQkJCQljaG9zZW4gPSBjdXJyZW50OwoJCQkJCWNvbnRpbnVlOwoJCQkJZGVmYXVsdCA6CgkJCQkJLy8gdHdvIGNhbmRpZGF0ZXMgYXJlIGVxdWFsbHkgYXBwcm9wcmlhdGUgLSBjYW5ub3QgY2hvb3NlCgkJCQkJcmV0dXJuIG51bGw7CgkJCX0KCQl9CgkJcmV0dXJuIGNob3NlbjsKCX0KCXByaXZhdGUgU3RyaW5nW10gcGFyc2VJdGVtcyhTdHJpbmcgc3RyaW5nKSB7CgkJaWYgKHN0cmluZyA9PSBudWxsKQoJCQlyZXR1cm4gbmV3IFN0cmluZ1swXTsKCQlTdHJpbmdUb2tlbml6ZXIgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcihzdHJpbmcsICIsIik7CgkJaWYgKCF0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpKQoJCQlyZXR1cm4gbmV3IFN0cmluZ1swXTsKCQlTdHJpbmcgZmlyc3QgPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7CgkJaWYgKCF0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpKQoJCQlyZXR1cm4gbmV3IFN0cmluZ1tde2ZpcnN0fTsKCQlBcnJheUxpc3QgaXRlbXMgPSBuZXcgQXJyYXlMaXN0KCk7CgkJaXRlbXMuYWRkKGZpcnN0KTsKCQlkbyB7CgkJCWl0ZW1zLmFkZCh0b2tlbml6ZXIubmV4dFRva2VuKCkpOwoJCX0gd2hpbGUgKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpOwoJCXJldHVybiAoU3RyaW5nW10pIGl0ZW1zLnRvQXJyYXkobmV3IFN0cmluZ1tpdGVtcy5zaXplKCldKTsKCX0KCXByb3RlY3RlZCB2b2lkIHJlZ2lzdGVyQ29udGVudFR5cGUoSUNvbmZpZ3VyYXRpb25FbGVtZW50IGNvbnRlbnRUeXBlQ0UpIHsKCQkvL1RPRE86IG5lZWQgdG8gZW5zdXJlIHRoZSBjb25maWcuIGVsZW1lbnQgaXMgdmFsaWQKCQlDb250ZW50VHlwZSBjb250ZW50VHlwZSA9IG5ldyBDb250ZW50VHlwZSh0aGlzLCBjb250ZW50VHlwZUNFKTsKCQljb250ZW50VHlwZS5zZXRTaW1wbGVJZChjb250ZW50VHlwZUNFLmdldEF0dHJpYnV0ZUFzSXMoImlkIikpOwoJCWNvbnRlbnRUeXBlLnNldE5hbWVzcGFjZShjb250ZW50VHlwZUNFLmdldERlY2xhcmluZ0V4dGVuc2lvbigpLmdldE5hbWVzcGFjZSgpKTsKCQljb250ZW50VHlwZS5zZXROYW1lKGNvbnRlbnRUeXBlQ0UuZ2V0QXR0cmlidXRlKCJuYW1lIikpOwoJCWNvbnRlbnRUeXBlLnNldEZpbGVFeHRlbnNpb25zKHBhcnNlSXRlbXMoY29udGVudFR5cGVDRS5nZXRBdHRyaWJ1dGVBc0lzKCJmaWxlLWV4dGVuc2lvbnMiKSkpOwoJCWNvbnRlbnRUeXBlLnNldEZpbGVOYW1lcyhwYXJzZUl0ZW1zKGNvbnRlbnRUeXBlQ0UuZ2V0QXR0cmlidXRlQXNJcygiZmlsZS1uYW1lcyIpKSk7CgkJY29udGVudFR5cGUuc2V0QmFzZVR5cGVJZChjb250ZW50VHlwZUNFLmdldEF0dHJpYnV0ZUFzSXMoImJhc2UtdHlwZSIpKTsKCQljb250ZW50VHlwZS5zZXREZWZhdWx0Q2hhcnNldChjb250ZW50VHlwZUNFLmdldEF0dHJpYnV0ZUFzSXMoImRlZmF1bHQtY2hhcnNldCIpKTsKCQljb250ZW50VHlwZS5zZXREZXNjcmliZXJDbGFzcyhjb250ZW50VHlwZUNFLmdldEF0dHJpYnV0ZUFzSXMoImRlc2NyaWJlci1jbGFzcyIpICE9IG51bGwpOwoJCWNhdGFsb2cucHV0KGNvbnRlbnRUeXBlLmdldElkKCksIGNvbnRlbnRUeXBlKTsKCX0KCXB1YmxpYyB2b2lkIHJlZ2lzdHJ5Q2hhbmdlZChJUmVnaXN0cnlDaGFuZ2VFdmVudCBldmVudCkgewoJCUlFeHRlbnNpb25EZWx0YVtdIGRlbHRhcyA9IChldmVudC5nZXRFeHRlbnNpb25EZWx0YXMoSVBsYXRmb3JtLlBJX1JVTlRJTUUsIFBUX0NPTlRFTlRUWVBFUykpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgZGVsdGFzLmxlbmd0aDsgaSsrKSB7CgkJCUlDb25maWd1cmF0aW9uRWxlbWVudFtdIGNvbmZpZ0VsZW1lbnRzID0gZGVsdGFzW2ldLmdldEV4dGVuc2lvbigpLmdldENvbmZpZ3VyYXRpb25FbGVtZW50cygpOwoJCQlpZiAoZGVsdGFzW2ldLmdldEtpbmQoKSA9PSBJRXh0ZW5zaW9uRGVsdGEuQURERUQpCgkJCQlmb3IgKGludCBqID0gMDsgaiA8IGNvbmZpZ0VsZW1lbnRzLmxlbmd0aDsgaisrKQoJCQkJCXJlZ2lzdGVyQ29udGVudFR5cGUoY29uZmlnRWxlbWVudHNbal0pOwoJCQllbHNlIHsKCQkJCS8vVE9ETyBzaG91bGQgdW5yZWdpc3RlciByZW1vdmVkIHR5cGVzCgkJCX0KCQl9CgkJLy8gcmVtb3ZlIG9ycGhhbiB0eXBlcyAvIGN5Y2xlcwoJCXZhbGlkYXRlQ29udGVudFR5cGVzKCk7Cgl9Cglwcm90ZWN0ZWQgdm9pZCBzdGFydHVwKCkgewoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IEludGVybmFsUGxhdGZvcm0uZ2V0RGVmYXVsdCgpLmdldFJlZ2lzdHJ5KCk7CgkJSW50ZXJuYWxQbGF0Zm9ybS5nZXREZWZhdWx0KCkuZ2V0UmVnaXN0cnkoKS5hZGRSZWdpc3RyeUNoYW5nZUxpc3RlbmVyKHRoaXMsIElQbGF0Zm9ybS5QSV9SVU5USU1FKTsKCQljYXRhbG9nID0gbmV3IEhhc2hNYXAoKTsKCQlJRXh0ZW5zaW9uUG9pbnQgY29udGVudFR5cGVzWFAgPSByZWdpc3RyeS5nZXRFeHRlbnNpb25Qb2ludChJUGxhdGZvcm0uUElfUlVOVElNRSwgUFRfQ09OVEVOVFRZUEVTKTsKCQlJQ29uZmlndXJhdGlvbkVsZW1lbnRbXSBhbGxDb250ZW50VHlwZUNFcyA9IGNvbnRlbnRUeXBlc1hQLmdldENvbmZpZ3VyYXRpb25FbGVtZW50cygpOwoJCWZvciAoaW50IGogPSAwOyBqIDwgYWxsQ29udGVudFR5cGVDRXMubGVuZ3RoOyBqKyspCgkJCXJlZ2lzdGVyQ29udGVudFR5cGUoYWxsQ29udGVudFR5cGVDRXNbal0pOwoJCXZhbGlkYXRlQ29udGVudFR5cGVzKCk7Cgl9Cglwcm90ZWN0ZWQgdm9pZCB2YWxpZGF0ZUNvbnRlbnRUeXBlcygpIHsKCQkvLyBmb3JnZXQgdGhlIHZhbGlkYXRpb24gc3RhdHVzIGZvciBhbGwgY29udGVudCB0eXBlcwoJCWZvciAoSXRlcmF0b3IgaSA9IGNhdGFsb2cudmFsdWVzKCkuaXRlcmF0b3IoKTsgaS5oYXNOZXh0KCk7KQoJCQkoKENvbnRlbnRUeXBlKSBpLm5leHQoKSkuc2V0VmFsaWRhdGlvbihDb250ZW50VHlwZS5VTktOT1dOKTsKCQlmb3IgKEl0ZXJhdG9yIGkgPSBjYXRhbG9nLnZhbHVlcygpLml0ZXJhdG9yKCk7IGkuaGFzTmV4dCgpOykgewoJCQllbnN1cmVWYWxpZCgoQ29udGVudFR5cGUpIGkubmV4dCgpKTsKCQl9Cgl9Cn0=